DDD Exchange London 2018: Know the flow! Events, commands and long-running services.

DDD Exchange London 2018: Know the flow! Events, commands and long-running services.

@martinschimak => April 26th, 2018 => London => DDD Exchange

2999fab21d182294fad0b2cc590fd54d?s=128

Martin Schimak

April 26, 2018
Tweet

Transcript

  1. Events, commands and long-running services @martinschimak -> April 26th, 2018

    -> London -> DDD eXchange Know the flow!
  2. Read Model Domain Event Aggregate Policy Command External System UI

    Command Invoked on raises raises Invoked on projected onto listened to by triggers triggers Inspired by the picture that explains (almost) everything :-) * *) © The ingenious Alberto Brandolini
  3. Domain events are more prominently discussed than commands

  4. The cool thing about domain events? They are facts. It

    already happened. Events let us look into the past. Payment received
  5. Events create trust in a world of eventual consistency. Strong

    consistency Payment received Payment
  6. We are dedicated to events. For good reasons. CQRS! Order

    summary Payment received Payment UI raises projected onto
  7. Need more good reasons? Event Sourcing! Payment received Payment Payment

    received Payment received Payment received Payment received
  8. Events are easy to grasp. Event Storming! Goods shipped Order

    placed Goods fetched Payment received „We need to achieve some facts to create value for customers!“ Events are a concept easy to grasp for everybody in the room.
  9. Events are relaxed! Just feel fine. Don‘t want to achieve

    anything.
  10. Events help to decouple services. Order summary Payment received Payment

    UI raises projected onto Payment Service Order Service
  11. Events help with cross-cutting concerns Payment received Customer Notification Policy

    Inform customer listened to by triggers Payment Service Notification Service
  12. Let‘s just rely on events in between services!

  13. Relying on events only leads to suboptimal coupling Order placed

    Payment Service Payment received Inventory Service Goods fetched Shipment Service Goods shipped
  14. Shipment Service Autonomous services can be deployed independently. To change

    the order of two services, we touch 4 sticky notes… but wait, all three services! Goods shipped Order placed Inventory Service Payment Service Payment received Goods fetched
  15. Who made the decision to use events only?

  16. Our policies decide to act on facts – with commands

    Domain Event Policy Command listened to by triggers
  17. Who owns the policy in a pure event choreography? Payment

    received Start Fetching Policy Fetch goods listened to by triggers Payment Service Inventory Service
  18. Who owns the policy in a commanding approach? Payment received

    Start Fetching Policy Fetch goods listened to by triggers Payment Service Inventory Service
  19. Neither of both truly „owns“ that policy? Payment received Fetch

    goods listened to by triggers Payment Service Inventory Service Start Fetching Policy
  20. Extracting the policy into a mediator service Payment received Start

    Fetching Policy Fetch goods listened to by triggers Payment Service Inventory Service Order Service
  21. The order as the companies core business Place order Order

    placed Request payment Order Service Payment received Fetch goods Goods fetched Ship goods Goods shipped “When the order is placed…” “When the payment is received…” “When the goods are fetched…” “Then we are done!” Mark order as fulfilled Order fulfilled Payment Service Inventory Service Shipment Service
  22. Double check: what happens when we charge later? Place order

    Order placed Request payment Order Service Payment received Fetch goods Goods fetched Ship goods Goods shipped “When the order is placed…” “When the payment is received…” “When the goods are fetched…” “Then we are done!” Mark order as fulfilled Order fulfilled Payment Service Inventory Service Shipment Service
  23. Events decrease coupling? Often! Pro Tip: some commands may help,

    too!-)
  24. Trade offs! Events and commands in between services. Payment received

    Policy Fetch goods listened to by triggers Payment Service Inventory Service Order Service
  25. Commands are intent Nothing really happened so far. It‘s in

    the future. Place order
  26. „Place order“ seen as an atomic transaction Order Invoked on

    Order Placed raises Place order
  27. When hugging a tree, it is difficult to see the

    wood!
  28. „Place order“ seen as a long-running service Order fulfilled Order

    canceled Payment received Goods shipped Place order Order placed
  29. Atomic vs. composite command execution Place order Order placed Typically

    we see a „command“ as the intent to change a write model... … but the customer‘s or service clients intent is often targeted at a more valuable business result, which needs many steps to be achieved. Place order Order fulfilled Atomic, trans- actional execution Composite, long- running execution
  30. Is that command executable as an atomic step? Request payment

  31. Let‘s do some event storming… Request payment Payment received Payment

    requested Charge credit card Depending on account balance Withdraw amount from account Amount Withdrawn Credit card charged Credit card failed Update credit card details Account details Credit card details updated Whenever card details are updated After two weeks Depending on the amount Amount credited Mark payment received Mark payment canceled Payment canceled Credit amount to account Whenever payment is canceled Mark payment received Payment received
  32. Credit card gateway Accounting system Payment Request payment Charge credit

    card Credit card charged Our result seen as a collection of commands Withdraw amount from account Amount Withdrawn Amount credited Credit amount to account Mark payment Payment received Payment canceled Payment requested Credit card failed Update credit card details Credit card details updated Update credit card details Credit card details updated Credit card failed
  33. What happens if we expose those atomic commands? Charge credit

    card Credit card charged Credit card failed Payment Service Retry with new credit card details Who owns the policy?
  34. Payment seen as a long-running service Request payment Payment received

    Payment Service
  35. What happens if we expose troubles with some steps? Request

    payment Payment received Credit card failed Payment Service Retry with new credit card details Who owns the policy?
  36. „Delegating our problems to our clients forces them to deal

    with the mitigation. They become god services.“ Credit card failed Retry with new credit card details Charge credit card listened to by triggers Payment Service Order Service
  37. Smart endpoints (with dumb pipes) … … don‘t delegate problems

    they better deal with themselves!
  38. A long-running smart endpoint … Request payment Payment received Payment

    canceled 1) creates value – serving a result its client is really interested in 2) assumes responsibility – instead of delegating troubles with internal steps to its client 3) may go asynchronous – if needed for composite execution Payment Service
  39. Long-running services help to protect bounded contexts Order service Payment

    service Request payment Payment canceled Payment received
  40. How to get productive with long-running services?

  41. Heavily inspired by Mathias Verraes! Thank you! Considering the CQRS

    pattern Read Model Projections Write Model Invariant Protection Client/Human Interaction Query Command Domain Event
  42. Write Model Read Model Query Domain Event Command Observe Act

    Decide
  43. How do we implement the payment service? Request payment Payment

    received Payment requested Charge credit card Depending on account balance Withdraw amount from account Amount Withdrawn Credit card charged Credit card failed Update credit card details Account details Credit card details updated Whenever card details are updated After two weeks Depending on the amount Amount credited Mark payment received Mark payment canceled Payment canceled Credit amount to account Whenever payment is canceled Mark payment received Payment received
  44. Write Model Read Model Query Domain Event Command Decide Observe

    Act
  45. Write Model Read Model Process Model Domain Event Command Query

    Policy plexiti de|coding domain language Observe Act Decide
  46. Process Model Write Model Domain Event Command Process Manager Read

    Model Policy Observe Decide
  47. How to get productive with process managers? Handling of time

    & timeouts Retries Compensation Message-Driven
  48. e.g. with Axon Messaging & Saga Management @Saga class Payment

    { private var paymentAmount = 0F @StartSaga @SagaEventHandler(associationProperty = "paymentId") fun on(event: PaymentRequested) { // save state, evaluate policy, create command } } Private, persistent process state Managed event correlation Process policy and construct command is cool, but Java works as well! :-)
  49. What about business process execution engines? Monitoring & Operations Handling

    of time & timeouts Versatile Retries Explicitness & Visibility for Flows Versioning for Flows and Policies Transparent Compensation Parallelisation and synchronisation
  50. Payment service as a BPMN model

  51. Payment service as a BPMN model

  52. Make the implicit explicit!

  53. Explicit and simple timer management

  54. Transparent and simple compensation handling

  55. Transparent business process monitoring and operations 897 2 Temporarily failing

    commands Executions currently waiting for events
  56. But are business process engines usable in a modern architecture?

  57. Credit amount back to account Withdraw amount from cust. account

    Charge amount by credit card I want that kind of „reactive“ business process execution Charge amount by credit card Credit amount back to account Update credit card details Check customer account balance Payment requested Depending on account balance Charge credit card Withdraw amount from account Credit card charged Whenever credit card is charged Mark payment received Payment received Amount Withdrawn Depending on the amount Mark payment received Payment received Mark paym. partly covered Payment partly covered Whenever payment p. covered Charge credit card Credit card failed Whenever credit card failed Update credit card details Credit card details updated Whenever card details are updated Charge credit card After two weeks Mark payment canceled Payment canceled Whenever payment is canceled Credit amount to account Amount credited Every two days Remind customer Customer reminded Withdraw amount from cust. account
  58. I want autonomous services - respecting boundaries Order service Payment

    service Request payment Payment received Payment canceled Request payment
  59. I want transparent commanding - atomic or composite Order service

    Request payment
  60. With this I get flexible and local technology decisions Order

    service Payment service Request payment Payment received Payment canceled Request payment Your local implementation reacting to events and commands
  61. Is it feasible? Sure it is.

  62. e.g. with Camunda an open source process engine Domain Entities,

    value objects, domain events etc… + atomic command behaviour + composite, long-running command behaviour Application Infrastructure Process Engine
  63. Reality Check. Order fulfillment process of a very large online

    retailer.
  64. BDD style business process specification

  65. Charge amount by credit card BDD style business process test

    - and visual feedback Charge amount by credit card Update credit card details Check customer account balance
  66. An emerging ecosystem of saga, state & process managers CADENCE

    Baker
  67. I like graphical models to know and discuss „what is“…

  68. … and I like sticky notes to discuss „what should

    be“! Request payment Payment received Payment requested Charge credit card Depending on account balance Withdraw amount from account Amount Withdrawn Credit card charged Credit card failed Update credit card details Account details Credit card details updated Whenever card details are updated After two weeks Depending on the amount Amount credited Mark payment received Mark payment canceled Payment canceled Credit amount to account Whenever payment is canceled Mark payment received Payment received
  69. Need code? Reactive processes with Axon & Camunda. Order service

    Payment service Request payment Payment received Payment canceled Request payment plexiti de|coding domain language https://github.com/plexiti/axon-camunda-poc @martinschimak