How are Saga associationValues expected to match the Segment's mask?

We can’t seem to find where in Axon the segment mask is updated to reflect the association value.

I’m sure I’m misreading the code but it appears to me that a Segment’s mask is only really set to match the hashCode of an Object during construction. Therefore the Object should exist before a Segment is created? When looking at the source for the Saga we are validating its creation against the Segment. This at the moment feels like a Chicken & the Egg problem. What should happen first?

Hi Michael,

the segment mask and segment Id together for the basis on which work is divided between different segments. The segment Id itself is not enough, because a segment of 1 is different than a segment of 1 when there is also a segment with ID 3. Masks only change when a segment is split (in that case, an extra 1 is added in front of the most significant 1).

For regular event handlers, the handler instance that handles an event, is the one where the sequencing policy value for that event mathes the segment (ID and mask) that the handler claimed. The sequencing policy value is provided by the Sequencing Policy object that you can configure for a Processing Group.

For Sagas, this works slightly differently. A processor will still have a segment claimed, but this time, segment isn’t used to filter out events, rather it is used to define which Saga instances to execute events on. This mechanism helps ensure that events are executed sequentially for any given Saga. In other words, all event are handled by the Saga Manager. That Saga Manager will then use the Association Values to find matching Saga Identifiers. Only the Saga identifier that match the claimed segment are processed.

When there are no matches found at all, and the SagaEventHandler is annotated with @StartSaga, then one of the processing threads should be responsible for creating that Saga instance. To make sure only one of the active threads creates the Saga, the value of the first association property is used. That value’s hash is tested against the segment mask and Id. If it matches, that thread is responsible for the Saga instance. Note that the identifier generated for the Saga instance will always match that Segment, too, so that any update events after the creation are handled by the same thread, guaranteeing sequential processing.

Hope this explains the mechanism.
In short, the SequencingPolicy is not used at all for Sagas. The association value should just have a consistent hash() function (which is always the case for simple types and Strings), to ensure different attempts to calculate the hash on different nodes (if applicable) results in the same value.

Hope this helps.



I am still confused about the segmentation process. When does the segmenting happen? Is it the TEP that first use mask to split the event stream into the segment and then pick a thread to claim that segment? (In the case of Saga, it is the Saga Manager since you said above that Saga manager process all events?) So if this true, say I have 4 segments, that means I can process at most 4 different Saga instances in parallel, correct? And what is event with @StartSaga comes after other events targeted to the same Saga, is this even possible?

I was also reading this thread:!searchin/axonframework/segment$20configuration|sort:date/axonframework/tXhJ1ATlQzY/PP_l5FazCwAJ The first post there seems to me like it is saying the segmenting happens first mysteriously thus we could result in that events targeted to the same saga instance get delivered to different segments?