-
Notifications
You must be signed in to change notification settings - Fork 42
feat: added interleave/4 #83
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
base: master
Are you sure you want to change the base?
Conversation
…sly defined transaction
sage :: t(), | ||
name :: stage_name(), | ||
intermediate_transaction :: intermediate_transaction(), | ||
compensation :: compensation() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we also want compensations to be reported in your use case? If so we'll need to add a type for it too or reuse intermediate_transaction
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. My use case actually doesn't require compensations at all, I just added them for completeness/generality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should add it for completeness. If there is some reporter on the saga progress, it should also be able to report compensation progress.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So are you saying that an interleaved compensation should be passed the previously run compensation, to mirror the intermediate_transaction
?
lib/sage.ex
Outdated
|
||
[stage, {name, build_operation!(:run, transaction, compensation)}] | ||
end) | ||
|> Enum.reduce(new(), fn stage, sage -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you don't need to reconstruct the Sage completely, just update the existing one like so: %{sage | steps: steps}
. Struct can be extended in the future and we don't want to re-apply everything else that is in there or lose it if we forget about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I did this because I didn't want to lose the duplicate stage name checking that add_step
gives. But I can refactor it for sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took a stab at a refactor, but I'm not sold on it. I am leaning towards thinking that the best approach is to rebuild the saga and refactor later if need be, but let me know what you think of the refactor attempt.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@apreifsteck if we use the suggestion below and namespace the interleaves then there can't be a collisition with the regular stage names, so we can do something like this:
%{sage | stage_names: MapSet.add(sage.stage_names, {:interleave, name}), steps: steps)
then just add a manual check for another interleave not colliding with the {:interleave, name}
right in this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've implemented your suggestion to use tuples as the stage names. I'm not sure if I understand the advantage of adding a check in this function to look for duplicate stage names. That seems like a separate responsibility that interleave
and run
could both take advantage of.
Thank you! |
What is being changed
Adding:
Sage.interleave/4
. This allows the user to add a transaction to be executed after every stage they had manually defined before.Rationale
Say you're working with a "token" struct, and you want to saga-fy this kind of code where you want to do something
with the intermediate results
This code is a bit tedious to write to begin with and this PR is meant to enable Sage to help with this kind of pattern by turning the above code into