[#4991] Rework SagaLifecycle to resolvable parameter - #4997
Conversation
Rough sketch to port the SagaLifecycle. Do so by adjusting the SagaLifecycle by not having static methods, but plain methods. Furthermore, let the Saga be an implementation of the SagaLifecycle. From there, we should add the SagaLifecycle to the ProcessingContext when handling a SagaEventHandler in the (Annotated)Saga. To wire the SagaLifecycle, users can simply add a parameter for it with their SagaEventHandler. Lastly, move other annotation-specific components from the stash to this project, as those are utilized by the annotation solution (in)directly. #4991
Expand api-changes #4991
There was a problem hiding this comment.
A few nits, generally good job. Thanks for the PR! :)
I think we should wait with merging that till featsaga-store merge.
| // TODO | ||
| // TODO |
There was a problem hiding this comment.
What are those TODO about? I thinks supportsReset returning false is appropriate here.
There was a problem hiding this comment.
Whoops, totally right. This is a leftover that I missed to fix. Adjusted it, by overriding the supportsReset to return false.
Added, I defaulted the handle(ResetContext, ProcessingContext) method here as well, throwing the throw new ResetNotSupportedException("Sagas do not support reset"); exception from the AF4-version of that method.
| private final AssociationValues associationValues; | ||
| private final String sagaId; | ||
| private final T sagaInstance; | ||
| private volatile boolean isActive = true; |
There was a problem hiding this comment.
Is saga always accessed by single thread? I believe the LockingSagaRepository needs to care about that, am I right?
There was a problem hiding this comment.
Yep, correct! The LockingSagaRepository will take care of that :-)
| * This is the {@link ProcessingContext}-scoped replacement for the Axon Framework 4 {@code SagaLifecycle}, which | ||
| * exposed the very same operations as {@code static} methods resolved through a {@code ThreadLocal}. Axon Framework |
There was a problem hiding this comment.
Since it's a replacement should it be since 5.4.0, or earlier version?
Regardless, I think the name "SagaLifecycle" is nice, just use instance methods instead of the static ones :)
There was a problem hiding this comment.
I added a quick doc-draft as the old version had practically no JavaDoc...I've fine-tuned it a little right now.
I've also marked it as since 3.0.0, as that's the accurate since tag.
|
|
||
| @Override | ||
| public Set<QualifiedName> supportedEvents() { | ||
| throw new UnsupportedOperationException("TODO"); |
There was a problem hiding this comment.
I'd place TODOs here with the issue number.
| * @author Steven van Beelen | ||
| * @since 5.4.0 | ||
| */ | ||
| public class SagaLifecycleParameterResolverFactory implements ParameterResolverFactory { |
There was a problem hiding this comment.
I don't see tests for that.
| testSubject.handle(matchingEvent, StubProcessingContext.forMessage(matchingEvent)).asCompletableFuture().join(); | ||
| var nonMatchingEvent = new GenericEventMessage(new MessageType("event"), new RegularEvent("wrongId")); | ||
| testSubject.handle(nonMatchingEvent, StubProcessingContext.forMessage(nonMatchingEvent)).asCompletableFuture().join(); | ||
| var unhandledEvent = new GenericEventMessage(new MessageType("event"), new Object()); | ||
| testSubject.handle(unhandledEvent, StubProcessingContext.forMessage(unhandledEvent)).asCompletableFuture().join(); |
There was a problem hiding this comment.
You have a few join() without timeouts here.
This pull request reworks the
SagaLifecycleto be a resolvable parameter instead of a statically invoked infrastructure component.This is required, as the old approach used the ThreadLocal logic of the previous
UnitOfWorkto access theSaga, which is no longer an option with AF5.Instead, it's something that's injected, the
ProcessingContext.Hence, this can be seen as one of the few breaking changes for users moving towards
axon-legacyin 5.4.0, which is sadly mandatory.To limit the break, the package of the
SagaLifecycleis the same as well as the name.The main difference for users is two-fold:
staticmethods.From a technical stance, the only
SagaLifecycleimplementation was theAnnotatedSaga.Hence, this PR also pulls in that class, immediately adjusting it to be an
EventHandlingComponentinstead of anEventHandlerInvoker.This portion has a large scoped outcome on this PR, as it had to pull in:
Sagainterface, as it's used by theAnnotatedSaga.@StartSaga,@SagaEventHandlerand@EndSagaannotations, as we're dealing with theAnnotatedSagaSagaMethodMessageHandlerDefinitionto be able to wire the@SagaEventHandlercorrectlyAssociationResolverplus its implementations, as those are used by theSagaEventHandlerandSagaMethodMessageHandlerDefinitionalikeSagaCreationPolicy, as it's by theSagaMethodMessageHandlerDefinitionSagaModeland it's creation, as those are used by theAnnotatedSagaNote that this PR does not fully implement all the
EventHandlingComponentoperations yet!This PR is already bigger than I wanted, so I decided against doing that part here as well.
Expect a follow-up PR instead.
In doing the above, this PR resolves #4991.