Class CheckpointingEventHandlingComponentHandlingAny
- All Implemented Interfaces:
Checkpointing,DescribableComponent,MessageHandler,EventHandler,EventHandlingComponent,ReplayStatusChangedHandler,ResetHandler
This component always participates in checkpoint coordination. This keeps every handler in the workflow processor checkpoint-aware, preserving the engine's deferred checkpointing behavior.
- Since:
- 5.4.0
- Author:
- Simon Zambrovski
-
Constructor Summary
ConstructorsConstructorDescriptionCheckpointingEventHandlingComponentHandlingAny(WorkflowEngine workflowEngine, Checkpointing checkpointingHandler) Constructs the component for a workflow engine. -
Method Summary
Modifier and TypeMethodDescriptionvoiddescribeTo(ComponentDescriptor descriptor) Describe the properties ofthis DescribableComponentwith the givendescriptor.onCheckpointAdvanced(Segment segment, TrackingToken requested) Invoked on the processing thread when the processor takes a checkpoint forsegmentthat must coverrequested.voidonSegmentClaimed(Segment segment, @Nullable TrackingToken from, CheckpointTrigger trigger) Invoked whensegmentis claimed, handing the unit theCheckpointTriggerit uses to declare safe positions for that segment.onSegmentReleased(Segment segment, TrackingToken requested) Invoked whensegmentis being released.booleanIndicates whether this component supports reset operations.Methods inherited from class io.axoniq.framework.workflow.runtime.execution.EventHandlingComponentHandlingAny
handle, sequenceIdentifierFor, supportedEvents, supportsMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface org.axonframework.messaging.eventhandling.EventHandler
handleMethods inherited from interface org.axonframework.messaging.eventhandling.EventHandlingComponent
handle, handle, sequenceIdentifierFor, supportedEvents, supports, unwrap
-
Constructor Details
-
CheckpointingEventHandlingComponentHandlingAny
public CheckpointingEventHandlingComponentHandlingAny(WorkflowEngine workflowEngine, Checkpointing checkpointingHandler) Constructs the component for a workflow engine.- Parameters:
workflowEngine- workflow engine to deliver events tocheckpointingHandler- handler to notify when checkpointing is required
-
-
Method Details
-
supportsReset
public boolean supportsReset()Description copied from interface:EventHandlingComponentIndicates whether this component supports reset operations.When
true, this component can participate in replay operations and itsEventHandlingComponent.handle(ResetContext, ProcessingContext)method will be called before replay begins.By default, reset is supported.
- Specified by:
supportsResetin interfaceEventHandlingComponent- Returns:
trueif this component supports reset operations,falseotherwise.
-
onCheckpointAdvanced
public CompletableFuture<TrackingToken> onCheckpointAdvanced(Segment segment, TrackingToken requested) Description copied from interface:CheckpointingInvoked on the processing thread when the processor takes a checkpoint forsegmentthat must coverrequested. Ensure work is durable at least up torequested, discard buffered state, then return the highest token now safe, which may exceedrequestedif more async work has drained. The processor stores the reported token only after every returned future completes. When several checkpointing units share a segment, it does not simply store the lowest report: it reconciles their positions to a single agreed token (the highest any unit reported), re-requesting any unit that has not yet reached it, and stores that, so no unit is ever left durably ahead of the stored token.Contract: the returned token must
coverrequested. The processor only ever advances the stored token: a value at or behind the last stored checkpoint is ignored (never rewinds progress).Exceptional completion. A unit that cannot reach
requestedmust complete its future exceptionally (returning a token that does not coverrequestedis treated the same way). The checkpoint then fails and nothing is stored. The processor handles this as a processing error: it aborts the segment's worker and releases the segment, so the coordinator re-claims it (after a back-off) and resumes from the last stored checkpoint; the events since are redelivered. The stored token therefore never advances on a failed checkpoint, and no progress is lost; an isolated failure costs a segment re-claim and some redelivery.The returned future is the lever for the two workloads described on this type. For an in-memory projection with asynchronous persistence, complete the future once the snapshot of the in-memory state has become durable, reporting the snapshotted position; the processing thread then resumes immediately. For a truly asynchronous handler, complete the future only once the in-flight work has caught up far enough to cover
requested; the processor awaits it before resuming the segment's worker, so the checkpoint acts as a barrier that holds event handling until the asynchronous work has reached this position.- Specified by:
onCheckpointAdvancedin interfaceCheckpointing- Parameters:
segment- the segment being checkpointedrequested- the segment-scoped position this checkpoint must cover (the highest anyone requested, or the batch-end token in auto mode)- Returns:
- the highest token this unit is durably safe at; must cover
requestedand must not sit behind the last persisted checkpoint
-
onSegmentClaimed
public void onSegmentClaimed(Segment segment, @Nullable TrackingToken from, CheckpointTrigger trigger) Description copied from interface:CheckpointingInvoked whensegmentis claimed, handing the unit theCheckpointTriggerit uses to declare safe positions for that segment. Retain it keyed by segment; it is invalid afterCheckpointing.onSegmentReleased(Segment, TrackingToken).The
fromtoken is the position this segment resumes at, the same positionCheckpointing.onSegmentReleased(Segment, TrackingToken)carries. It shows how far along the stream the segment is before the first event is delivered, so a unit restoring state at claim time can see whether it is picking up a segment at the end of the stream or one that still has history to replay.Defaults to a no-op: a unit that obtains its trigger another way (typically through a
CheckpointTriggerhandler-method parameter) does not need to retain it here.Invoked synchronously as part of claiming the segment. Throwing from this method fails the claim cycle: the segment is not claimed and the coordinator retries it (after a back-off). This is deliberate: a component that never received its trigger could never checkpoint, so signal a genuine inability to accept the claim by throwing, but do not throw for transient conditions that a retained trigger would handle later.
- Specified by:
onSegmentClaimedin interfaceCheckpointing- Parameters:
segment- the segment that was claimedfrom- the segment's storedTrackingToken, the position processing resumes from, ornullwhen processing starts at the beginning of the streamtrigger- the handle to request checkpoints forsegment
-
onSegmentReleased
Description copied from interface:CheckpointingInvoked whensegmentis being released. Flush everything handled so far, discard the segment's local state, and report the highest token made durable; the processor reconciles it with any co-located units (the same way asCheckpointing.onCheckpointAdvanced(Segment, TrackingToken)) and stores the result while still holding the claim, then releases the claim. After this theCheckpointTriggerfor the segment is invalid.The returned token must lie in the range
[lastStoredCheckpoint, upTo]: it must not rewind below the last persisted checkpoint (a regressive value is ignored), and it cannot exceedupTo(a unit can only be durable up to what it was handed). Returning a token belowupTois the normal lagging case: the uncovered tail (from the returned token up toupTo) is simply reprocessed on the next claim. Forcing the value all the way up toupTois not required and is often impossible for asynchronous work.The same two workloads described on this type apply here. An in-memory projection with asynchronous persistence takes a final snapshot and completes the future once it is durable, normally reporting
upTo. A truly asynchronous handler completes the future once its in-flight work has drained as far as it can before the claim is given up, reporting whatever position is durable by then, typically lower thanupTo, with the uncovered tail reprocessed on the next claim. UnlikeonCheckpointAdvanced, reachingupTois not required here: there is no later request to satisfy, so an asynchronous unit may report best-effort progress rather than forcing a full drain.Exceptional completion. Unlike
Checkpointing.onCheckpointAdvanced(Segment, TrackingToken), a future that completes exceptionally here does not abort or retry: the segment is being given up regardless. The release still proceeds: the checkpoint simply does not advance for what the unit could not confirm, the claim is freed, and the uncovered tail (everything past the last stored checkpoint) is reprocessed when the segment is next claimed. There is nothing the framework can do about a genuine durability failure at release beyond this reprocessing, so a unit that knows a lower already-durable position should report it (return it) rather than fail, to keep the redelivered window as small as possible.Defaults to
onCheckpointAdvanced(segment, upTo), i.e. a full flush up to the consumed position. Because that delegate mustcoverits argument or complete exceptionally, the default does not advance the checkpoint on release if the unit cannot reachupTo(the claim is still released, per the exceptional-completion behaviour above); override this method to instead report a lower already-durable position (the relaxed, best-effort semantics) for an asynchronous unit that may legitimately lag behindupToat release.- Specified by:
onSegmentReleasedin interfaceCheckpointing- Parameters:
segment- the segment being releasedrequested- the segment'slastConsumedToken: the position to drain toward- Returns:
- the highest token durably persisted; at least the last persisted checkpoint and at most
upTo, and typically lower thanupTowhen asynchronous work is still in flight
-
describeTo
Description copied from interface:DescribableComponentDescribe the properties ofthis DescribableComponentwith the givendescriptor.Components should call the appropriate
describePropertymethods on the descriptor to register their properties. The descriptor is responsible for determining how these properties are formatted and structured in the final output.Best Practices: As a general rule, all relevant fields of a
DescribableComponentimplementation should be described in this method. However, developers have discretion to include only the fields that make sense in the context. Not every field may be meaningful for description purposes, especially internal implementation details. Furthermore, components might want to expose different information based on their current state. The final decision on what properties to include lies with the person implementing thedescribeTomethod, who should focus on providing information that is useful for understanding the component's configuration and state.Example implementation:
public void describeTo(ComponentDescriptor descriptor) { descriptor.describeProperty("name", this.name); descriptor.describeProperty("enabled", this.enabled); descriptor.describeProperty("configuration", this.configuration); // A nested component descriptor.describeProperty("handlers", this.eventHandlers); // A collection }- Specified by:
describeToin interfaceDescribableComponent- Overrides:
describeToin classEventHandlingComponentHandlingAny- Parameters:
descriptor- The component descriptor to describethis DescribableComponentn its properties in.
-