Memstate is a complete redesign of OrigoDB with major improvements in key areas such as performance, availability, licensing, cross-platform, docker and cloud support.
Performance - OrigoDB can process up to 3K write transactions per second, Memstate can process up to 100K, a 33x improvement!
High Availability - An OrigoDB cluster has a single primary and one or more read-only replicas. If the primary fails one of the replicas can be promoted to new primary but this requires manual intervention. Nodes in a Memstate cluster are all read/write.
Licensing - OrigoDB Server is a commercial offering while Memstate server is OSS and free for commercial use.
Cross platform - Memstate targets .NET Standard 2.0 which means it runs on both .NET Framework >= 4.6.1 and .NET Core >=2.0, Mono, Xamarin, UWP.
Data can be spread across multiple OrigoDb Server nodes, aka sharding or horizontal data partitioning. Partition logic is handled by PartitionClusterClient, the process is entirely transparent to the server instances. The client maintains a list of nodes, dispatches queries and commands to one or more nodes and merges results from multiple nodes.
Dispatching
By default, the client dispatches each command and query to every node. Set a custom dispatcher for command or query type T by calling SetDispatcherFor<T>(Func<T,int> dispatcher) or SetDispatcherFor<T>(Func<T,int[]> dispatcher). The dispatcher must return either a zero-based index of the target node or an array of node indices for dispatching to multiple nodes.
Merging
Results from commands and queries need to be aggregated. Register a merger function by calling SetMergerFor<T>() where T can be a command, query or result type. The function takes an array of the expected result type and must return an instance of the return type. For a query with the signature Query<M,R> a merger must have the signature Func<R[],R>. A merger with the wrong signature will throw a runtime exception.
Example code
Using the client
Partitioning schemes
The example above partitions using a modulus function and changing the number of nodes will affect the partitioning. Design a scheme that will accommodate for growth without the need to move data between nodes. For an example, see the GeekStream model, which is designed for partitioning.
Partitioning and ACID
When partitioning, atomicity, isolation and consistency are not necessarily guaranteed. Design accordingly.