Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 47 additions & 100 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,103 +143,50 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

---

## Roadmap

There are a few things that must be done before v0.1.0:

### Next

- [x] Do some renaming around:
- rename MembersStorage to MembershipStorage (rio_rs::cluster::storage)
- ObjectPlacement to ObjectPlacementItem (rio_rs::object_placement)
- ObjectPlacementProvider to ObjectPlacement (rio_rs::object_placement)
- [x] Bypass clustering for self messages
- Not an issue. You can do just `Self::handle(my_other_message)?`
- [x] Bypass networking for local messages
- Already handled by `rio_rs::service::Service::call`
- [x] Tracing
- [ ] MDNs
- [ ] Client bindings for other languages
- [ ] Remove the need for two types of concurrent hashmap (papaya and dashmap)
- [ ] Guest languages support - Currently possible with WASM + tons of boiler-plate
- [ ] Create server from config
- [ ] Move all the client to user tower
- [ ] Remove the need to pass the StateSaver to `ObjectStateManager::save_state`
- Might not be feasible, there are a few workarounds for testing that I might write some examples
and call it a day
- [ ] Include registry configuration in Server builder
- [ ] Create a getting started tutorial
- Cargo init
- Add deps (rio-rs, tokio, async_trait, serde, sqlx - optional)
- Write a server
- Write a client
- Add service and messages
- Cargo run --bin server
- Cargo run --bin client
- Life cycle
- Life cycle depends on app_data(StateLoader + StateSaver)
- Cargo test?
- [ ] MySQL support for sql backends
- [ ] Add pgsql jsonb support
- [ ] Client/server keep alive
- [ ] Topology - nodes work with different sets of service types
- [ ] Placement strategies - sets where to place objects
- [ ] Supervision
- [ ] Ephemeral objects (aka regular - local - actors)
- [ ] Remove magic numbers
- [ ] Object TTL
- [ ] Code of conduct
- [ ] Metrics
- [ ] Deny allocations based on system resources
- [ ] Dockerized examples
- [ ] Reduce static lifetimes
- Might not be feasible


### Version 0.2.3

- [x] Improve error message for ManagedState macro when the struct doesn't implement ServiceObject
- [x] Improve error message for ManagedState when the storage is not in the context
- [x] Improve error message for when the services are not added to the registry (server)
- [x] Client doesn't need to have a access to the cluster backend if we implement an HTTP API

### Version 0.2.0

- [x] Support 'typed' message/response on client (TODO define what this means)
- [x] Ability to hook up own custom errors on message handlers
- [x] Allow `ServiceObject` trait without state persistence
- [x] Add more extensive tests to client/server integration
- [x] Increase public API test coverage
- [x] Add all SQL storage behind a feature flag (sqlite, mysql, pgsql, etc)
- [x] Matrix test with different backends
- [x] Replace prints with logging

### Version 0.1.0

- [x] Naive server/client protocol
- [x] Basic cluster support
- [x] Basic placement support
- [x] Object self shutdown
- [x] Naive object persistence
- [x] Public API renaming
- [x] Reduce Boxed objects
- [x] Create a Server builder
- [x] Remove need to use `add_static_fn(FromId::from_id)` -> Removed in favour of `Registry::add_type`
- [x] Support service background task
- [x] Pub/sub
- [x] Examples covering most use cases
- [x] Background async task on a service
- [x] Background blocking task on a service (_see_ [black-jack](./examples/black-jack))
- [x] Pub/sub (_see_ [black-jack](./examples/black-jack))
- [x] Re-organize workspace
- [x] Support ephemeral port
- [x] Remove the need for an `Option<T>` value for `managed_state` attributes (as long as it has a 'Default')
- [x] `ServiceObject::send` shouldn't need a type for the member storage
- [x] Handle panics on messages handling
- [x] Error and panic handling on life cycle hooks (probably kill the object)
- [x] Create a test or example to show re-allocation when servers dies
- [x] Sqlite support for sql backends
- [x] PostgreSQL support for sql backends
- [x] Redis support for members storage
- [x] Redis support for state backend (loader and saver)
- [x] Redis support for object placement
## Features

Here are some of the features that are fully implemented:

### Clustering

Clustering is divided in two parts: `Membership Protocol` and `Membership Storage`.

The Membership Storage is responsible for the rendezvous of the cluster, it manages which nodes are members of the
clusters, and how to store the nodes' state in the cluster. Both server and client need to have access to the Membership Storage.

The Membership Protocol is a server that run in each node of the cluster, it is reponsible for testing
the nodes to define which nodes are alive and which are dead.
The Memebership Protocols utilize the Membership Storage to store the state of the nodes in the cluster.

Currently, we only have a `PeerToPeerClusterProvider`, which is a simple implementation of the cluster membership protocol that uses a gossip protocol to keep track of the nodes in the cluster.

As for Storages, we have a few:

- LocalStorage: A simple in-memory storage, built just for testing
- HttpMembershipStorage: A read-only storage that uses HTTP API to expose information of the cluster, it is useful to use this on the client side, but it should never be used on the server side, since it is read-only and the server needs to update the state of the cluster.
- PostgresMembershipStorage
- RedisMembershipStorage
- SqliteMembershipStorage

### Object Placement

Object Placement maps each object's location in the cluster. Only the server has access to the Object Placement, and it is used by the server to know where to send the requests for each object.

- LocalObjectPlacement: Simple in-memory object placement, built just for testing
- PostgresObjectPlacement
- RedisObjectPlacement
- SqliteObjectPlacement

### Object Persistence (Managed State)

Rio offers a way to manage the state of your objects in a persistent storage.
You can simply drop the `ManagedState` derive on your struct, and it will automatically implement necessary
traits to serialize and deserialize your struct, and to save and load it from a persistence backend.
Alternatively, you can implement the persistence traits manually, if you need more control over how your state is saved and loaded.

Here are the built-in persistence backends:

- LocalState: A simple in-memory state, built just for testing
- PostgresState
- RedisState
- SqliteState
147 changes: 47 additions & 100 deletions README.tpl.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,103 +10,50 @@

---

## Roadmap

There are a few things that must be done before v0.1.0:

### Next

- [x] Do some renaming around:
- rename MembersStorage to MembershipStorage (rio_rs::cluster::storage)
- ObjectPlacement to ObjectPlacementItem (rio_rs::object_placement)
- ObjectPlacementProvider to ObjectPlacement (rio_rs::object_placement)
- [x] Bypass clustering for self messages
- Not an issue. You can do just `Self::handle(my_other_message)?`
- [x] Bypass networking for local messages
- Already handled by `rio_rs::service::Service::call`
- [x] Tracing
- [ ] MDNs
- [ ] Client bindings for other languages
- [ ] Remove the need for two types of concurrent hashmap (papaya and dashmap)
- [ ] Guest languages support - Currently possible with WASM + tons of boiler-plate
- [ ] Create server from config
- [ ] Move all the client to user tower
- [ ] Remove the need to pass the StateSaver to `ObjectStateManager::save_state`
- Might not be feasible, there are a few workarounds for testing that I might write some examples
and call it a day
- [ ] Include registry configuration in Server builder
- [ ] Create a getting started tutorial
- Cargo init
- Add deps (rio-rs, tokio, async_trait, serde, sqlx - optional)
- Write a server
- Write a client
- Add service and messages
- Cargo run --bin server
- Cargo run --bin client
- Life cycle
- Life cycle depends on app_data(StateLoader + StateSaver)
- Cargo test?
- [ ] MySQL support for sql backends
- [ ] Add pgsql jsonb support
- [ ] Client/server keep alive
- [ ] Topology - nodes work with different sets of service types
- [ ] Placement strategies - sets where to place objects
- [ ] Supervision
- [ ] Ephemeral objects (aka regular - local - actors)
- [ ] Remove magic numbers
- [ ] Object TTL
- [ ] Code of conduct
- [ ] Metrics
- [ ] Deny allocations based on system resources
- [ ] Dockerized examples
- [ ] Reduce static lifetimes
- Might not be feasible


### Version 0.2.3

- [x] Improve error message for ManagedState macro when the struct doesn't implement ServiceObject
- [x] Improve error message for ManagedState when the storage is not in the context
- [x] Improve error message for when the services are not added to the registry (server)
- [x] Client doesn't need to have a access to the cluster backend if we implement an HTTP API

### Version 0.2.0

- [x] Support 'typed' message/response on client (TODO define what this means)
- [x] Ability to hook up own custom errors on message handlers
- [x] Allow `ServiceObject` trait without state persistence
- [x] Add more extensive tests to client/server integration
- [x] Increase public API test coverage
- [x] Add all SQL storage behind a feature flag (sqlite, mysql, pgsql, etc)
- [x] Matrix test with different backends
- [x] Replace prints with logging

### Version 0.1.0

- [x] Naive server/client protocol
- [x] Basic cluster support
- [x] Basic placement support
- [x] Object self shutdown
- [x] Naive object persistence
- [x] Public API renaming
- [x] Reduce Boxed objects
- [x] Create a Server builder
- [x] Remove need to use `add_static_fn(FromId::from_id)` -> Removed in favour of `Registry::add_type`
- [x] Support service background task
- [x] Pub/sub
- [x] Examples covering most use cases
- [x] Background async task on a service
- [x] Background blocking task on a service (_see_ [black-jack](./examples/black-jack))
- [x] Pub/sub (_see_ [black-jack](./examples/black-jack))
- [x] Re-organize workspace
- [x] Support ephemeral port
- [x] Remove the need for an `Option<T>` value for `managed_state` attributes (as long as it has a 'Default')
- [x] `ServiceObject::send` shouldn't need a type for the member storage
- [x] Handle panics on messages handling
- [x] Error and panic handling on life cycle hooks (probably kill the object)
- [x] Create a test or example to show re-allocation when servers dies
- [x] Sqlite support for sql backends
- [x] PostgreSQL support for sql backends
- [x] Redis support for members storage
- [x] Redis support for state backend (loader and saver)
- [x] Redis support for object placement
## Features

Here are some of the features that are fully implemented:

### Clustering

Clustering is divided in two parts: `Membership Protocol` and `Membership Storage`.

The Membership Storage is responsible for the rendezvous of the cluster, it manages which nodes are members of the
clusters, and how to store the nodes' state in the cluster. Both server and client need to have access to the Membership Storage.

The Membership Protocol is a server that run in each node of the cluster, it is reponsible for testing
the nodes to define which nodes are alive and which are dead.
The Memebership Protocols utilize the Membership Storage to store the state of the nodes in the cluster.

Currently, we only have a `PeerToPeerClusterProvider`, which is a simple implementation of the cluster membership protocol that uses a gossip protocol to keep track of the nodes in the cluster.

As for Storages, we have a few:

- LocalStorage: A simple in-memory storage, built just for testing
- HttpMembershipStorage: A read-only storage that uses HTTP API to expose information of the cluster, it is useful to use this on the client side, but it should never be used on the server side, since it is read-only and the server needs to update the state of the cluster.
- PostgresMembershipStorage
- RedisMembershipStorage
- SqliteMembershipStorage

### Object Placement

Object Placement maps each object's location in the cluster. Only the server has access to the Object Placement, and it is used by the server to know where to send the requests for each object.

- LocalObjectPlacement: Simple in-memory object placement, built just for testing
- PostgresObjectPlacement
- RedisObjectPlacement
- SqliteObjectPlacement

### Object Persistence (Managed State)

Rio offers a way to manage the state of your objects in a persistent storage.
You can simply drop the `ManagedState` derive on your struct, and it will automatically implement necessary
traits to serialize and deserialize your struct, and to save and load it from a persistence backend.
Alternatively, you can implement the persistence traits manually, if you need more control over how your state is saved and loaded.

Here are the built-in persistence backends:

- LocalState: A simple in-memory state, built just for testing
- PostgresState
- RedisState
- SqliteState