making workflow implementation easy with cqrs

16
Andrea Saltarello @andysal74 CEO @ Managed Designs http://www.manageddesigns.it Making workflow implementation easy with CQRS

Upload: britt-king

Post on 16-Apr-2017

506 views

Category:

Software


3 download

TRANSCRIPT

Page 1: Making workflow implementation easy with CQRS

Andrea Saltarello @andysal74

CEO @ Managed Designshttp://www.manageddesigns.it

Making workflow implementation easy with

CQRS

Page 2: Making workflow implementation easy with CQRS

Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS

A workflow consists of an orchestrated and repeatable pattern of business activity enabled by the systematic organization of resources into processes that transform materials, provide services, or process information.[1]

It can be depicted as a sequence of operations, declared as work of a person or group,[2] an organization of staff, or one or more simple or complex mechanisms.

[Wikipedia]

Page 3: Making workflow implementation easy with CQRS

Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS

A simple workflow: Invoicing

Issue

Payment

Ship

NotifyExpires IsPaid CollectNo

Page 4: Making workflow implementation easy with CQRS

Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS

A simple workflow: Invoicing

Either a user or a scheduler fires code such as:

public void NotifyCustomersAboutPertainingExpiredInvoices()

{

var expiredInvoices = from i in db.OutgoingInvoices

where SomeClausesPointingToStillUnpaidExpiredInvoicesselect i;

foreach(var invoice in expiredInvoices)

{

NotifyExpiredInvoiceToCustomer(invoice);

}

}

Page 5: Making workflow implementation easy with CQRS

Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS

Enter CQRS

Presentation layer

Application layer

Infrastructure layer

Domain Model

Domain layer

Presentation layer

Infrastructure layer

CQRS

Queries

Data access

Commands

Application+

Domain

Page 6: Making workflow implementation easy with CQRS

Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS

Why CQRS?

We faced a lot of complexity in modelingWe thought it was inherent domain complexityLong story short: a single model caring about all aspects of the domain is hard. Enter CQS

Command/Query Separation (cit. Bertrand Meyer – 1980s)

Query> Returns data> Doesn’t alter state

Command> Alter state > Doesn’t return data

Page 7: Making workflow implementation easy with CQRS

Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS

CQRS in action

As a business unit manager, I want to notify customers about expired invoices

Database.OutgoingInvoices..PerBusinessUnit(businessUnitId).ExpiredOnly().Select(i => new {InvoiceNumber = i.Number, CustomerId =

i.Customer.Id}).AsParallel().ForAll(i => NotifyCustomer(i.InvoiceNumber, i.CustomerId));

Page 8: Making workflow implementation easy with CQRS

Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS

The result

Pros:• Easy to read• Close to Ubiquitous Language

Cons:• Synchronous (lower scalability)• Either a scheduling engine or human interaction is

required

Page 9: Making workflow implementation easy with CQRS

Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS

Commands: a different strategy

1. Application sends a command to the system2. Commands are dispatched to workflow managers

(a.k.a. Sagas) which will execute them and then state success/failure accordingly

3. Responses are notified to interested subscribers (a.k.a. handlers) such as Denormalizers, which will (eventually) update the read model’s database

Note: command/responses dispatch will be managed by a Mediator

Page 10: Making workflow implementation easy with CQRS

Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS

CQRS in action, part 2

As a business unit manager, I want to notify customers about expired invoicesDatabase

.OutgoingInvoices.

.PerBusinessUnit(businessUnitId)

.ExpiredOnly()

.Select(i => new {InvoiceNumber = i.Number, CustomerId = i.Customer.Id})

.AsParallel()

.ForAll(i => mediator.Send(new NotifyPaymentDueCommand(i.InvoiceNumber, i.CustomerId)));

Page 11: Making workflow implementation easy with CQRS

Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS

The result, part 2

Pros:• Easy to read• Close to Ubiquitous Language• Asynchronous

Cons:• Either a scheduling engine or human interaction is

required

Page 12: Making workflow implementation easy with CQRS

Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS

Queues or buses? That is the question (semi cit. )

Although both categories are viable options and support common features (e.g.: message durability), a bus is generally preferable due to advanced capabilities (e.g.: message scheduling)

Mediator, who art thou?

Page 13: Making workflow implementation easy with CQRS

Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS

Sagas 1-2-3

In a messaging system, a saga orchestrate a set of messages. The main benefit of using a saga is that it allows us to manage the interaction in a stateful manner (easy to think and reason about) while actually working in a distributed and asynchronous environment.

[Ayende]

Though Saga are not proper workflow/process manager, they are effective at pretending to be

Page 14: Making workflow implementation easy with CQRS

Sagas in action

Page 15: Making workflow implementation easy with CQRS

Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS

More resources: •“Microsoft .NET: Architecting Applications for the Enterprise” by Andrea Saltarello and Dino Esposito, Microsoft Press (2014)•Merp (http://naa4e.codeplex.com)

Links

Page 16: Making workflow implementation easy with CQRS

Thank you