Closed ajengs closed 4 years ago
Hello @ajengs, sorry for the delayed reply.
Can you show me how do you build your Sagas? The idea is that functions indeed do not need to know name of previous step, instead you want to use those names when you build your saga, eg.:
...
|> run(:user, &create_user/2)
|> run(:plans, &fetch_subscription_plans(&1.user, &2), &subscription_plans_circuit_breaker/3)
This makes the variable that steps are using explicit and under your control. If you would just always use last effect (which is not always the case as sometimes you want multiple effects), then somebody can reorder the saga and break it without noticing.
Hmm, I see.. that way also works if I define the name and use it when constructing. I use it this way so I can encapsulate it in each module. And about reorder, that's more or less my requirements too. My Saga
modules should be able to be reused and reordered based on some flows without much change.
defmodule Api.OnboardingStatusController do
alias Saga.{Status, Merchant, WorkerFlow}
...
Sage.new()
|> Status.maybe_update()
|> Merchant.get_and_validate_merchant_by_phone()
|> Merchant.get_and_validate_merchant_by_id_number()
|> WorkerFlow.maybe_trigger_flow()
|> Sage.execute(attrs)
...
defmodule Saga.Merchant
def get_and_validate_merchant_by_phone(sage) do
Sage.run(sage, :merchant_by_phone, &validate_by_phone/2)
end
def get_and_validate_merchant_by_id_number(sage) do
Sage.run(sage, :merchant_by_id_number, &validate_by_id_number/2)
end
@ajengs maybe it would still be better if you would have something like this:
def get_and_validate_merchant_by_phone(sage) do
- Sage.run(sage, :merchant_by_phone, &validate_by_phone/2)
+ Sage.run(sage, :merchant_by_phone, &validate_by_phone(&1.phone, &2))
end
It does not look as nice but it is explicit and you don't need to go very deep to understand dependencies between sage steps, does not require you to make sure that validate_by_phone/2
only accepts phone
and nothing else (protecting from reordering problem) and still gives you lots of freedom to accept multiple effects whenever you need.
Got it. I can pass the name when building the sage and pass the it to the next step 👌 And you're right, now I have requirement to use effects from multiple sage steps, it's easier this way. Thanks @AndrewDryga !
Hi, I'm just starting to use this library, which would really help to solve my dependencies hell. But my case will need latest effect to be processed by next stage transaction. I know that we can access
effects_so_far
, but we will need to know the previous stage name executed.I'd like to have
latest_effect
so each stage does not need to care what is previously executed and can access the latest parameters directly.Please help to see if it makes sense or is there any other better way to achieve this.