Skip to content

input-output-hk/caryatid

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Caryatid Event-based Modular Framework

This is the Caryatid event-based, modular framework for Rust. It allows creation of microservices comprising one or more modules which communicate over publish-subscribe, with an optional request/response layer on top.

graph TB
  subgraph Microservice A
    direction TB
    M1(Module 1)
    M2(Module 2)
    M3(Module 3)
    Config1[Configuration]
    Tracing1[Tracing]
    Correlation1[Request/Response Correlator]
    Routing1[Message Routing]
    InMemory1[In-memory Bus]
    RabbitMQ1[RabbitMQ Bus]


    M1 <--> Correlation1
    M2 --> Correlation1
    M3 <--> Correlation1
    Correlation1 <--> Routing1
    Routing1 <--> InMemory1
    Routing1 <--> RabbitMQ1
    Config1 ~~~ Tracing1
  end

  subgraph Microservice B
    direction TB
    M4(Module 4)
    Correlation2[Request/Response Correlator]
    Routing2[Message Routing]
    InMemory2[In-memory Bus]
    RabbitMQ2[RabbitMQ Bus]
    Config2[Configuration]
    Tracing2[Tracing]

    M4 <--> Correlation2
    Correlation2 <--> Routing2
    Routing2 <--> InMemory2
    Routing2 <--> RabbitMQ2
    Config2 ~~~ Tracing2
  end

  RabbitMQ([RabbitMQ Message Bus])
  style RabbitMQ fill:#eff
  RabbitMQ1 <--> RabbitMQ
  RabbitMQ2 <--> RabbitMQ
Loading

Modules in the same microservice can communicate over an internal, zero-copy, in-memory bus. Modules in different microservices can communicate over external message buses (only RabbitMQ is implemented so far). The module itself doesn't need to know which is in use, because there is a routing layer to direct particular topics to different buses.

Messages are generic, and can either be a universal format such as JSON, or for better performance, an enum of application-specific Rust types. In either case, they are automatically serialised to CBOR when passed externally.

Currently - because tokio doesn't play well with dynamic loading, and complexities around ABI - microservice processes are built with a simple main.rs which explicitly loads the modules required. The eventual aim is to support dynamic loading at runtime into a standard process.

Building and running

Caryatid is a standard Rust workspace, so you can build it all with

$ cargo build

at the root directory.

Individual examples can be built and run from their directories in examples:

$ cd examples/simple
$ cargo run
... builds ...
2024-11-19T13:01:43.547798Z  INFO simple_example: Caryatid modular framework - simple example process
... runs ...

Code structure

The code is structured as follows:

About

Caryatid Event-based Modular Framework

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages