private async Task <BoolResult> StreamContentAsync(IAsyncStreamReader <CopyFileResponse> input, Stream output, CopyOptions?options, CancellationToken cancellationToken) { try { await GrpcExtensions.CopyChunksToStreamAsync( input, output, response => { if (response.Header != null) { var error = new ErrorResult(response.Header.ErrorMessage ?? "Unknown error", response.Header.Diagnostics); error.ThrowIfFailure(); } return(response.Content); }, totalBytes => options?.UpdateTotalBytesCopied(totalBytes), cancellationToken); return(BoolResult.Success); } catch (ResultPropagationException e) { return(new BoolResult(e.Result)); } }
private async Task <BoolResult> StreamContentWithCompressionAsync(IAsyncStreamReader <CopyFileResponse> input, Stream output, CopyOptions?options, CancellationToken cancellationToken) { try { long chunks = 0L; long bytes = 0L; using (var grpcStream = new BufferedReadStream( async() => { if (await input.MoveNext(cancellationToken)) { if (input.Current.Header is { } header) { var error = new ErrorResult(header.ErrorMessage ?? "Unknown error", header.Diagnostics); error.ThrowIfFailure(); } chunks++; bytes += input.Current.Content.Length; options?.UpdateTotalBytesCopied(bytes); return(input.Current.Content); } else { return(null); } })) { using (Stream decompressedStream = new GZipStream(grpcStream, CompressionMode.Decompress, true)) { await decompressedStream.CopyToAsync(output, _configuration.ClientBufferSizeBytes, cancellationToken); } } return(BoolResult.Success); } catch (ResultPropagationException e) { return(new BoolResult(e.Result)); } }
/// <summary> /// Tracks a latency of a server's response and throws an exception if <paramref name="responseHeader"/>'s Success property returns false. /// </summary> private void TrackLatencyAndThrowIfFailure(DateTime startTime, ResponseHeader responseHeader, bool throwFailures) { Contract.Assert(responseHeader != null); var serverTicks = responseHeader.ServerReceiptTimeUtcTicks; if (serverTicks > 0 && serverTicks > startTime.Ticks) { // It make no sense to trace negative numbers. // It is possible that the time on different machines is different and the server time is less then the local one. long ticksWaited = serverTicks - startTime.Ticks; ServiceClientTracer.TrackClientWaitForServerTicks(ticksWaited); } if (!responseHeader.Succeeded && throwFailures) { var errorResult = new ErrorResult(responseHeader.ErrorMessage, responseHeader.Diagnostics); // This method will throw ResultPropagationException that is tracked by the PerformSessionOperationAsync errorResult.ThrowIfFailure(); } }