概要
apneadiving/waterfall は Ruby でフロー処理を実現するためのライブラリです
今回は簡単なサンプルを作成して挙動を確認してみました
環境
- macOS 10.15.6
- Ruby 2.7.1p83
- waterfall 1.3.0
簡単なサンプルコード
まずは成功する簡単なサンプルコードを作成しました
waterfall は chain
を使って処理を数珠つなぎにすることでフロー処理を実現します
またメインの処理は Waterfall モジュールを include しクラスにすることで管理しやすくしています
また call メソッドを実装することでオブジェクトが生成された際に自動的に処理を開始することができます
結果を受け取る場合は chain
にシンボルで引数を与えその名前のシンボルに結果が格納されるようにします
フローを開始する場合は Flow.new
します
最後まで成功した場合は最後の chain
で結果を受け取ることができます
require 'waterfall'
class MyClass
include Waterfall
def initialize(value)
@value = value
end
def call
self.chain(:value) do
@value ** 2
end
end
end
f = Flow.new
ret = f.chain(value1: :value) do
MyClass.new(2)
end
.chain(value2: :value) do
MyClass.new(3)
end
.chain do |result|
puts result.value1
puts result.value2
end
失敗した場合
次に途中でフローが失敗した場合のサンプルです
フローが失敗した場合には dam に流すことでフローを失敗にすることができます
前の chain の結果がどうだったか判定するのに when_falsy
を使います
このブロック内の結果が false だっと場合に .dam
が実行されてエラー処理に流れます
Flow.new
側では dam に流れた処理を受け取るために .on_dam
を実装します
dam で返却された内容とエラーの箇所がブロックの引数として渡ってきます
require 'waterfall'
class MyClass
include Waterfall
def initialize(value)
@value = value
end
def call
chain do
begin
@value / 0
rescue ZeroDivisionError
@value = false
end
end
when_falsy do
@value
end
.dam do
"ZeroDivisionError"
end
chain(:value) do
@value ** 2
end
end
end
f = Flow.new
ret = f.chain(value1: :value) do
MyClass.new(2)
end
.chain(value2: :value) do
MyClass.new(3)
end
.chain do |result|
puts "SUCCESS"
puts result.value1
puts result.value2
end
.on_dam do |error, context|
puts "ERROR"
puts error
puts context
end
halt_chain
dam に流したあとに続けて別のエラー処理をしたい場合に使います
例えば以下のようにエラーになって dam に流れた場合は @value
にエラーコード的な値を設定することができます
require 'waterfall'
class MyClass
include Waterfall
def initialize(value)
@value = value
end
def call
chain do
begin
@value / 0
rescue ZeroDivisionError
@value = false
end
end
.when_falsy do
@value
end
.dam do
"ZeroDivisionError"
end
.halt_chain do |outflow, error_pool, error_pool_context|
outflow.value = 9999 if error_pool
end
chain(:value) do
@value ** 2
end
end
end
f = Flow.new
ret = f.chain(value1: :value) do
MyClass.new(2)
end
.chain(value2: :value) do
MyClass.new(3)
end
.chain do |result|
puts "SUCCESS"
puts result.value1
puts result.value2
end
.on_dam do |error, error_pool_context, outflow, waterfall|
puts "ERROR"
p waterfall.outflow.value1
end
最後に
Ruby の waterfall を使ってフロー処理を実現してみました
今回は丁寧に do ... end
で書きましたが見やすくするために {}
で 1 行ブロックで書いてもいいかもしれません
フロー間の引数のやり取りが少し面倒なのでそれに慣れないと使いこなすのは難しいかもしれません
Sidekiq などを使ってもフロー処理は実現できますがブローカが必要だったりするので簡単なフロー処理を実現したいのであれば waterfall でもいいかもしれません
0 件のコメント:
コメントを投稿