Class DisruptorCommandBus
- All Implemented Interfaces:
org.axonframework.commandhandling.CommandBus,org.axonframework.messaging.MessageDispatchInterceptorSupport<org.axonframework.commandhandling.CommandMessage<?>>,org.axonframework.messaging.MessageHandlerInterceptorSupport<org.axonframework.commandhandling.CommandMessage<?>>
Disruptor,
which ensures that two steps are executed sequentially in these threads, while minimizing locking and inter-thread
communication.
The process is split into two separate steps, each of which is executed in a different thread:
- Command Handler execution
This process invokes the command handler with the incoming command. The result and changes to the aggregate are recorded for the next step. - Event storage and publication
This process stores all generated domain events and publishes them (with any optional application events) to the event bus. Finally, an asynchronous task is scheduled to invoke the command handler callback with the result of the command handling result.
This separation of process steps makes this implementation very efficient and highly performing. However, it does
not cope with exceptions very well. When an exception occurs, an Aggregate that has been loaded is potentially
corrupt. That means that an aggregate does not represent a state that can be reproduced by replaying its committed
events. Although this implementation will recover from this corrupt state, it may result in a number of commands
being rejected in the meantime. These command may be retried if the cause of the AggregateStateCorruptedException does not indicate a non-transient error.
Commands that have been executed against a potentially corrupt Aggregate will result in a AggregateStateCorruptedException exception. These commands are automatically rescheduled for processing by
default. Use DisruptorCommandBus.Builder.rescheduleCommandsOnCorruptState(boolean) to disable this feature. Note
that the order in which commands are executed is not fully guaranteed when this feature is enabled (default).
Limitations of this implementation
Although this implementation allows applications to achieve extreme performance (over 1M commands on commodity hardware), it does have some limitations. It only allows a single aggregate to be invoked during command processing.
This implementation can only work with Event Sourced Aggregates. Infrastructure considerations
This CommandBus implementation has special requirements for the Repositories being used during Command Processing.
Therefore, the Repository instance to use in the Command Handler must be created using createRepository(EventStore, AggregateFactory, RepositoryProvider).
Using another repository will most likely result in undefined behavior.
The DisruptorCommandBus must have access to at least 3 threads, two of which are permanently used while the DisruptorCommandBus is operational. At least one additional thread is required to invoke callbacks and initiate a recovery process in the case of exceptions.
Consider providing an alternative IdentifierFactory implementation. The default
implementation used UUID.randomUUID() to generated identifier for Events. The poor performance of
this method severely impacts overall performance of the DisruptorCommandBus. A better performing alternative is, for
example, com.eaio.uuid.UUID
- Since:
- 2.0
- Author:
- Allard Buijze
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classBuilder class to instantiate aDisruptorCommandBus. -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedInstantiate aDisruptorCommandBusbased on the fields contained in theDisruptorCommandBus.Builder. -
Method Summary
Modifier and TypeMethodDescriptionstatic DisruptorCommandBus.Builderbuilder()Instantiate a Builder to be able to create aDisruptorCommandBus.<T> org.axonframework.modelling.command.Repository<T>createRepository(org.axonframework.eventsourcing.eventstore.EventStore eventStore, org.axonframework.eventsourcing.AggregateFactory<T> aggregateFactory) Creates a repository instance for an Event Sourced aggregate that is created by the giveneventStoreandaggregateFactory.<T> org.axonframework.modelling.command.Repository<T>createRepository(org.axonframework.eventsourcing.eventstore.EventStore eventStore, org.axonframework.eventsourcing.AggregateFactory<T> aggregateFactory, org.axonframework.eventsourcing.SnapshotTriggerDefinition snapshotTriggerDefinition) Creates a repository instance for an Event Sourced aggregate, source from giveneventStore, that is created by the givenaggregateFactory.<T> org.axonframework.modelling.command.Repository<T>createRepository(org.axonframework.eventsourcing.eventstore.EventStore eventStore, org.axonframework.eventsourcing.AggregateFactory<T> aggregateFactory, org.axonframework.eventsourcing.SnapshotTriggerDefinition snapshotTriggerDefinition, org.axonframework.messaging.annotation.ParameterResolverFactory parameterResolverFactory) Creates a repository instance for an Event Sourced aggregate, sourced from giveneventStore, that is created by the givenaggregateFactory.<T> org.axonframework.modelling.command.Repository<T>createRepository(org.axonframework.eventsourcing.eventstore.EventStore eventStore, org.axonframework.eventsourcing.AggregateFactory<T> aggregateFactory, org.axonframework.eventsourcing.SnapshotTriggerDefinition snapshotTriggerDefinition, org.axonframework.messaging.annotation.ParameterResolverFactory parameterResolverFactory, org.axonframework.messaging.annotation.HandlerDefinition handlerDefinition, org.axonframework.modelling.command.RepositoryProvider repositoryProvider) Creates a repository instance for an Event Sourced aggregate, sourced from giveneventStore, that is created by the givenaggregateFactory.<T> org.axonframework.modelling.command.Repository<T>createRepository(org.axonframework.eventsourcing.eventstore.EventStore eventStore, org.axonframework.eventsourcing.AggregateFactory<T> aggregateFactory, org.axonframework.eventsourcing.SnapshotTriggerDefinition snapshotTriggerDefinition, org.axonframework.modelling.command.RepositoryProvider repositoryProvider) Creates a repository instance for an Event Sourced aggregate, source from giveneventStore, that is created by the givenaggregateFactory.<T> org.axonframework.modelling.command.Repository<T>createRepository(org.axonframework.eventsourcing.eventstore.EventStore eventStore, org.axonframework.eventsourcing.AggregateFactory<T> aggregateFactory, org.axonframework.messaging.annotation.ParameterResolverFactory parameterResolverFactory) Creates a repository instance for an Event Sourced aggregate that is created by the givenaggregateFactoryand sourced from giveneventStore.<T> org.axonframework.modelling.command.Repository<T>createRepository(org.axonframework.eventsourcing.eventstore.EventStore eventStore, org.axonframework.eventsourcing.AggregateFactory<T> aggregateFactory, org.axonframework.messaging.annotation.ParameterResolverFactory parameterResolverFactory, org.axonframework.messaging.annotation.HandlerDefinition handlerDefinition, org.axonframework.modelling.command.RepositoryProvider repositoryProvider) Creates a repository instance for an Event Sourced aggregate that is created by the givenaggregateFactoryand sourced from giveneventStore.<T> org.axonframework.modelling.command.Repository<T>createRepository(org.axonframework.eventsourcing.eventstore.EventStore eventStore, org.axonframework.eventsourcing.AggregateFactory<T> aggregateFactory, org.axonframework.modelling.command.RepositoryProvider repositoryProvider) Creates a repository instance for an Event Sourced aggregate that is created by the giveneventStoreandaggregateFactory.<C> voiddispatch(org.axonframework.commandhandling.CommandMessage<C> command) <C,R> void dispatch(org.axonframework.commandhandling.CommandMessage<C> command, org.axonframework.commandhandling.CommandCallback<? super C, ? super R> callback) org.axonframework.common.RegistrationregisterDispatchInterceptor(org.axonframework.messaging.MessageDispatchInterceptor<? super org.axonframework.commandhandling.CommandMessage<?>> dispatchInterceptor) org.axonframework.common.RegistrationregisterHandlerInterceptor(org.axonframework.messaging.MessageHandlerInterceptor<? super org.axonframework.commandhandling.CommandMessage<?>> handlerInterceptor) voidstop()Shuts down the command bus.org.axonframework.common.Registrationsubscribe(String commandName, org.axonframework.messaging.MessageHandler<? super org.axonframework.commandhandling.CommandMessage<?>> handler)
-
Constructor Details
-
DisruptorCommandBus
Instantiate aDisruptorCommandBusbased on the fields contained in theDisruptorCommandBus.Builder. The Threads required for command execution are immediately requested from the Configuration's Executor, if any. Otherwise, they are created.Will assert that the
CommandTargetResolver,MessageMonitor,RollbackConfiguration,ProducerType,WaitStrategyandCacheare notnull. Additional verification is done on the thecoolingDownPeriod,publisherThreadCount,bufferSizeandinvokerThreadCountto check whether they are positive numbers. If any of these checks fails, anAxonConfigurationExceptionwill be thrown.- Parameters:
builder- theDisruptorCommandBus.Builderused to instantiate aDisruptorCommandBusinstance
-
-
Method Details
-
builder
Instantiate a Builder to be able to create aDisruptorCommandBus.The following configurable fields have defaults:
- The
rescheduleCommandsOnCorruptStatedefaults totrue. - The
coolingDownPerioddefaults to1000. - The
CommandTargetResolverdefaults to anAnnotationCommandTargetResolver. - The
publisherThreadCountdefaults to1. - The
MessageMonitordefaults toNoOpMessageMonitor.INSTANCE. - The
RollbackConfigurationdefaults toRollbackConfigurationType.UNCHECKED_EXCEPTIONS. - The
bufferSizedefaults to4096. - The
ProducerTypedefaults toProducerType.MULTI. - The
WaitStrategydefaults to aBlockingWaitStrategy. - The
invokerThreadCountdefaults to1. - The
Cachedefaults toNoCache.INSTANCE. - The
DuplicateCommandHandlerResolverdefaults toDuplicateCommandHandlerResolution.logAndOverride().
Executor.The
CommandTargetResolver,MessageMonitor,RollbackConfiguration,ProducerType,WaitStrategyandCacheare a hard requirements. Thus setting them tonullwill result in anAxonConfigurationException. Additionally, thecoolingDownPeriod,publisherThreadCount,bufferSizeandinvokerThreadCounthave a positive number constraint, thus will also result in an AxonConfigurationException if set otherwise.- Returns:
- a Builder to be able to create a
DisruptorCommandBus
- The
-
dispatch
public <C> void dispatch(@Nonnull org.axonframework.commandhandling.CommandMessage<C> command) - Specified by:
dispatchin interfaceorg.axonframework.commandhandling.CommandBus
-
dispatch
public <C,R> void dispatch(@Nonnull org.axonframework.commandhandling.CommandMessage<C> command, @Nonnull org.axonframework.commandhandling.CommandCallback<? super C, ? super R> callback) - Specified by:
dispatchin interfaceorg.axonframework.commandhandling.CommandBus
-
createRepository
public <T> org.axonframework.modelling.command.Repository<T> createRepository(org.axonframework.eventsourcing.eventstore.EventStore eventStore, org.axonframework.eventsourcing.AggregateFactory<T> aggregateFactory) Creates a repository instance for an Event Sourced aggregate that is created by the giveneventStoreandaggregateFactory.The repository returned must be used by Command Handlers subscribed to this Command Bus for loading aggregate instances. Using any other repository instance may result in undefined outcome (a.k.a. concurrency problems).
- Type Parameters:
T- The type of aggregate to create the repository for- Parameters:
eventStore- The Event Store to retrieve and persist eventsaggregateFactory- The factory creating uninitialized instances of the Aggregate- Returns:
- the repository that provides access to stored aggregates
-
createRepository
public <T> org.axonframework.modelling.command.Repository<T> createRepository(org.axonframework.eventsourcing.eventstore.EventStore eventStore, org.axonframework.eventsourcing.AggregateFactory<T> aggregateFactory, org.axonframework.modelling.command.RepositoryProvider repositoryProvider) Creates a repository instance for an Event Sourced aggregate that is created by the giveneventStoreandaggregateFactory.The repository returned must be used by Command Handlers subscribed to this Command Bus for loading aggregate instances. Using any other repository instance may result in undefined outcome (a.k.a. concurrency problems).
- Type Parameters:
T- The type of aggregate to create the repository for- Parameters:
eventStore- The Event Store to retrieve and persist eventsaggregateFactory- The factory creating uninitialized instances of the AggregaterepositoryProvider- Provides repositories for specified aggregate types- Returns:
- the repository that provides access to stored aggregates
-
createRepository
public <T> org.axonframework.modelling.command.Repository<T> createRepository(org.axonframework.eventsourcing.eventstore.EventStore eventStore, org.axonframework.eventsourcing.AggregateFactory<T> aggregateFactory, org.axonframework.eventsourcing.SnapshotTriggerDefinition snapshotTriggerDefinition) Creates a repository instance for an Event Sourced aggregate, source from giveneventStore, that is created by the givenaggregateFactory.The repository returned must be used by Command Handlers subscribed to this Command Bus for loading aggregate instances. Using any other repository instance may result in undefined outcome (a.k.a. concurrency problems).
- Type Parameters:
T- The type of aggregate to create the repository for- Parameters:
eventStore- The Event Store to retrieve and persist eventsaggregateFactory- The factory creating uninitialized instances of the AggregatesnapshotTriggerDefinition- The trigger definition for creating snapshots- Returns:
- the repository that provides access to stored aggregates
-
createRepository
public <T> org.axonframework.modelling.command.Repository<T> createRepository(org.axonframework.eventsourcing.eventstore.EventStore eventStore, org.axonframework.eventsourcing.AggregateFactory<T> aggregateFactory, org.axonframework.eventsourcing.SnapshotTriggerDefinition snapshotTriggerDefinition, org.axonframework.modelling.command.RepositoryProvider repositoryProvider) Creates a repository instance for an Event Sourced aggregate, source from giveneventStore, that is created by the givenaggregateFactory. The givendecoratoris used to decorate event streams.The repository returned must be used by Command Handlers subscribed to this Command Bus for loading aggregate instances. Using any other repository instance may result in undefined outcome (a.k.a. concurrency problems).
Note that a second invocation of this method with an aggregate factory for the same aggregate type may return the same instance as the first invocation, even if the given
decoratoris different.- Type Parameters:
T- The type of aggregate to create the repository for- Parameters:
eventStore- The Event Store to retrieve and persist eventsaggregateFactory- The factory creating uninitialized instances of the AggregatesnapshotTriggerDefinition- The trigger definition for creating snapshotsrepositoryProvider- Provides repositories for specified aggregate types- Returns:
- the repository that provides access to stored aggregates
-
createRepository
public <T> org.axonframework.modelling.command.Repository<T> createRepository(org.axonframework.eventsourcing.eventstore.EventStore eventStore, org.axonframework.eventsourcing.AggregateFactory<T> aggregateFactory, org.axonframework.messaging.annotation.ParameterResolverFactory parameterResolverFactory) Creates a repository instance for an Event Sourced aggregate that is created by the givenaggregateFactoryand sourced from giveneventStore. Parameters of the annotated methods are resolved using the givenparameterResolverFactory.- Type Parameters:
T- The type of aggregate managed by this repository- Parameters:
eventStore- The Event Store to retrieve and persist eventsaggregateFactory- The factory creating uninitialized instances of the AggregateparameterResolverFactory- The ParameterResolverFactory to resolve parameter values of annotated handler with- Returns:
- the repository that provides access to stored aggregates
-
createRepository
public <T> org.axonframework.modelling.command.Repository<T> createRepository(org.axonframework.eventsourcing.eventstore.EventStore eventStore, org.axonframework.eventsourcing.AggregateFactory<T> aggregateFactory, org.axonframework.messaging.annotation.ParameterResolverFactory parameterResolverFactory, org.axonframework.messaging.annotation.HandlerDefinition handlerDefinition, org.axonframework.modelling.command.RepositoryProvider repositoryProvider) Creates a repository instance for an Event Sourced aggregate that is created by the givenaggregateFactoryand sourced from giveneventStore. Parameters of the annotated methods are resolved using the givenparameterResolverFactory. The givenhandlerDefinitionis used to create handler instances.- Type Parameters:
T- The type of aggregate managed by this repository- Parameters:
eventStore- The Event Store to retrieve and persist eventsaggregateFactory- The factory creating uninitialized instances of the AggregateparameterResolverFactory- The ParameterResolverFactory to resolve parameter values of annotated handler withhandlerDefinition- The handler definition used to create concrete handlersrepositoryProvider- Provides specific for given aggregate types- Returns:
- the repository that provides access to stored aggregates
-
createRepository
public <T> org.axonframework.modelling.command.Repository<T> createRepository(org.axonframework.eventsourcing.eventstore.EventStore eventStore, org.axonframework.eventsourcing.AggregateFactory<T> aggregateFactory, org.axonframework.eventsourcing.SnapshotTriggerDefinition snapshotTriggerDefinition, org.axonframework.messaging.annotation.ParameterResolverFactory parameterResolverFactory) Creates a repository instance for an Event Sourced aggregate, sourced from giveneventStore, that is created by the givenaggregateFactory. Parameters of the annotated methods are resolved using the givenparameterResolverFactory.- Type Parameters:
T- The type of aggregate managed by this repository- Parameters:
eventStore- The Event Store to retrieve and persist eventsaggregateFactory- The factory creating uninitialized instances of the AggregatesnapshotTriggerDefinition- The trigger definition for snapshotsparameterResolverFactory- The ParameterResolverFactory to resolve parameter values of annotated handler with- Returns:
- the repository that provides access to stored aggregates
-
createRepository
public <T> org.axonframework.modelling.command.Repository<T> createRepository(org.axonframework.eventsourcing.eventstore.EventStore eventStore, org.axonframework.eventsourcing.AggregateFactory<T> aggregateFactory, org.axonframework.eventsourcing.SnapshotTriggerDefinition snapshotTriggerDefinition, org.axonframework.messaging.annotation.ParameterResolverFactory parameterResolverFactory, org.axonframework.messaging.annotation.HandlerDefinition handlerDefinition, org.axonframework.modelling.command.RepositoryProvider repositoryProvider) Creates a repository instance for an Event Sourced aggregate, sourced from giveneventStore, that is created by the givenaggregateFactory. Parameters of the annotated methods are resolved using the givenparameterResolverFactory. The givenhandlerDefinitionis used to create handler instances.- Type Parameters:
T- The type of aggregate managed by this repository- Parameters:
eventStore- The Event Store to retrieve and persist eventsaggregateFactory- The factory creating uninitialized instances of the AggregatesnapshotTriggerDefinition- The trigger definition for snapshotsparameterResolverFactory- The ParameterResolverFactory to resolve parameter values of annotated handler withhandlerDefinition- The handler definition used to create concrete handlersrepositoryProvider- Provides repositories for specific aggregate types- Returns:
- the repository that provides access to stored aggregates
-
subscribe
public org.axonframework.common.Registration subscribe(@Nonnull String commandName, @Nonnull org.axonframework.messaging.MessageHandler<? super org.axonframework.commandhandling.CommandMessage<?>> handler) - Specified by:
subscribein interfaceorg.axonframework.commandhandling.CommandBus
-
stop
public void stop()Shuts down the command bus. It no longer accepts new commands, and finishes processing commands that have already been published. This method will not shut down any executor that has been provided as part of the Builder process. -
registerDispatchInterceptor
@Nonnull public org.axonframework.common.Registration registerDispatchInterceptor(@Nonnull org.axonframework.messaging.MessageDispatchInterceptor<? super org.axonframework.commandhandling.CommandMessage<?>> dispatchInterceptor) - Specified by:
registerDispatchInterceptorin interfaceorg.axonframework.messaging.MessageDispatchInterceptorSupport<org.axonframework.commandhandling.CommandMessage<?>>
-
registerHandlerInterceptor
public org.axonframework.common.Registration registerHandlerInterceptor(@Nonnull org.axonframework.messaging.MessageHandlerInterceptor<? super org.axonframework.commandhandling.CommandMessage<?>> handlerInterceptor) - Specified by:
registerHandlerInterceptorin interfaceorg.axonframework.messaging.MessageHandlerInterceptorSupport<org.axonframework.commandhandling.CommandMessage<?>>
-