Crates.io | timesource |
lib.rs | timesource |
version | 0.1.3 |
source | src |
created_at | 2021-10-29 10:46:53.606863 |
updated_at | 2022-01-17 16:51:48.638609 |
description | Event sourcing with TimescaleDb |
homepage | https://gitlab.com/j3a-solutions/timesource |
repository | https://gitlab.com/j3a-solutions/timesource |
max_upload_size | |
id | 473910 |
size | 156,825 |
Event sourcing with Timescaledb as storage engine for Rust applications.
NOTE: public APIs are very unstable. Documentation will be published when API stabilises further.
11 April 2262 23:47:16.854
.Timesource supports:
If no configuration is provided, timesource defaults to JSON. Encodings can be configured via derive attributes. For example:
#[derive(serde::Serialize, serde::Deserialize, TimesourceEvent, PartialEq, Debug)]
#[timesource(encoding = "json")] // this is optional, as JSON is already the default
enum TdbEventJson {
Created,
Abandoned(String),
#[allow(dead_code)]
AddedItem {
id: usize,
},
}
#[derive(minicbor::Encode, minicbor::Decode, TimesourceEvent, PartialEq, Debug)]
#[timesource(encoding = "cbor", version = "1.1")] // it's also possible to set the version along with the encoding
enum TdbEventCbor {
#[b(0)]
Created,
#[b(1)]
Abandoned(#[b(0)] String),
#[b(2)]
AddedItem {
#[b(0)]
id: usize,
},
}
mod proto {
use prost::Message;
#[derive(Clone, PartialEq, Message)]
pub struct Created {}
#[derive(Clone, PartialEq, Message)]
pub struct Abandoned {
#[prost(string, tag = "1")]
pub reason: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, Message)]
pub struct AddedItem {
#[prost(uint32, tag = "1")]
pub id: u32,
}
#[derive(Clone, PartialEq, Message, TimesourceEvent)]
#[timesource(encoding = "proto")]
pub struct TdbEvent {
#[prost(oneof = "tdb_event_proto::Data", tags = "1, 2, 3")]
pub data: ::core::option::Option<tdb_event_proto::Data>,
}
pub mod tdb_event_proto {
#[derive(Clone, PartialEq, ::prost::Oneof)]
pub enum Data {
#[prost(message, tag = "1")]
Created(super::Created),
#[prost(message, tag = "2")]
Abandoned(super::Abandoned),
#[prost(message, tag = "3")]
AddedItem(super::AddedItem),
}
}
}
Each of the supported protocols has its benefits and drawbacks, and there probably isn't one that would cover all use cases.
The following table summarizes why each protocol was chosen:
Encoding | Human-friendly (i.e. easy to read) | Performance | Stored size | Schema evolution support |
---|---|---|---|---|
JSON | x | (manual via derive attribute) | ||
CBOR | x | x | x | |
Protobuf | x | x | x |
While there are no benchmarks for timesource yet, it may be useful to check serdebench for serialisation benchmarks.
Timesource was born out as a fork of eventually-rs. Eventually-rs doesn't support timestamps, and so it isn't possible to use timescaledb as storage engine in a meaningful way.
Whereas Eventually's philosophy is to be an event sourcing library with pluggable storage engines, Timesource will only ever support Timescaledb. This makes Timesource much narrower in scope. It also allows for a number of optimisations, a more efficient handling of events and the removal of the risk for memory overflows.