/// <summary> /// LeaseKeepAlive keeps the lease alive by streaming keep alive requests from the client /// to the server and streaming keep alive responses from the server to the client. /// </summary> /// <param name="leaseId"></param> /// <param name="cancellationToken"></param> public async Task LeaseKeepAlive(long leaseId, CancellationToken cancellationToken) { await CallEtcdAsync(async (connection) => { using (AsyncDuplexStreamingCall <LeaseKeepAliveRequest, LeaseKeepAliveResponse> leaser = connection.leaseClient.LeaseKeepAlive(cancellationToken: cancellationToken)) { LeaseKeepAliveRequest request = new LeaseKeepAliveRequest { ID = leaseId }; while (true) { cancellationToken.ThrowIfCancellationRequested(); await leaser.RequestStream.WriteAsync(request); if (!await leaser.ResponseStream.MoveNext(cancellationToken)) { await leaser.RequestStream.CompleteAsync(); throw new EndOfStreamException(); } LeaseKeepAliveResponse update = leaser.ResponseStream.Current; if (update.ID != leaseId || update.TTL == 0) // expired { await leaser.RequestStream.CompleteAsync(); return; } await Task.Delay(TimeSpan.FromMilliseconds(update.TTL * 1000 / 3), cancellationToken); } } }); }
/// <summary> /// LeaseKeepAlive keeps the lease alive by streaming keep alive requests from the client /// to the server and streaming keep alive responses from the server to the client. /// </summary> /// <param name="request">The request to send to the server.</param> /// <param name="methods"></param> /// <param name="cancellationToken"></param> /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param> public async Task LeaseKeepAlive(LeaseKeepAliveRequest request, Action <LeaseKeepAliveResponse>[] methods, CancellationToken cancellationToken, Grpc.Core.Metadata headers = null) { await CallEtcdAsync(async (connection) => { using (AsyncDuplexStreamingCall <LeaseKeepAliveRequest, LeaseKeepAliveResponse> leaser = connection.leaseClient .LeaseKeepAlive(headers, cancellationToken: cancellationToken)) { Task leaserTask = Task.Run(async() => { while (await leaser.ResponseStream.MoveNext(cancellationToken)) { LeaseKeepAliveResponse update = leaser.ResponseStream.Current; foreach (Action <LeaseKeepAliveResponse> method in methods) { method(update); } } }, cancellationToken); await leaser.RequestStream.WriteAsync(request); await leaser.RequestStream.CompleteAsync(); await leaserTask; } }); }
/// <summary> /// LeaseKeepAlive keeps the lease alive by streaming keep alive requests from the client /// to the server and streaming keep alive responses from the server to the client. /// </summary> /// <param name="request"></param> /// <param name="method"></param> /// <param name="token"></param> public async void LeaseKeepAlive(LeaseKeepAliveRequest request, Action <LeaseKeepAliveResponse> method, CancellationToken token) { try { using (AsyncDuplexStreamingCall <LeaseKeepAliveRequest, LeaseKeepAliveResponse> leaser = _leaseClient.LeaseKeepAlive(_headers)) { Task leaserTask = Task.Run(async() => { while (await leaser.ResponseStream.MoveNext(token)) { LeaseKeepAliveResponse update = leaser.ResponseStream.Current; method(update); } }); await leaser.RequestStream.WriteAsync(request); await leaser.RequestStream.CompleteAsync(); await leaserTask; } } catch (RpcException ex) when(ex.Status.Equals(StatusCode.Unavailable)) { // If connection issue, then re-initate the LeaseKeepAlive request ResetConnection(ex); LeaseKeepAlive(request, method, token); } catch { throw; } }
public void LeaseKeepAlive(long leaseid) { var request = new LeaseKeepAliveRequest() { ID = leaseid }; var req = request.ToProto(); var rsp = client.LeaseKeepAlive(req, new Action <Etcdserverpb.LeaseKeepAliveResponse>(p => { }), CancellationToken.None); }
/// <summary> /// LeaseKeepAlive keeps the lease alive by streaming keep alive requests from the client /// to the server and streaming keep alive responses from the server to the client. /// </summary> /// <param name="leaseId"></param> /// <param name="cancellationToken"></param> public async Task LeaseKeepAlive(long leaseId, CancellationToken cancellationToken) { int retryCount = 0; while (true) { try { using (AsyncDuplexStreamingCall <LeaseKeepAliveRequest, LeaseKeepAliveResponse> leaser = _balancer.GetConnection().leaseClient.LeaseKeepAlive(cancellationToken: cancellationToken)) { LeaseKeepAliveRequest request = new LeaseKeepAliveRequest { ID = leaseId }; while (true) { cancellationToken.ThrowIfCancellationRequested(); await leaser.RequestStream.WriteAsync(request); if (!await leaser.ResponseStream.MoveNext(cancellationToken)) { await leaser.RequestStream.CompleteAsync(); throw new EndOfStreamException(); } LeaseKeepAliveResponse update = leaser.ResponseStream.Current; if (update.ID != leaseId || update.TTL == 0) // expired { await leaser.RequestStream.CompleteAsync(); return; } await Task.Delay(TimeSpan.FromMilliseconds(update.TTL * 1000 / 3), cancellationToken); } } } catch (RpcException ex) when(ex.StatusCode == StatusCode.Unavailable) { retryCount++; if (retryCount >= _balancer._numNodes) { throw; } } } }
static async Task TestMemLeakAsync() { var channel = new Channel("192.168.2.13", 2379, ChannelCredentials.Insecure); var leaseClient = new Lease.LeaseClient(channel); Console.WriteLine("Start"); Console.ReadLine(); for (int i = 0; i < 100; i++) { var leaseGrantReq = new LeaseGrantRequest() { TTL = 100, }; var leaseGrantRes = await leaseClient.LeaseGrantAsync(leaseGrantReq, cancellationToken : channel.ShutdownToken); using (var leaser = leaseClient.LeaseKeepAlive(cancellationToken: channel.ShutdownToken)) { var leaseKeepAliveReq = new LeaseKeepAliveRequest() { ID = leaseGrantRes.ID }; await leaser.RequestStream.WriteAsync(leaseKeepAliveReq); await leaser.RequestStream.CompleteAsync(); while (await leaser.ResponseStream.MoveNext(channel.ShutdownToken)) { var leaseKeepAliveRes = leaser.ResponseStream.Current; if (leaseKeepAliveRes.ID == leaseKeepAliveReq.ID) { break; } } } } Console.WriteLine("Done"); Console.ReadLine(); GC.Collect(); Console.WriteLine("GC"); Console.ReadLine(); await channel.ShutdownAsync(); }
/// <summary> /// LeaseKeepAlive keeps the lease alive by streaming keep alive requests from the client /// to the server and streaming keep alive responses from the server to the client. /// </summary> /// <param name="request">The request to send to the server.</param> /// <param name="methods"></param> /// <param name="cancellationToken"></param> /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param> public async Task LeaseKeepAlive(LeaseKeepAliveRequest request, Action <LeaseKeepAliveResponse>[] methods, CancellationToken cancellationToken, Grpc.Core.Metadata headers = null) { bool success = false; int retryCount = 0; while (!success) { try { using (AsyncDuplexStreamingCall <LeaseKeepAliveRequest, LeaseKeepAliveResponse> leaser = _balancer.GetConnection().leaseClient .LeaseKeepAlive(headers, cancellationToken: cancellationToken)) { Task leaserTask = Task.Run(async() => { while (await leaser.ResponseStream.MoveNext(cancellationToken)) { LeaseKeepAliveResponse update = leaser.ResponseStream.Current; foreach (Action <LeaseKeepAliveResponse> method in methods) { method(update); } } }, cancellationToken); await leaser.RequestStream.WriteAsync(request); await leaser.RequestStream.CompleteAsync(); await leaserTask; } success = true; } catch (RpcException ex) when(ex.StatusCode == StatusCode.Unavailable) { retryCount++; if (retryCount >= _balancer._numNodes) { throw; } } } }
/// <summary> /// LeaseKeepAlive keeps the lease alive by streaming keep alive requests from the client /// to the server and streaming keep alive responses from the server to the client. /// </summary> /// <param name="request"></param> /// <param name="method"></param> /// <param name="token"></param> public async void LeaseKeepAlive(LeaseKeepAliveRequest request, Action <LeaseKeepAliveResponse> method, CancellationToken token, Metadata headers = null) { using (AsyncDuplexStreamingCall <LeaseKeepAliveRequest, LeaseKeepAliveResponse> leaser = _balancer.GetConnection().leaseClient.LeaseKeepAlive(headers)) { Task leaserTask = Task.Run(async() => { while (await leaser.ResponseStream.MoveNext(token)) { LeaseKeepAliveResponse update = leaser.ResponseStream.Current; method(update); } }); await leaser.RequestStream.WriteAsync(request); await leaser.RequestStream.CompleteAsync(); await leaserTask; } }