/// <summary> /// Start to request only once but response many (one by one) /// </summary> /// <param name="next"></param> /// <returns></returns> public async Task StartServerStreamingCall(ulong next) { _next = Math.Max(next, ToBeIndexedInfoQueue.Last()?.Height ?? -1 + 1); try { var request = new RequestBlockInfo { ChainId = Hash.LoadHex(ChainConfig.Instance.ChainId), NextHeight = ToBeIndexedInfoQueue.Count == 0 ? _next : ToBeIndexedInfoQueue.Last().Height + 1 }; using (var call = Call(request)) { while (await call.ResponseStream.MoveNext()) { var response = call.ResponseStream.Current; // request failed or useless response if (!response.Success || response.Height != _next) { continue; } if (ToBeIndexedInfoQueue.TryAdd(response.BlockInfoResult)) { _next++; } } } } catch (RpcException e) { _logger.Error(e); throw; } }
/// <summary> /// Task to create request in loop. /// </summary> /// <param name="call"></param> /// <param name="cancellationToken"></param> /// <returns></returns> private async Task RequestLoop(AsyncDuplexStreamingCall <RequestBlockInfo, TResponse> call, CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { var request = new RequestBlockInfo { ChainId = Hash.LoadHex(ChainConfig.Instance.ChainId), NextHeight = ToBeIndexedInfoQueue.Count == 0 ? _next : ToBeIndexedInfoQueue.Last().Height + 1 }; //_logger.Trace($"New request for height {request.NextHeight} to chain {_targetChainId.DumpHex()}"); await call.RequestStream.WriteAsync(request); await Task.Delay(_realInterval); } }