The CommandService is the interface to schedule commands in Sequent. To execute a Command pass it to the CommandService. For instance from a Sinatra controller:
class Users < Sinatra::Base post '/create' do Sequent.command_service.execute_commands CreateUser.new( aggregate_id: Sequent.new_uuid, name: params[:name] ) end end
By default all Commands passed into the CommandService are executed in a single transaction. When something fails and an Exception is raised and the transaction is rolled back.
Order of Command execution
Commands are executed in the order in which they are scheduled. For instance if you schedule new Commands in a Workflow running in the foreground it will be added to the queue of Commands. For instance:
# command c1 results in event e1 on c1 do apply e1 end # workflow: event e1 results in new command c3 on e1 do execute_commands(c3) end # main execute_commands(c1, c2)
The order in which Commands are “executed” is:
c1 results in Event
e1 that will result in
the execution of Command
c3. However since Command
c2 is scheduled
first it will also be executed first.
Order of Event publishing
Sequent .command_service .execute_commands(MarkInvoicesPaid.new(...)) class InvoiceCommandHandler < Sequent::CommandHandler on MarkInvoicesPaid do invoice_1 = repository.load_aggregate(c1.aggregate_id) invoice_2 = repository.load_aggregate(c1.invoice_2_id) invoice_2.mark_paid # applies event InvoiceMarkPaid invoice_1.mark_paid # applies event InvoiceMarkPaid invoice_2.finalize # applies event InvoiceFinalized invoice_1.finalize # applies event InvoiceFinalized end end
Given the above example the order in which the events are published is:
invoice_1 is loaded first from the AggregateRepository all it’s
Events (ordered as they occurred) as a result from the Command
MarkInvoicesPaid will be published first. Then all events from
invoice_2 will be published.