dotnet-etcd 7.2.0

dotnet add package dotnet-etcd --version 7.2.0                
NuGet\Install-Package dotnet-etcd -Version 7.2.0                
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="dotnet-etcd" Version="7.2.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add dotnet-etcd --version 7.2.0                
#r "nuget: dotnet-etcd, 7.2.0"                
#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.
// Install dotnet-etcd as a Cake Addin
#addin nuget:?package=dotnet-etcd&version=7.2.0

// Install dotnet-etcd as a Cake Tool
#tool nuget:?package=dotnet-etcd&version=7.2.0                

dotnet-etcd

alternate text is missing from this package README image

A C# .NET (dotnet) GRPC client for etcd v3+

Build Status Nuget Version Info Nuget Download Info

Supported .NET Versions

  • .NET 7
  • .NET 6

For older dotnet versions, use lib version < 5.x

Installing Package

Nuget package is published on nuget.org and can be installed in the following ways :

Nuget Package Manager

Install-Package dotnet-etcd

.NET CLI

dotnet add package dotnet-etcd

Paket CLI

paket add dotnet-etcd

The NuGet Team does not provide support for this client. Please contact its maintainers for support.

Usage :

Add using statement at the top of your class file

    using dotnet_etcd;

Client Initialization

    EtcdClient client = new EtcdClient("host1:port1:,...., hostN:portN");
    // E.g.
    EtcdClient etcdClient = new EtcdClient("https://localhost:23790,https://localhost:23791,https://localhost:23792");
Insecure Endpoint
    EtcdClient client = new EtcdClient("host1:port1:,...., hostN:portN", configureChannelOptions: (options =>
    {
        options.Credentials = ChannelCredentials.Insecure;
    }));

    // E.g.
    EtcdClient etcdClient = new EtcdClient("http://localhost:23790,http://localhost:23791,http://localhost:23792", configureChannelOptions: (options =>
    {
        options.Credentials = ChannelCredentials.Insecure;
    }));

Client With user and password

    EtcdClient client = new EtcdClient("https://localhost:23790");
    var authRes = client.Authenticate(new Etcdserverpb.AuthenticateRequest()
    {
        Name = "name",
        Password = "password",
    });
    //  Put key "foo/bar" with value "barfoo" with authenticated token
    client.Put("foo/bar", "barfoo", new Grpc.Core.Metadata() {
        new Grpc.Core.Metadata.Entry("token",authRes.Token)
    });
Available Constructor Parameters
  • handler - Http Handler that can be used by the underlying grpc client. This can be used for variouse use cases, for e.g. configuring client certifcates . Default : null
  • ssl - Bool depicting whether to configure a secure or unsecure connection. Default : false.
  • useLegacyRpcExceptionForCancellation - Bool setting to revert task cancellations back to throwing gRPC's RpcException with a StatusCode=Cancelled. The default behavior now is to throw an OperationCanceledException, which integrates better with .net Tasks. Default : false.

Operations

A lot of methods have been implemented using etcd's default input/output parameters. I am simplifying a lot of methods by including more overloads as I come across use cases. If you have some, please feel free to raise and issue or a PR 😃

Key-Value Operations
Put a key
    client.Put(<KEY_STRING>,<VALUE_STRING>);
    // E.g Put key "foo/bar" with value "foobar"
    client.Put("foo/bar","barfoo");

    await client.PutAsync(<KEY_STRING>,<VALUE_STRING>);
    // E.g Put key "foo/bar" with value "foobar" in async
    await client.PutAsync("foo/bar","barfoo");
Get a key
    client.GetVal(<KEY_STRING>);
    // E.g Get key "foo/bar"
    client.GetVal("foo/bar");
    // To get full etcd response
    client.Get("foo/bar");

    await client.GetValAsync(<KEY_STRING>);
    // E.g. Get key "foo/bar" in async
    await client.GetValAsync("foo/bar");
    // To get full etcd response
    await client.GetAsync("foo/bar");
Get multiple keys with a common prefix
    client.GetRange(<PREFIX_STRING>);
    // E.g. Get all keys with pattern "foo/*"
    client.GetRange("foo/"); 

    await client.GetRangeAsync(<PREFIX_STRING>);
    // E.g. Get all keys with pattern "foo/*" in async
    await client.GetRangeAsync("foo/");

    // E.g. Get all keys
    await client.GetRangeAsync("");
Delete a key
    client.Delete(<KEY_STRING>);
    // E.g. Delete key "foo/bar"
    client.Delete("foo/bar");

    await client.DeleteAsync(<KEY_STRING>);
    // E.g. Delete key "foo/bar" in async
    await client.DeleteAsync("foo/bar");
Delete multiple keys with a common prefix
    client.DeleteRange(<PREFIX_STRING>);
    // E.g. Delete all keys with pattern "foo/*"
    client.DeleteRange("foo/"); 

    await client.DeleteRangeAsync(<PREFIX_STRING>);
    // E.g. Delete all keys with pattern "foo/*" in async
    await client.DeleteRangeAsync("foo/");

Watch Operations

Watch a key
    WatchRequest request = new WatchRequest()
    {
        CreateRequest = new WatchCreateRequest()
        {
            Key = ByteString.CopyFromUtf8("foo")
        }
    };
    etcdClient.Watch(request, print);

    // -------------------------------
    // Print function that prints key and value from the watch response
    private static void print(WatchResponse response)
    {   
        if (response.Events.Count == 0)
        {
            Console.WriteLine(response);
        }
        else
        {
            Console.WriteLine($"{response.Events[0].Kv.Key.ToStringUtf8()}:{response.Events .Kv.Value.ToStringUtf8()}");
        }
    }

    // ----------------------------------
    // Print function that prints key and value from the minimal watch
    // response data 
    private static void print(WatchEvent[] response)
    {
        foreach(WatchEvent e1 in response)
        {
            Console.WriteLine($"{e1.Key}:{e1.Value}:{e1.Type}");
        }
    }

Watch also has a simple overload as follows

    etcdClient.Watch("foo", print);

More overloads are also available. You can check them using IntelliSense (Ctrl+Shift+Space). Detailed documentation coming soon.

Cluster Operations

Add a member into the cluster
     MemberAddRequest request = new MemberAddRequest();
     request.PeerURLs.Add("http://example.com:2380");
     request.PeerURLs.Add("http://10.0.0.1:2380");
     MemberAddResponse res = etcdClient.MemberAdd(request);

     // Async
     MemberAddResponse res = await etcdClient.MemberAddAsync(request);

     // Do something with response
Remove an existing member from the cluster
    MemberRemoveRequest request = new MemberRemoveRequest
    {
        // ID of member to be removed
        ID = 651748107021
    };
    MemberRemoveResponse res = etcdClient.MemberRemove(request);

    // Async
    MemberRemoveResponse res = await etcdClient.MemberRemoveAsync(request);

    // Do something with response

Update the member configuration

    MemberUpdateRequest request = new MemberUpdateRequest
    {
        // ID of member to be updated
        ID = 651748107021
    };
    request.PeerURLs.Add("http://10.0.0.1:2380");
    MemberUpdateResponse res = etcdClient.MemberUpdate(request);

    // Async
    MemberUpdateResponse res = await etcdClient.MemberUpdateAsync(request);

    // Do something with response

List all the members in the cluster

    MemberListRequest request = new MemberListRequest();
    etcdClient.MemberList(request);
    MemberListResponse res = etcdClient.MemberList(request);

    // Async
    MemberListResponse res = await etcdClient.MemberListAsync(request);

    // Do something with response
    foreach(var member in res.Members)
    {
        Console.WriteLine($"{member.ID} - {member.Name} - {member.PeerURLs}");
    }

Modify data with transaction https://etcd.io/docs/v3.4.0/learning/api/#transaction

    var txr = new Etcdserverpb.TxnRequest();
    txr.Success.Add(new Etcdserverpb.RequestOp()
    {
        RequestPut = new Etcdserverpb.PutRequest()
        {
            Key = Google.Protobuf.ByteString.CopyFrom("transaction-key", System.Text.Encoding.UTF8),
            Value = Google.Protobuf.ByteString.CopyFrom("tv", System.Text.Encoding.UTF8),
        }
    });
    client.Transaction(txr);

Canceling an operation

Handling cancellations with OperationCanceledException

This is the default behavior selected when creating the EtcdClient with the useLegacyRpcExceptionForCancellation parameter set to false.

    CancellationTokenSource cts = new CancellationTokenSource();
    CancellationToken cancellationToken = cts.Token;

    try
    {
        cts.Cancel();
        StatusRequest request = new StatusRequest();
        StatusResponse response = client.Status(request, cancellationToken: cancellationToken);
        bool isOK = response.Errors.Count == 0;
        Console.WriteLine(isOK ? "Status OK" : "Status not OK");
    }
    catch (OperationCanceledException)
    {
        Console.WriteLine("Operation was canceled.");
    }
Legacy cancellation with RpcException and StatusCode=Cancelled

The next sample shows the behavior when gRPC throws an RpcException with Cancelled StatusCode. To enable this legacy feature, create the EtcdClient with the useLegacyRpcExceptionForCancellation set to true.

    using EtcdClient client = new EtcdClient(
        "https://localhost:2379",
        useLegacyRpcExceptionForCancellation: true);

    CancellationTokenSource cts = new CancellationTokenSource();
    CancellationToken cancellationToken = cts.Token;

    try
    {
        cts.Cancel();
        StatusRequest request = new StatusRequest();
        StatusResponse response = client.Status(request, cancellationToken: cancellationToken);
        bool isOK = response.Errors.Count == 0;
        Console.WriteLine(isOK ? "Status OK" : "Status not OK");
    }
    catch (RpcException rpc) // useLegacyRpcExceptionForCancellation: true
    {
        if (rpc.StatusCode == StatusCode.Cancelled)
        {
            Console.WriteLine("Operation was canceled.");
        }
        else throw;
    }
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 is compatible.  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 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (30)

Showing the top 5 NuGet packages that depend on dotnet-etcd:

Package Downloads
NetCorePal.Extensions.Snowflake.Etcd

NetCorePal Cloud Framework

cm-catalog-etcd

A CM Catalog implementation using etcd.

Etcd.Configuration

Get configuration from etcd configuration center.

etcd.Provider.Cluster.Extensions

etcd客户端扩展,集群客户端刷新

Ocelot.Provider.Etcd.Cluster

Provides Ocelot extensions to use etcd

GitHub repositories (1)

Showing the top 1 popular GitHub repositories that depend on dotnet-etcd:

Repository Stars
netcorepal/netcorepal-cloud-framework
基于 ASP.NET Core 的领域驱动设计微服务架构实现方案
Version Downloads Last updated
7.2.0 1,998 10/19/2024
7.1.1 9,379 8/4/2024
7.1.0 92 7/30/2024
7.0.0 723 7/14/2024
7.0.0-beta 8,173 1/7/2024
6.2.0-beta 24,002 12/7/2022
6.0.1 132,879 11/9/2022
6.0.0-beta.0 3,392 9/27/2022
5.2.1 144,809 7/16/2022
5.2.0 112,772 3/2/2022
5.1.0 69,452 10/19/2021
5.0.2 28,974 9/6/2021
5.0.2-alpha 764 8/22/2021
5.0.0-alpha 743 8/9/2021
4.2.0 401,932 12/8/2020
4.1.1 85,304 7/12/2020
4.1.0-beta 1,107 5/31/2020
4.0.0-beta 998 5/10/2020
3.2.0 57,124 4/6/2020
3.1.1 11,636 3/21/2020
3.1.0 2,605 2/23/2020
3.0.0.1-beta 1,313 9/6/2019
3.0.0 55,224 9/24/2019
3.0.0-beta 3,269 9/6/2019
3.0.0-alpha 1,044 8/11/2019
2.3.1 175,880 3/18/2019
2.3.0 1,864 3/9/2019
2.2.0 1,508 2/17/2019
2.1.1 1,667 2/12/2019
2.1.0 1,910 1/27/2019
2.0.1 8,067 12/9/2018
2.0.0 1,830 11/18/2018

* Package updates
   * Minor enhancements and cleanups