github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/design/projectors/README.md (about)

     1  ### Abstract
     2  
     3  Projectors design
     4  
     5  ### Terms
     6  - Projector (Проектор)
     7    - Common: Describes the way how events are applied to projection
     8    - Heeus: Provides a function which generates *Intents* based on the information from *Event* and current *State*
     9  - State (состояние)
    10    - Provides reading from Storages
    11  - Intents (намерения)
    12    - A declaration of Create or Update modifications in Storage that will be applied in the result of projector execution
    13    - Modifications declared by Intents are not applied before the extension function ends
    14  - Storage
    15    - Provides I/O access for extensions (to e.g. Views, Records, WLog, HTTP, Mailer, etc)
    16  - Projection (Проекция, Read Model, Query Model)
    17    - Common: Projection is about deriving current state from the stream of events. [(c)](https://abdullin.com/post/event-sourcing-projections/)
    18      - Состояние, вычисленное на основе анализа потока событий
    19    - Common: "Projection is a left-fold over the sequence of events" [(c)](https://domaincentric.net/blog/event-sourcing-projections) [Greg Young](https://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf)
    20      - [Левоассоциативная свертка](https://ru.wikipedia.org/wiki/%D0%A1%D0%B2%D1%91%D1%80%D1%82%D0%BA%D0%B0_%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0) списка
    21    - In terms of Heeus: cumulative result of *all applied intents* of the projector.
    22    - Example: one projector may generate one or more Views. A *combination of these views* is a projection
    23  - Internal Projection
    24    - A projection which is kept in the AppStorage;
    25    - WLog, Table, View;
    26    - Read Model is the set of internal projectors;
    27  - External Projection
    28    - A projection which is kept outside of the AppStorage;
    29  - Actualizer (Feeder, Актуализатор, Кормилец)
    30    - A component which *feeds Projector* with events from PLog
    31    - Applies intents to storages
    32  - Async Actualizer
    33    - Feeds projectors asynchronously with Command Processor: no guarantee that projection is updated before CP finishes handling the event.
    34    - Each Projector fed by it's own Async Actualizer
    35  - Sync Actualizer
    36    - Feeds projectors within Command Processor => projection is updated before event handling is finished
    37    - This type of actualizer will be soon eliminated
    38  - Actualizer Factory (Фабрика Актуализатора)
    39    - A function which creates actualizer instance for the app partition for certain projector
    40  - Actualizer Offset (Смещение проектора)
    41    - The number of the last PLog event which is guaranteed fed to the projector and applied to storages
    42  
    43  ### Concepts
    44  
    45  ```mermaid
    46  erDiagram
    47  AppSchema ||--o{ ViewSpec: declares
    48  ViewSpec ||--|| ViewProjectorFactory: "used to build"
    49  CustomProjectorSpec {
    50      string Name
    51      bool NonBuffered
    52      func Func
    53  }
    54  AppSchema ||--o{ CustomProjectorSpec: declares
    55  CustomProjectorSpec ||--|| CustomProjectorFactory: "used to build"
    56  BuiltInProjectorFactory ||--|| ProjectorFactory: "is a"
    57  CustomProjectorFactory ||--|| ProjectorFactory: "is a"
    58  ViewProjectorFactory ||--|| ProjectorFactory: "is a"
    59  ActualizerFactory ||--|{ Actualizer: "creates per AppPartition"
    60  ActualizerFactory ||--|{ Projector: "creates per AppPartition"
    61  Projector ||--|| Actualizer: "fed by"
    62  Projector ||--o{ Intent: "declares Storages modification"
    63  Projector ||--|| State: "reads from Storages using"
    64  Projector ||--|| Event: "gets as a param"
    65  State ||--|| Actualizer: "provided by"
    66  Event ||--|| Actualizer: "provided by"
    67  Intent }o--|| Actualizer: "applied by"
    68  Actualizer }|--|| PLog: "reads from"
    69  Actualizer }|--|| CommandProcessor: "notified by"
    70  ProjectorFactory }|--|| ActualizerFactory: "used by"
    71  State ||--|{ Storage: "reads from"
    72  Actualizer ||--|{ Storage: "applies intents to"
    73  ```
    74  ### Principles
    75  - As we don't use "Prepare" function, Projector is *not an IOperator anymore*, but a function with three arguments: *workpiece*, *State* and *Intents*
    76  - Async Actualizers (AA):
    77    - State 1:
    78      - Changes to storage applied immediately after every event
    79    - State 2.0:
    80      - AA Buffers changes to storages and applies them by timer or when the buffer is full
    81      - there is a possibility to set projection as "non%-buffered". In this case changes applied after every event
    82  - Sync Actualizers (SA):
    83    - State 1:
    84      - SA handle single event in a Fork. Every SA applies it's changes independently
    85    - State 2.0:
    86      - SA handle single event in a Fork. Changes to storages applied when all projectors for the event are handled with no errors
    87  
    88  ### Detailed design
    89  
    90  - [Async Actualizers](./async-act.md)
    91  - [Sync Actualizers](./sync-act.md)
    92  - [Idempotency](./idempotency.md)
    93  
    94  ### References
    95  - [State 2.0](./README.md)
    96  - [Extension Engines / WASM ABI](./ext-engines.md)
    97  - [Lazy Projections](./lazy-projections.md)
    98