Varelen.Mimoria.Core 0.0.1-alpha3

This is a prerelease version of Varelen.Mimoria.Core.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Varelen.Mimoria.Core --version 0.0.1-alpha3
                    
NuGet\Install-Package Varelen.Mimoria.Core -Version 0.0.1-alpha3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Varelen.Mimoria.Core" Version="0.0.1-alpha3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Varelen.Mimoria.Core" Version="0.0.1-alpha3" />
                    
Directory.Packages.props
<PackageReference Include="Varelen.Mimoria.Core" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Varelen.Mimoria.Core --version 0.0.1-alpha3
                    
#r "nuget: Varelen.Mimoria.Core, 0.0.1-alpha3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#addin nuget:?package=Varelen.Mimoria.Core&version=0.0.1-alpha3&prerelease
                    
Install Varelen.Mimoria.Core as a Cake Addin
#tool nuget:?package=Varelen.Mimoria.Core&version=0.0.1-alpha3&prerelease
                    
Install Varelen.Mimoria.Core as a Cake Tool

mimoria

Build and Test Publish Docker image NuGet Version Docker Image Version GitHub License

Modern and performant cross-platform distributed key-value cache server written in .NET 9.

Currently under development.

Content

Features

  • structured data (key-value, list, json, binary, map, counter)
    • list has optional per value expiration
  • publish and subscribe (built-in channels like key expiration, deletion, list added)
  • good test coverage (unit, integration and system) and asserts
  • metrics built-in with support for Azure Application Insights
  • cluster support for primary and secondary servers (WIP)
    • synchronous replication
    • asynchronous replication
  • client libraries
    • C# (with micro caching and DI support)
    • TypeScript/Node
    • Rust
  • json and binary object serialization
  • cross platform (Windows, Linux, macOS and ARM)
  • retry policies and resilience for
    • connect and auto reconnect
    • operation response timeout
    • built-in exponential and linear retry policy
  • IPv4 and IPv6 support

Installation server

Quickstart

You can run the server with Docker based on the main branch:

docker run -p 6565:6565 --name mimoria -e MIMORIA__PASSWORD=PleaseChooseAVeryLongOne varelen/mimoria:main

To change the port:

docker run -p 50000:50000 --name mimoria -e MIMORIA__PORT=50000 -e MIMORIA__PASSWORD=PleaseChooseAVeryLongOne varelen/mimoria:main

See the config section for more options.

Manual

From source

Installation client

You can install the .NET client library from Nuget:

dotnet add package Varelen.Mimoria.Client

C# client examples

Using dotnet dependency injection (IServiceCollection):

// ...

builder.Services.AddMimoria(options =>
{
    options.Host = "localhost";
    options.Port = 6565;
    options.OperationTimeout = TimeSpan.FromMilliseconds(250);
    options.ConnectRetryPolicy = new ExponentialRetryPolicy(initialDelay: 1000, maxRetries: 4, typeof(TimeoutException));
    options.OperationRetryPolicy = new ExponentialRetryPolicy<IByteBuffer>(initialDelay: 1000, maxRetries: 4, typeof(TimeoutException));
});

// The "IMimoriaClient" interface can then be injected and be used

Single instance:

IMimoriaClient mimoriaClient = new MimoriaClient("127.0.0.1", 6565, "password");

await mimoriaClient.ConnectAsync();

await mimoriaClient.SetStringAsync("key", "Hello!", ttl: TimeSpan.FromMinutes(5));

string? value = await mimoriaClient.GetStringAsync("key");
Console.WriteLine(value);
// Outputs:
// Hello!

Stats stats = await mimoriaClient.GetStatsAsync();
Console.WriteLine(stats);
// Outputs:
// Uptime: 6, Connections: 1, CacheSize: 1, CacheHits: 1, CacheMisses: 0, CacheHitRatio: 1 (100%)

Pub Sub with add list subscription and expiring list value:

IMimoriaClient mimoriaClient = new MimoriaClient("127.0.0.1", 6565, "password");
await mimoriaClient.ConnectAsync();

var subscription = await mimoriaClient.SubscribeAsync(Channels.ForListAdded("elements"));
subscription.Payload += HandleListAdded;

static void HandleListAdded(MimoriaValue payload)
{
    string element = payload!;

    Console.WriteLine($"Added to the elements list: {element}");
}

await mimoriaClient.AddListAsync("elements", "Water");
await mimoriaClient.AddListAsync("elements", "Air", ttl: default, valueTtl: TimeSpan.FromSeconds(1));

await Task.Delay(TimeSpan.FromSeconds(2));

List<string> list = await mimoriaClient.GetListAsync("elements");
// List only contains 'Water'

Cluster servers (primary and secondaries):

var clusterMimoriaClient = new ClusterMimoriaClient("password", [
    new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6565),
    new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6567),
    new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6569)
]);

await clusterMimoriaClient.ConnectAsync();

await clusterMimoriaClient.SetStringAsync("key", "valueeeee");

string? value = await clusterMimoriaClient.GetStringAsync("key", preferSecondary: true);
Console.WriteLine(value);
// Outputs (if using sync replication):
// some value

Sharded servers:

IShardedMimoriaClient shardedMimoriaClient = new ShardedMimoriaClient(
    "password", new IPEndPoint(IPAddress.Loopback, 6565), new IPEndPoint(IPAddress.Loopback, 6666));

await shardedMimoriaClient.ConnectAsync();

await shardedMimoriaClient.SetStringAsync("key", "some value");
string? value = await shardedMimoriaClient.GetStringAsync("key");
Console.WriteLine(value);
// Outputs:
// some value

Fast custom binary object serialization:

Guid userId = Guid.Parse("9d9b9548-3c34-415b-98c9-cb3bcfd56392");
var user = new User { Id = userId, Byte = 5, Name = "User 1" };

await mimoriaClient.SetObjectBinaryAsync($"user:{userId}", user);

User? responseUser = await mimoriaClient.GetObjectBinaryAsync<User>($"user:{userId}");
Console.WriteLine(responseUser)
// Outputs:
// Id: 9d9b9548-3c34-415b-98c9-cb3bcfd56392, Byte: 5, Name: User 1

public class User : IBinarySerializable
{
    public Guid Id { get; set; }
    public byte Byte { get; set; }
    public string Name { get; set; }
    
    public void Serialize(IByteBuffer byteBuffer)
    {
        byteBuffer.WriteGuid(this.Id);
        byteBuffer.WriteByte(this.Byte);
        byteBuffer.WriteString(this.Name);
    }

    public void Deserialize(IByteBuffer byteBuffer)
    {
        this.Id = byteBuffer.ReadGuid();
        this.Byte = byteBuffer.ReadByte();
        this.Name = byteBuffer.ReadString()!;
    }

    public override string ToString()
        => $"Id: {this.Id}, Byte: {this.Byte}, Name: {this.Name}";
}

Json object serialization:

Guid userId = Guid.Parse("9d9b9548-3c34-415b-98c9-cb3bcfd56392");
var user = new User { Id = userId, Byte = 5, Name = "User 1" };

await mimoriaClient.SetObjectJsonAsync<User>($"user:{userId}", user);

User? responseUser = await mimoriaClient.GetObjectJsonAsync<User>($"user:{userId}");
Console.WriteLine(responseUser);
// Outputs:
// Id: 9d9b9548-3c34-415b-98c9-cb3bcfd56392, Byte: 5, Name: User 1

Both SetObjectJsonAsync and GetObjectJsonAsync have an overload that can take an optional System.Text.Json.JsonSerializerOptions:

var jsonSerializerOptions = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };

await mimoriaClient.SetObjectJsonAsync<User>($"user:{myUserId}", user, jsonSerializerOptions);

_ = await mimoriaClient.GetObjectJsonAsync<User>($"user:{myUserId}", jsonSerializerOptions);

Config

Options can aslo be set via environment variables with two underscores as separators. List can be set with double underscores and the index.

Some examples:

MIMORIA__PASSWORD=PleaseChooseAVeryLongOne

MIMORIA__CLUSTER__ID=1

MIMORIA__CLUSTER__NODES__0__ID=2

Example of all config options:

{
    "Mimoria": {
        "Ip": "0.0.0.0",
        "Port": 6565,
        "Password": "password",
        "Cluster": {
            "Id": 1,
            "Ip": "127.0.0.1",
            "Port": 6566,
            "Password": "YourClusterPassword",
            "Nodes": [
                {
                    "Id": 2,
                    "Host": "127.0.0.2",
                    "Port": 6568
                }
            ],
            "Replication": {
                "Type": "Async",
                "IntervalMilliseconds": 5000
            },
            "Election": {
                "LeaderHeartbeatIntervalMs": 1000,
                "LeaderMissingTimeoutMs": 3000,
                "ElectionTimeoutMs": 1000
            }
        }
    },
    "ConnectionStrings": {
        "ApplicationInsights": "OptionalApplicationInsightsConnectionString"
    },
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "System": "Information",
            "Microsoft": "Warning"
        }
    }
}

Contributing

Any contributions are greatly appreciated. Just fork the project, create a new feature branch, commit and push your changes and open a pull request.

License

Distributed under the MIT License. See LICENSE for more information.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Varelen.Mimoria.Core:

Package Downloads
Varelen.Mimoria.Client

.NET client for the modern and performant cross-platform distributed key-value cache server Mimoria.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.0.1-alpha6 118 5 days ago
0.0.1-alpha5 122 6 days ago
0.0.1-alpha4 107 10 days ago
0.0.1-alpha3 118 a month ago
0.0.1-alpha2 148 a month ago
0.0.1-alpha1 104 a month ago