Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mizrael/eveniredb
small stream-based DB engine
https://github.com/mizrael/eveniredb
database dotnet event-sourcing stream
Last synced: 20 days ago
JSON representation
small stream-based DB engine
- Host: GitHub
- URL: https://github.com/mizrael/eveniredb
- Owner: mizrael
- License: apache-2.0
- Created: 2023-09-16T01:33:41.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2024-08-13T02:25:30.000Z (3 months ago)
- Last Synced: 2024-10-15T03:09:40.954Z (about 1 month ago)
- Topics: database, dotnet, event-sourcing, stream
- Language: C#
- Homepage:
- Size: 1.02 MB
- Stars: 36
- Watchers: 3
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# EvenireDB
[![Tests](https://github.com/mizrael/EvenireDB/actions/workflows/dotnet.yml/badge.svg)](https://github.com/mizrael/EvenireDB/actions/workflows/dotnet.yml)
![coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/mizrael/ebd585c5ad0069d0e8486e43cade5793/raw/eveniredb-code-coverage.json)
[![client Nuget](https://img.shields.io/nuget/v/EvenireDB.Client?style=plastic)](https://www.nuget.org/packages/EvenireDB.Client/)> [Evenire](https://en.wiktionary.org/wiki/evenire), from Latin, present active infinitive of *ēveniō*, "to happen".
This project is a Proof-of-Concept of a small stream-based DB engine.
One of the potential use cases is Event Sourcing. If you don't know what Event Sourcing is, I've been writing for a while about it on [my blog](https://www.davidguida.net). These articles can be a good starting point:
- [Event Sourcing in .NET Core – part 1: a gentle introduction](https://www.davidguida.net/event-sourcing-in-net-core-part-1-a-gentle-introduction/)
- [Event Sourcing: 5 things to consider when approaching it](https://www.davidguida.net/event-sourcing-things-to-consider)I took a personal interest in this amazing pattern and after a while using it, I also wanted to write a database system specifically suited for it.
Honestly, I don't know how far this project will go, but I'm having a lot of fun so far and I am definitely learning a lot :)## How does it work?
The basic idea behind Evenire is quite simple: events can be appended to streams and later on, retrieved by providing the stream ID.
Streams are identified by a tuple composed of a `Guid` (the stream key) and a string (the stream type). For the curious, the sources are [here](https://github.com/mizrael/EvenireDB/tree/main/src/EvenireDB.Common/StreamId.cs)).
Every stream is kept in memory using a local cache, for fast retrieval. A background process takes care of serializing events to a file, one per stream.
Reading can happen from the very beginning of a stream moving forward or from a specific point. This is the basic scenario, useful when you want to rehydrate the state of an [Aggregate](https://www.martinfowler.com/bliki/DDD_Aggregate.html).
Another option is to read the events from the _end_ of the stream instead, moving backward in time. This is interesting for example if you are recording data from sensors and you want to retrieve the latest state.
AuthN/Z was **left out intentionally** as it would go outside the scope of the project (for now).
## Setup
As of now, there are two possible options for spinning up an Evenire server:
- deploying the [Server project](https://github.com/mizrael/EvenireDB/tree/main/src/EvenireDB.Server) somewhere
- building the [docker image](https://github.com/mizrael/EvenireDB/blob/main/Dockerfile) and deploying it somewhereThese are both viable options, however, I would recommend opting for the Docker solution as it will package everything you need in the container. Building the image can be done using [this script](https://github.com/mizrael/EvenireDB/blob/main/scripts/dockerize.ps1).
Once you have the image ready, you can run it in a Container by running `docker compose up`.
## Client configuration
Once your server is up, you can start using it to store your events. If you are writing a .NET application, you can leverage [the Client library](https://github.com/mizrael/EvenireDB/tree/main/src/EvenireDB.Client) I provided.
Client configuration is pretty easy. The first step is to update your `appsettings.json` file and add a new section:
```json
{
"Evenire": {
"ServerUri": "[your server url here]",
"HttpSettings": {
"Port": 80 <---- make sure this is correct for you
},
"GrpcSettings": {
"Port": 5243 <---- make sure this is correct for you
}
}
}
```Once you have that, the last step is to register EvenireDB on your DI container. Something like this:
```csharp
var builder = WebApplication.CreateBuilder(args);var clientConfig = builder.Configuration.GetSection("Evenire").Get();
builder.Services.AddEvenireDB(clientConfig);
```### Writing events
Once you have added the Client to your DI Container, just inject `IEventsClient` into your classes and start making calls to it:
```csharp
var streamKey = /* this is a GUID */;
var streamId = new StreamId(streamKey, "MyStreamType");await _eventsClient.AppendAsync(streamId, new[]
{
Event.Create(new{ Foo = "bar" }, "Event type 1"),
Event.Create(new{ Bar = "Baz" }, "Event type 1"),
});
```### Reading events
Reading too can be done trough an `IEventsClient` instance:
```csharp
var streamKey = /* this is a GUID */;
var streamId = new StreamId(streamKey, "MyStreamType");// write some events for streamId...
await foreach(var @event in client.ReadAsync(streamId, StreamPosition.Start, Direction.Forward).ConfigureAwait(false)){
// do something with the event
}
````ReadAsync` can be configured to fetch the events from `StreamPosition.Start`, `StreamPosition.End` or a specific point in the stream. You can also specify the direction you want to move (forward or backward).
## Admin UI
Evenire also has a rudimentary administration UI, written with Blazor. It allows a few basic operations:
- see the list of all the available streams
- create a new stream
- append events to an existing stream
- delete a stream![streams archive](https://raw.githubusercontent.com/mizrael/EvenireDB/main/docs/assets/streams_archive.jpg)
![stream details](https://raw.githubusercontent.com/mizrael/EvenireDB/main/docs/assets/stream_details.jpg)
## Samples
- [TemperatureSensors](https://github.com/mizrael/EvenireDB/tree/main/samples/EvenireDB.Samples.TemperatureSensors) shows how to use a Background worker to produce events and uses Minimal APIs to retrieve the latest events for a specific stream.## TODO
- snapshots
- backup and replicas
- cluster management