Example #1
0
 public LightweightRpcFrame(
     RpcFrameType frameType, int messageNumber, string rpcOperation, RpcOperationFlags flags, uint timeout,
     IReadOnlyCollection <KeyValuePair <string, ImmutableArray <byte> > >?headers)
 {
     this.FrameType      = frameType;
     this.FrameLength    = null;
     this.RpcOperation   = rpcOperation;
     this.MessageNumber  = messageNumber;
     this.OperationFlags = flags;
     this.Timeout        = timeout;
     this.Payload        = ReadOnlySequence <byte> .Empty;
     this.Headers        = headers;
 }
Example #2
0
        internal LightweightRpcFrame(
            RpcFrameType frameType,
            int frameLength,
            int messageNumber)
        {
            this.FrameType     = frameType;
            this.FrameLength   = frameLength;
            this.RpcOperation  = "";
            this.MessageNumber = messageNumber;
            this.Payload       = ReadOnlySequence <byte> .Empty;
            this.Headers       = null;

            this.OperationFlags = 0;
            this.Timeout        = 0;
        }
Example #3
0
#pragma warning disable CA2000 // Dispose objects before losing scope
        public IAsyncStreamingServerCall <TResponse> BeginStreamingServerCall <TRequest, TResponse>(
            RpcFrameType frameType,
            string operation,
            RpcRequestContext?context,
            TRequest request,
            LightweightSerializers <TRequest, TResponse> serializers,
            int callTimeout)
            where TRequest : class
            where TResponse : class
        {
            var streamingCall = new AsyncStreamingServerCall <TResponse>(serializers.Serializer, serializers.ResponseSerializer);
            int messageId     = this.AddAwaitingResponse(streamingCall);

            try
            {
                RpcOperationFlags flags = 0;
                var cancellationToken   = context != null ? context.CancellationToken : default;
                if (cancellationToken.CanBeCanceled)
                {
                    cancellationToken.Register(() => this.CancelCall(messageId, operation));
                    flags |= RpcOperationFlags.CanCancel;
                }

                if (callTimeout > 0 && !RpcProxyOptions.RoundTripCancellationsAndTimeouts)
                {
                    Task.Delay(callTimeout)
                    .ContinueWith(t =>
                                  this.TimeoutCall(messageId, operation, callTimeout), cancellationToken, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default)
                    .Forget();
                }

                var frame = new LightweightRpcFrame(frameType, messageId, operation, flags, (uint)callTimeout, context?.Headers);

                var writeState = this.BeginWrite(frame);
                this.WriteRequest(request, serializers.RequestSerializer, writeState);

                return(streamingCall);
            }
            catch (Exception e)
            {
                this.HandleCallError(messageId, e);
                streamingCall.DisposeAsync().Forget();
                throw;
            }
        }
Example #4
0
 public LightweightRpcFrame(
     RpcFrameType frameType,
     int?frameLength,
     int messageNumber, string rpcOperation, RpcOperationFlags flags, uint timeout,
     in ReadOnlySequence <byte> payload,
Example #5
0
        internal Task <TResponse> SendReceiveFrameAsync <TRequest, TResponse>(
            RpcFrameType frameType,
            string operation,
            RpcRequestContext?context,
            TRequest request,
            LightweightSerializers <TRequest, TResponse> serializers,
            int timeout)
            where TRequest : class
        {
            if (TraceEnabled)
            {
                // TODO: Logger.Trace("Begin SendReceiveFrameAsync {Operation}.", operation);
            }

            var tcs = new ResponseCompletionSource <TResponse>(serializers.Serializer, serializers.ResponseSerializer);

            int messageId = this.AddAwaitingResponse(tcs);

            try
            {
                RpcOperationFlags flags = 0;

                var cancellationToken = context != null ? context.CancellationToken : default;
                if (cancellationToken.CanBeCanceled)
                {
                    cancellationToken.Register(() => this.CancelCall(messageId, operation));
                    flags |= RpcOperationFlags.CanCancel;
                }

                var frame = new LightweightRpcFrame(frameType, messageId, operation, flags, (uint)timeout, context?.Headers);

                var writeState = this.BeginWrite(frame);

                var writeTask = this.WriteRequestAsync(request, serializers.RequestSerializer, writeState);
                if (writeTask.IsCompletedSuccessfully)
                {
                    if (timeout == 0 || RpcProxyOptions.RoundTripCancellationsAndTimeouts)
                    {
                        return(tcs.Task);
                    }
                    else
                    {
                        return(AwaitTimeoutResponse(tcs.Task, operation, timeout));
                    }
                }
                else
                {
                    return(AwaitWrite(writeTask, tcs.Task));
                }
            }
            catch (Exception ex)
            {
                this.HandleCallError(messageId, ex);
                throw;
            }

            async Task <TResponse> AwaitTimeoutResponse(Task <TResponse> responseTask, string operation, int timeout)
            {
                var completedTask = await Task.WhenAny(responseTask, Task.Delay(timeout)).ContextFree();

                if (completedTask == responseTask)
                {
                    return(responseTask.AwaiterResult());
                }
                else
                {
                    throw new TimeoutException($"Operation '{operation}' didn't complete within the timeout ({timeout} ms).");
                }
            }

            async Task <TResponse> AwaitWrite(ValueTask writeTask, Task <TResponse> responseTask)
            {
                await writeTask.ContextFree();

                if (timeout == 0 || RpcProxyOptions.RoundTripCancellationsAndTimeouts)
                {
                    return(await responseTask.ContextFree());
                }
                else
                {
                    return(await AwaitTimeoutResponse(responseTask, operation, timeout).ContextFree());
                }
            }
        }