public async Task StartParticipatingInElectionAsync() { await Task.Run(async() => { //Create our InOrder key under the election key. // If we're the first node we'll get /MasterElection/Status/1, second /MasterElection/Status/2 (roughly speaking) var instanceElectionResponse = await etcdClient.CreateInOrderNodeAsync(ElectionKey, InstanceId, electionTimeoutSec); while (!cancellationToken.IsCancellationRequested) { var shouldBeMaster = await UpdateKeyAndCheckIsMaster(instanceElectionResponse.Node); Debug.WriteLine($"Is master: {shouldBeMaster}"); if (shouldBeMaster) { if (IsMaster) { Debug.WriteLine($"Was already master, nothing changes"); } else { isMaster = true; await CancelCurrentElectionTaskAsync(); electionTask = Task.Run(() => isNowMaster(electionTaskCancellationSource.Token)); Debug.WriteLine($"Becoming master, wasn't already"); } } else { if (!IsMaster && electionTask != null) { Debug.WriteLine($"Was already secondary, nothing changes"); } else { isMaster = false; await CancelCurrentElectionTaskAsync(); electionTask = Task.Run(() => isNowSecondary(electionTaskCancellationSource.Token)); Debug.WriteLine($"Not the master, either lost it or never had it"); } } } }); }
static async Task DoSample() { EtcdClientOpitions options = new EtcdClientOpitions() { #if NET45 // TODO: This is optional, having HTTPS setup could make this work in .NET Core as well, but it's not tested for now Urls = new string[] { "https://etcd0.em", "https://etcd1.em", "https://etcd2.em" }, #else Urls = new string[] { "http://*****:*****@"client.p12"), // client cerificate JsonDeserializer = new NewtonsoftJsonDeserializer(), }; EtcdClient etcdClient = new EtcdClient(options); string key = "/my/key"; string value; // query the value of the node using GetNodeValueAsync try { value = await etcdClient.GetNodeValueAsync(key); Console.WriteLine("The value of `{0}` is `{1}`", key, value); } catch (EtcdCommonException.KeyNotFound) { Console.WriteLine("Key `{0}` does not exist", key); } // update the value using SetNodeAsync EtcdResponse resp = await etcdClient.SetNodeAsync(key, "some value"); Console.WriteLine("Key `{0}` is changed, modifiedIndex={1}", key, resp.Node.ModifiedIndex); // query the node using GetNodeAsync resp = await etcdClient.GetNodeAsync(key, ignoreKeyNotFoundException : true); if (resp == null || resp.Node == null) { Console.WriteLine("Key `{0}` does not exist", key); } else { Console.WriteLine("The value of `{0}` is `{1}`", key, resp.Node.Value); } ////////////////////////////////////////////////////////// List <Task <EtcdResponse> > tasks = new List <Task <EtcdResponse> >(); key = "/in-order-queue"; // start monitoring the expire event WatchChanges(etcdClient, key); // create 5 in-order nodes, TTL = 3 second for (int i = 0; i < 5; i++) { tasks.Add(etcdClient.CreateInOrderNodeAsync(key, i.ToString(), ttl: 3)); } await Task.WhenAll(tasks); // list the in-order nodes resp = await etcdClient.GetNodeAsync(key, false, recursive : true, sorted : true); if (resp.Node.Nodes != null) { foreach (var node in resp.Node.Nodes) { Console.WriteLine("`{0}` = {1}", node.Key, node.Value); } } ///////////////////////////////////////////////////////////// key = "/my/cas-test"; value = Guid.NewGuid().ToString(); try { resp = await etcdClient.CreateNodeAsync(key, value, null, dir : false); Console.WriteLine("Key `{0}` is created with value {1}", key, value); } catch (EtcdCommonException.NodeExist) { Console.WriteLine("Key `{0}` already exists", key); } long prevIndex = 1; try { resp = await etcdClient.CompareAndSwapNodeAsync(key, value, "new value"); Console.WriteLine("Key `{0}` is updated to `{1}`", key, resp.Node.Value); prevIndex = resp.Node.ModifiedIndex; } catch (EtcdCommonException.KeyNotFound) { Console.WriteLine("Key `{0}` does not exists", key); } catch (EtcdCommonException.TestFailed) { Console.WriteLine("Key `{0}` can not be updated because the supplied previous value is incorrect", key); } try { resp = await etcdClient.CompareAndSwapNodeAsync(key, prevIndex, "new value2"); Console.WriteLine("Key `{0}` is updated to `{1}`", key, resp.Node.Value); } catch (EtcdCommonException.KeyNotFound) { Console.WriteLine("Key `{0}` does not exists", key); } catch (EtcdCommonException.TestFailed) { Console.WriteLine("Key `{0}` can not be updated because the supplied previous index is incorrect", key); } try { resp = await etcdClient.CompareAndDeleteNodeAsync(key, prevIndex + 1); Console.WriteLine("Key `{0}` is deleted", key); } catch (EtcdCommonException.KeyNotFound) { Console.WriteLine("Key `{0}` does not exists", key); } catch (EtcdCommonException.TestFailed) { Console.WriteLine("Key `{0}` can not be deleted because the supplied previous index is incorrect", key); } if (prevIndex == 1) // the previous CAS failed { try { resp = await etcdClient.CompareAndDeleteNodeAsync(key, "new value2"); Console.WriteLine("Key `{0}` is deleted", key); } catch (EtcdCommonException.KeyNotFound) { Console.WriteLine("Key `{0}` does not exists", key); } catch (EtcdCommonException.TestFailed) { Console.WriteLine("Key `{0}` can not be deleted because the supplied previous value is incorrect", key); etcdClient.DeleteNodeAsync(key, ignoreKeyNotFoundException: true).Wait(); } } }