Exemplo n.º 1
0
        public async Task <CopyResult> Write(Stream stream, string name = null, CancellationToken ct = default(CancellationToken))
        {
            if (stream is null)
            {
                throw new ArgumentNullException(nameof(stream));
            }
            if (!stream.CanRead)
            {
                throw new InvalidOperationException();
            }

            WriteRequest request = new WriteRequest()
            {
                FileName = name
            };

            CopyResult result = new CopyResult()
            {
                FileName = name
            };

            try
            {
                Metadata requestHeaders = request.ToMetadata();

                // Create a CancellationTokenSource we will use to cancel on time-outs
                // and to transmit any cancellation to server.
                using (CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(ct))
                {
                    CallOptions options = default(CallOptions).WithHeaders(requestHeaders).WithCancellationToken(cts.Token);

                    AsyncClientStreamingCall <Chunk, WriteReply> call;
                    Stopwatch responseTimer = Stopwatch.StartNew();
                    try
                    {
                        call = client.Write(options);
                        //responseHeaders = await call.ResponseHeadersAsync.ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        // TODO: Also handle timeout
                        result.Status       = CopyResultStatus.ConnectionFailure;
                        result.ErrorType    = e.GetType().Name;
                        result.ErrorMessage = e.Message;
                        return(result);
                    }
                    finally
                    {
                        responseTimer.Stop();
                        result.ResponseTime = responseTimer.Elapsed;
                    }

                    byte[] buffer = new byte[CopyConstants.BufferSize];
                    GrpcContentStreamer streamer = new GrpcContentStreamer(govener);

                    Stopwatch streamingTimer = Stopwatch.StartNew();
                    try
                    {
                        await streamer.WriteContent(stream, buffer, call.RequestStream, ct).ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        result.ErrorType    = e.GetType().Name;
                        result.ErrorMessage = e.Message;
                        if (e is TimeoutException)
                        {
                            result.Status = CopyResultStatus.StreamingTimeout;
                        }
                        else
                        {
                            result.Status = CopyResultStatus.StreamingFailure;
                        }
                        return(result);
                    }
                    finally
                    {
                        streamingTimer.Stop();
                        result.BytesStreamed = streamer.Bytes;
                        result.StreamingTime = streamingTimer.Elapsed;
                    }

                    // gRPC requires client to explicitly declare end-of-stream
                    await call.RequestStream.CompleteAsync().ConfigureAwait(false);

                    WriteReply reply = await call.ResponseAsync;
                    result.FileName = reply.FileName;
                }

                return(result);
            }
            catch (Exception e)
            {
                result.Status       = CopyResultStatus.OtherClientSideError;
                result.ErrorType    = e.GetType().Name;
                result.ErrorMessage = e.Message;
                return(result);
            }
        }