Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Easier way to add pre-defined stages #46

Open
ssbb opened this issue Nov 27, 2019 · 2 comments
Open

Easier way to add pre-defined stages #46

ssbb opened this issue Nov 27, 2019 · 2 comments

Comments

@ssbb
Copy link

ssbb commented Nov 27, 2019

I have few sagas which can be used independently and in another more high-level sagas. Just curious what is the proper way to use shared arguments/stages with such workflow.

Right now I have two functions process(%Sage{} = sage) which running all stages and run(...). So I assume required data always in effects_so_far. For run function I pass accepted arguments into "fake" stages:

Sage.new()
|> Sage.run(:required_effect, fn _effects, _params -> {:ok, arg1} end)

What is proper way to do it?

@AndrewDryga
Copy link
Member

AndrewDryga commented Jan 26, 2020

Hey @ssbb, Im not sure that I understood the question, can you please give a real life use case (with more code) and Ill think how we can improve Sage in this direction? Thank you 🙏.

@ssbb
Copy link
Author

ssbb commented Jan 31, 2020

Hi @AndrewDryga, we discussed this in Slack actually. My code looks like this:

  def run(%DepositForm{} = deposit, user, transaction, application) do
    result =
      Sage.new()
      |> Sage.run(:transaction, fn _effects, _params -> {:ok, transaction} end)
      |> Sage.run(:application, fn _effects, _params -> {:ok, application} end)
      |> process()
      |> Sage.transaction(Repo, %{deposit: deposit, user: user})

    case result do
      {:ok, _, %{update_payment: payment}} ->
        {:ok, payment}

      {:error, %Stripe.Error{user_message: user_message, message: message}} ->
        {:error, "Deposit error: #{user_message || message}"}

      err ->
        Sentry.capture_exception(nil, extra: %{error: err}, level: "error")
        err
    end
  end

  def skip(sage) do
    Sage.run(sage, :deposit, fn _effects, _params ->
      {:ok, nil}
    end)
  end

  def process(sage) do
    sage
    |> create_payment
    |> customer
    |> charge
    |> update_payment
    |> deliver_email
    |> deliver_slack
  end

Really I am ok with "fake" Sage.run calls but when I asked about this in Slack you said I should create an issue.

Basically it can be used 2 ways - via run to run this saga when we already have transaction and application or via process as part of another saga (so transaction and application will be created in previous stages).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants