Contact Us

If you still have questions or prefer to get help directly from an agent, please submit a request.
We’ll get back to you as soon as possible.

Please fill out the contact form below and we will reply as soon as possible.

  • Contact Us
  • Home
  • System Architecture

Process Manager

Written by Oleksandr Sydorenko

Updated at May 5th, 2025

Contact Us

If you still have questions or prefer to get help directly from an agent, please submit a request.
We’ll get back to you as soon as possible.

Please fill out the contact form below and we will reply as soon as possible.

  • System Architecture
+ More

The saga pattern manages simple, linear flow. Strictly speaking, a saga matches events to the corresponding commands. In the examples we used to demonstrate saga implementations, we actually implemented simple matching of events to commands:

• CampaignActivated event to PublishingService.SubmitAdvertisement

command

• PublishingConfirmed event to Campaign.TrackConfirmation command

• PublishingRejected event to Campaign.TrackRejection command

The process manager pattern, shown in Figure 9-14, is intended to implement a business-logic-based process. It is defined as a central processing unit that maintains the state of the sequence and determines the next processing steps.2


Figure 9-14. Process manager

As a simple rule of thumb, if a saga contains if-else statements to choose the correct course of action, it is probably a process manager.

Another difference between a process manager and a saga is that a saga is instantiated implicitly when a particular event is observed, as in CampaignActivated in the pre‐ ceding examples. A process manager, on the other hand, cannot be bound to a single source event. Instead, it’s a coherent business process consisting of multiple steps. Hence, a process manager has to be instantiated explicitly. Consider the following example:

Booking a business trip starts with the routing algorithm choosing the most cost- effective flight route and asking the employee to approve it. In case the employee pre‐ fers a different route, their direct manager needs to approve it. After the flight is booked, one of the preapproved hotels has to be booked for the appropriate dates. If no hotels are available, the flight tickets have to be canceled.

In this example, there is no central entity to trigger the trip booking process. The trip booking is the process and it has to be implemented as a process manager (see Figure 9-15).


2 Hohpe, G., & Woolf, B. (2003). Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions. Boston: Addison-Wesley.

Figure 9-15. Trip booking process manager

From an implementation perspective, process managers are often implemented as aggregates, either state based or event sourced. For example:

public class BookingProcessManager

{

private readonly IList<IDomainEvent> _events;

private BookingId _id;

private Destination _destination; private TripDefinition _parameters; private EmployeeId _traveler; private Route _route;

private IList<Route> _rejectedRoutes;

private IRoutingService _routing;

...

public void Initialize(Destination destination,

TripDefinition parameters, EmployeeId traveler)

{

_destination = destination;

_parameters = parameters;

_traveler = traveler;

_route = _routing.Calculate(destination, parameters);

var routeGenerated = new RouteGeneratedEvent( BookingId: _id,

Route: _route);

var commandIssuedEvent = new CommandIssuedEvent(

command: new RequestEmployeeApproval(_traveler, _route)

);

_events.Append(routeGenerated);

_events.Append(commandIssuedEvent);

}

public void Process(RouteConfirmed confirmed)

{

var commandIssuedEvent = new CommandIssuedEvent( command: new BookFlights(_route, _parameters)

);

_events.Append(confirmed);

_events.Append(commandIssuedEvent);

}

public void Process(RouteRejected rejected)

{

var commandIssuedEvent = new CommandIssuedEvent( command: new RequestRerouting(_traveler, _route)

);

_events.Append(rejected);

_events.Append(commandIssuedEvent);

}

public void Process(ReroutingConfirmed confirmed)

{

_rejectedRoutes.Append(route);

_route = _routing.CalculateAltRoute(destination,

parameters, rejectedRoutes);

var routeGenerated = new RouteGeneratedEvent( BookingId: _id,

Route: _route);

var commandIssuedEvent = new CommandIssuedEvent(

command: new RequestEmployeeApproval(_traveler, _route)

);

_events.Append(confirmed);

_events.Append(routeGenerated);

_events.Append(commandIssuedEvent);

}

public void Process(FlightBooked booked)

{

var commandIssuedEvent = new CommandIssuedEvent( command: new BookHotel(_destination, _parameters)

);

_events.Append(booked);

_events.Append(commandIssuedEvent);

}

...

}

In this example, the process manager has its explicit ID and persistent state, describ‐ ing the trip that has to be booked. As in the earlier example of a saga pattern, the pro‐ cess manager subscribes to events that control the workflow (RouteConfirmed, RouteRejected, ReroutingConfirmed, etc.), and it instantiates events of type Command Issued Event that will be processed by an outbox relay to execute the actual commands.

Was this article helpful?

Yes
No
Give feedback about this article

Related Articles

  • Discovering Domain Knowledge
  • Business Problems
  • Knowledge Discovery
  • Communication
  • What Is a Ubiquitous Language?

info@smartphonekey.com

  • Home
  • How It Works
  • Features
  • Residents and Tenants
  • Property Managers
  • Airbnb Hosts
  • Products
  • Blog
  • Guide for Usage and Installation
  • Our Team
  • Contact Us
  • Privacy Policy
  • Terms of Service
  • Facebook
  • Instagram
  • LinkedIn
© 2025, Smartphonekey.com Powered by Shopify
Expand