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

Except-Logic for DisallowReplay annotation #2775

Open
nils-christian opened this issue Jul 4, 2023 · 3 comments
Open

Except-Logic for DisallowReplay annotation #2775

nils-christian opened this issue Jul 4, 2023 · 3 comments
Assignees
Labels
Status: Under Discussion Use to signal that the issue in question is being discussed. Type: Feature Use to signal an issue is completely new to the project.

Comments

@nils-christian
Copy link
Contributor

Hi,

Assume the following situation: We have a processing group "MyProcessingGroup" with several event handlers, which maintain a read model and are allowed to be replayed. Now we add another handler "MyNewEventHandler" to this group, which is usually not allowed to be replayed, as it sends commands with side effects. One could of course argue that "MyNewEventHandler" belongs in a new processing group, but in our case it uses a (rather extensive) read model which is already maintained by the handlers of "MyProcessingGroup". So we basically want to allow the replay for "MyNewEventHandler" (so that it sends the commands for a prefilling) once and never again.

Unfortunately, it is not possible the change the behaviour of the ReplayAwareMessageHandlerWrapper. Thus we implemented an own annotation named DisallowReplayExceptFor which behaves like "DisallowReplay" but allows to add certain replay contexts which are an exception for this rule:

@DisallowReplayExceptFor("2.0.0")
public class MyNewEventHandler {
   ...
}

When performing the replay, we use a certain context:

eventProcessor.resetTokens( "2.0.0" );

This makes sure that "MyNewEventHandler" is executed during the replay of version 2.0.0, but not for any other replay that follows after that.

We would suggest to add this except-logic to the DisallowReplay annotation of Axon.

@DisallowReplay(exceptFor = { "2.0.0" })
public class MyNewEventHandler {
   ...
}

The ReplayAwareMessageHandlerWrapper should be changed to recognize this logic. If there is at least one entry for exceptFor, the wrapper should unwrap the replay context as String. If such a replay context does not exist or if it does not match at least one of the entries in exceptFor, the replay should be blocked.

One issue for the implementation might be that DisallowReplay is actually defined via AllowReplay.

Best regards

Nils

@nils-christian nils-christian added the Type: Feature Use to signal an issue is completely new to the project. label Jul 4, 2023
@smcvb smcvb added the Status: Under Discussion Use to signal that the issue in question is being discussed. label Jul 6, 2023
@CodeDrivenMitch
Copy link
Member

Hello @nils-christian! Cool to see your usage of the 4.6 ReplayContext feature here. I discussed this issue in the team, but we think this feature request is too specific for your use-case. It's not the first similar request we have gotten, and every time it's a little bit different. In this case, you want to skip certain events if the context is set. This could be achieved by a message handler interceptor like so:

    @MessageHandlerInterceptor
    Object intercept(ReplayStatus replayStatus, @ReplayContext Object context, InterceptorChain interceptorChain) throws Exception {
        if(replayStatus.isReplay() && (!(context instanceof String) || !context.equals("2.0.0"))) {
            return null;
        }
        return interceptorChain.proceed();
    }

To be clear, we could generify this to the annotation, but as I said, it's very specific. The customer I built this feature for wanted to filter on the event's index in the event store, only replaying those specific events. Another wanted the exact opposite.
We are very happy with how customizable this feature makes replays right now. This is why we won't implement this feature, but at some point in the futur,e I will do a blog or video on this!

Thanks for contributing your feature request! If you feel I am missing something obvious concerning your request, be sure to reply!

@nils-christian
Copy link
Contributor Author

Hi @CodeDrivenMitch,

I understand and agree with your assessment that the request is too specific. However, I wonder if it would help if we would be able to change the behaviour of the ReplayAwareMessageHandlerWrapper. This is currently not possible, as the wrapper is not a Spring bean or some part of the configuration, but rather loaded via the service provider interface mechanism. If we would be able to do so, we could define this specific behaviour in a more additive way instead of having to reimplement the behaviour of the original wrapper.

@DisallowReplay
@ExceptFor("2.0.0")
public class MyNewEventHandler {
   ...
}

However, this is more of a personal preference and I assume that making the wrapper a part of the configuration is not something that can be done easily. Thus I would suggest we close this issue.

Best regards

Nils

@smcvb
Copy link
Member

smcvb commented Jul 10, 2023

We made the ReplayAwareMessageHandlerWrapper more closed in the past because, back then, it made sense.
However, we would like to service the behavior you've implemented in an easier fashion where possible.

Hence, I would opt the keep it open actually! :-)
Perhaps we can rename the title or adjust the description to clarify the discussion we've had.

In short, I think it's fair to put in the effort to simplify your implementation of the except-logic.
Thus, having Axon Framework support the capability to go for an "except-logic for the @DisallowReplay".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Under Discussion Use to signal that the issue in question is being discussed. Type: Feature Use to signal an issue is completely new to the project.
Projects
None yet
Development

No branches or pull requests

3 participants