Skip to content

Commit

Permalink
More docs
Browse files Browse the repository at this point in the history
  • Loading branch information
halgari committed Jan 23, 2024
1 parent 1d713d2 commit 5c5574c
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 1 deletion.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# NexusMods.EventSourcing
EventSourcing and CQRS library for .NET. This library is designed for single process multi threaded applications, and provides
extremely high performance event sourcing and CQRS capabilities. The current datastore is based on RocksDB, but the interface is
designed to be easily swapped out for other storage systems.

This is a template repository for `NexusMods.App.*` repositories.
## Documentation
The full docs can be found [here](https://nexus-mods.github.io/NexusMods.EventSourcing/)

## License

Expand Down
49 changes: 49 additions & 0 deletions docs/Serialization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
hide:
- toc
---

## Serialization

Events and snapshot data are stored in a custom, extremely high performance binary serialization format. Since events are
readonly, and snapshots are versioned, there is a lot of flexibility in the serialization format.

The core of the serialization format is the `ISerializer` interface. This interface is indicating if a given serializer
(registered via Dependency Injection) can serialize a given type. If it can, the `TryGetFixedSize` may be called to get
the size of the serialized data. This is used to pre-allocate buffers for serialization. Returning false from this method
means that the serializer does not support fixed size serialization, and dynamic sized serialization will be used.

Serializers then implement either `IFixedSizeSerializer` or `IVariableSizedSerializer`. The fixed size serializer is used
when the `TryGetFixedSize` method returns true. The dynamic size serializer is used when the `TryGetFixedSize` method returns
false.

`IEvent` records are seralized via the BinaryEventSerializer. This serializer is designed to be extremely fast, and auto
generates the serialization code for each event type. The format isn't documented, but in general the members are sorted
by name, and the fixed sized members are written first in a large block. This allows for the fixed sized members to be
pre-allocated and serialized in a single block. Since all events are marked with an `EventId` attribute, no type information
is included in the serialized data.

!!!info
Events are assumed to be immutable, records and are not versioned. This is a solid assumption based on the structure of
the system, and allows for the serialization format to be extremely fast. But this does mean that special consideration
must be taken when designing events. Prefer to use a new event type for each change, rather than assuming that a new
property will be added to an existing event.

## Composite Types
Currently, composite types are not supported. This includes tuples and classes. This functionality could be added in the future,
but for now it's easy enough to structure records to avoid the need for composite types.

For example, let's say an event needs to add 3 files, instead of writing an event like this:

```csharp
public record AddFiles(string name, (string path, string hash)[] files) : IEvent;
```

Restructure the event to use several value arrays:

```csharp
public record AddFiles(string name, string[] paths, string[] hashes) : IEvent;
```

Not only does this avoid the need for composite types, but it also likely is slightly faster to serialize and deserialize,
as all the values of like type are packed together
2 changes: 2 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,7 @@ theme:
nav:
- Home: index.md
- Adapting to Changes: AdaptingToChanges.md
- Serialization: Serialization.md
- Secondary Indexes: SecondaryIndexes.md
- Storage Model: StorageModel.md

1 change: 1 addition & 0 deletions src/NexusMods.EventSourcing.RocksDB/RocksDBEventStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public RocksDBEventStore(TSerializer serializer, Settings settings, ISerializati
var options = new DbOptions();
options.SetCreateIfMissing();
options.SetCreateMissingColumnFamilies();
options.SetCompression(Compression.Zstd);

_db = RocksDb.Open(options,
settings.StorageLocation.ToString(), _families);
Expand Down

0 comments on commit 5c5574c

Please sign in to comment.