Skip to content

Latest commit

 

History

History
225 lines (178 loc) · 10.2 KB

technical.md

File metadata and controls

225 lines (178 loc) · 10.2 KB

TECHNICAL FEATURE SET
Domain Driven Design | Command Sourcing | CQRS | Functional Reactive Programing | Haskell

1. Definitions

GSD is a distributed application based on the following concepts :

  • Domain Driven Design (DDD)
    • Place the project's primary focus on the core domain and domain logic
    • Base complex designs on a model of the domain
  • CQRS
    • It stands for Command Query Responsibility Segregation.
    • It also known as the distributed version of DDD (and then DDDD as Distributed Domain Driven Design)
  • Command Sourcing ( Event Sourcing ++)
    • It's Event Sourcing where commands are also persisted
      • Capture all changes to an application state as a sequence of events
      • Capture all the commands sent to the system
    • Commands sent to the system are stored and consumed asynchronously as opposed to Event Sourcing
      • Command losses are reduced when the service is down
      • The data flow is pulled as opposed to pushed in Event Sourcing
      • Processes are embedded in a stream from A-Z
    • This command consumption produces and stores a single transaction :
data CommandHandlingResult =   CommandRejected   { reason ::  RejectionReason}
                             | CommandValidated  { events ::  [Event]}

data CommandTransaction = CommandTransaction {
                              commandId :: CommandId,
                              commandOffset :: Offset ,
                              aggregateId :: AggregateId ,
                              commandHandlingResult :: CommandHandlingResult }
  • Functional Reactive Programing
    • it's a programming paradigm for reactive programming (asynchronous dataflow programming) using the building blocks of functional programming (e.g. map, reduce, filter).
    • Streams and Logs (FIFO) are natural DDDD Architecture Building Blocks.
  • Micro-service Architecture
    • Services are small in size
    • Messaging enabled
    • Bounded by contexts
    • Autonomously developed
    • Independently deployable
    • Decentralized
    • Built and released with automated processes.

All these concepts are building blocks for implementing the Kahn process networks (KPNs, or process networks). They are a concurrent model of computation which can be also considered as a Pattern / Architecture for distributed systems.

Related Articles :

2. Microservices

2.1 Overview

The GSD application is made of 6 distributed services :

  • cli - Command Line Interface to pilot the system.

    • Send commands to the system
    • Read eventually up-to-date projections from the Read service
    • Read eventually up-to-date projections from a Monitoring service
  • command-sourcer

    • Receive commands
    • Dispatch and Persist these commands
  • command-consumer - Command Consumption Orchestration (CQRS Sagas Terminology)

    • Listen on commands arriving on the command stream for each aggregates
    • Re-build the write model from the previous command transactions
    • Perform the transactions on each command persisted (handleCommand), a command can be :
      • Accepted (contains events)
      • Rejected (contains the reason of rejection)
    • Persist these command transactions
  • gsd-read

    • Read from the command transaction streams
    • Project a model optimised for the read
    • Serve that model to the cli service
  • gsd-monitoring

    • Read the command transaction and the command streams
    • Project a model optimised for monitoring the system
    • Serve that model to the cli service
  • eventstore-service - embedded into a docker container

2.2 Resiliency and high availability

Each service is safe and can only be terminated by

  • a SIG-INT (releasing resources properly)
  • a SIG-KILL

Each service has a built-in bootstrap health-check mechanism and come back in that mechanism whenever it becomes unhealthy.

  • Regarding the GSD application
    • cli is healthy, when the following dependencies are healthy :

      • command-sourcer
      • command-consumer
      • gsd-read
      • gsd-monitoring
    • command-sourcer is healthy, when eventstore-service is healthy

    • command-consumer is healthy, when eventstore-service is healthy

    • gsd-read is healthy, when eventstore-service is healthy

    • gsd-monitoring is healthy, when eventstore-service is healthy

2.3 Health-Check Mechanism Demo

3. Bounded Contexts

Eventuria is the name of the company hosting the project (root package). By flicking through the codebase under Eventuria, you'll see the following packages :


  • Adapters : Contains wrappers, tweaks on external libraries

  • Commons : Tiny Bounded Contexts

  • GSD : GSD Application Bounded Context, you'll find the 4 services cited previously in that doc

    • CLI : gsd-cli implementation
    • Write :
      • gsd-command-consumer
      • gsd-command-sourcer
    • Read : gsd-read implementation
    • Monitoring : gsd-monitoring implementation
  • Libraries

All these packages will eventually be in their own git repository as they get more mature.




4. Streams and Logs

  • command-sourcer
    • Handle an Aggregate index (AggregateId Stream)
    • Serve Command Requests - Feed the Command Streams (1 Command Stream per Aggregate)
  • command-consumer - Per aggregate :
    • Subscribe to Commands
    • Project a write Model
    • Handle each command by providing a Command Transaction :
      • Accepted (contains events)
      • Rejected (contains the reason of rejection)
    • Feed the Command Transaction Stream
  • gsd-read
    • Read a Command Transaction Stream
    • Project from command transaction to a specific read model
    • Serve clients with this model
  • gsd-monitoring
    • Read a Command Transaction Stream
    • Project from command transaction to a specific read model
    • Serve clients with this model

5. Emergent CQRS framework

One of the intents when starting this project was to formalize the CQRS pattern and get eventually a Framework out of a concrete application like GSD. This is what the package Eventuria.CQRS will eventually become... To use this framework, the GSD application provides the following :

  • a specific WriteModel (GSD WriteModel)
  • a map between the application and CQRS events (GSD Commands)
  • a map between the application and CQRS commands (GSD Events)
  • a Command Consumption Orchestration (GSD Orchestration)
  • 2 functions (ProjectWriteModel and HandleCommand)
    data CommandHandlingResult =   CommandRejected   { reason ::  RejectionReason}
                                 | CommandValidated  { events ::  [Event]}
    
    type ProjectWriteModel writeModel = Maybe writeModel ->
                                        CommandHandlingResult ->
                                        Maybe writeModel
    
    type HandleCommand writeModel = Maybe writeModel ->
                                    (Persisted Command) ->
                                    IO (CommandHandlingResult)
  • GSD ProjectWriteModel
  • GSD HandleCommand