internal static void TraceFrame(Communicator communicator, ReadOnlySpan <byte> header, IncomingResponseFrame frame) => TraceResponse( "received response", communicator, header[8], // Message Type header[9], // Compression Status InputStream.ReadInt(header.Slice(10, 4)), // Request size InputStream.ReadInt(header.Slice(14, 4)), // Request-Id, frame.ReplyStatus, frame.Encoding);
internal static void TraceCollocatedFrame(Communicator communicator, byte messageType, int requestId, IncomingResponseFrame frame) => TraceResponse( "received response", communicator, messageType, 0, frame.Size + Ice1Definitions.HeaderSize + 4, requestId, frame.ReplyStatus, frame.Encoding);
internal static void TraceFrame( Communicator communicator, ReadOnlySpan <byte> header, IncomingResponseFrame frame) => TraceResponse( "received response", communicator, frame.Protocol, header[8], // Frame type header[9], // Compression Status InputStream.ReadFixedLengthSize(frame.Protocol.GetEncoding(), header.Slice(10, 4)), // Request size InputStream.ReadInt(header.Slice(14, 4)), // Request-Id, frame.ReplyStatus, frame.Encoding);
/// <summary>Forwards an incoming request to another Ice object.</summary> /// <param name="proxy">The proxy for the target Ice object.</param> /// <param name="oneway">When true, the request is sent as a oneway request. When false, it is sent as a /// two-way request.</param> /// <param name="request">The incoming request frame.</param> /// <param name="progress">Sent progress provider.</param> /// <param name="cancel">A cancellation token that receives the cancellation requests.</param> /// <returns>A task holding the response frame.</returns> public static async ValueTask <OutgoingResponseFrame> ForwardAsync(this IObjectPrx proxy, bool oneway, IncomingRequestFrame request, IProgress <bool>?progress = null, CancellationToken cancel = default) { var forwardedRequest = new OutgoingRequestFrame(proxy, request.Operation, request.IsIdempotent, request.Context, request.Payload); IncomingResponseFrame response = await proxy.InvokeAsync(forwardedRequest, oneway : oneway, progress, cancel) .ConfigureAwait(false); return(new OutgoingResponseFrame(request.Encoding, response.Payload)); }
internal async virtual ValueTask <IncomingResponseFrame> ReceiveResponseFrameAsync(CancellationToken cancel) { ArraySegment <byte> data; try { byte frameType = _socket.Endpoint.Protocol == Protocol.Ice1 ? (byte)Ice1FrameType.Reply : (byte)Ice2FrameType.Response; data = await ReceiveFrameAsync(frameType, cancel).ConfigureAwait(false); } catch (OperationCanceledException) { if (_socket.Endpoint.Protocol != Protocol.Ice1) { await ResetAsync((long)StreamResetErrorCode.RequestCanceled).ConfigureAwait(false); } throw; } IncomingResponseFrame response; if (ReceivedEndOfStream) { response = new IncomingResponseFrame(_socket.Endpoint.Protocol, data, _socket.IncomingFrameMaxSize, null); } else { // Increment the use count of this stream to ensure it's not going to be disposed before the // stream parameter data is disposed. Interlocked.Increment(ref UseCount); response = new IncomingResponseFrame(_socket.Endpoint.Protocol, data, _socket.IncomingFrameMaxSize, this); } if (_socket.Endpoint.Communicator.TraceLevels.Protocol >= 1) { TraceFrame(response); } return(response); }
/// <summary>Forwards an incoming request to another Ice object represented by the <paramref name="proxy"/> /// parameter.</summary> /// <remarks>When the incoming request frame's protocol and proxy's protocol are different, this method /// automatically bridges between these two protocols. When proxy's protocol is ice1, the resulting outgoing /// request frame is never compressed.</remarks> /// <param name="proxy">The proxy for the target Ice object.</param> /// <param name="request">The incoming request frame to forward to proxy's target.</param> /// <param name="oneway">When true, the request is sent as a oneway request. When false, it is sent as a /// two-way request.</param> /// <param name="progress">Sent progress provider.</param> /// <param name="cancel">A cancellation token that receives the cancellation requests.</param> /// <returns>A task holding the response frame.</returns> public static async ValueTask <OutgoingResponseFrame> ForwardAsync( this IObjectPrx proxy, IncomingRequestFrame request, bool oneway, IProgress <bool>?progress = null, CancellationToken cancel = default) { var forwardedRequest = new OutgoingRequestFrame(proxy, request, cancel: cancel); try { // TODO: add support for stream data forwarding. using IncomingResponseFrame response = await Reference.InvokeAsync(proxy, forwardedRequest, oneway, progress).ConfigureAwait(false); return(new OutgoingResponseFrame(request, response)); } catch (LimitExceededException exception) { return(new OutgoingResponseFrame(request, new ServerException(exception.Message, exception))); } }
public async Task <IncomingResponseFrame> SendRequestAsync( OutgoingRequestFrame outgoingRequest, bool oneway, bool synchronous, IInvocationObserver?observer, IProgress <bool> progress, CancellationToken cancel) { cancel.ThrowIfCancellationRequested(); IChildInvocationObserver?childObserver = null; int requestId = 0; // The CollocatedRequestHandler is an internal object so it's safe to lock (this) as long as our // code doesn't use the collocated request handler as a lock. The lock here is useful to ensure // the protocol trace and observer call is output or called in the same order as the request ID // is allocated. lock (_mutex) { if (!oneway) { requestId = ++_requestId; } if (observer != null) { childObserver = observer.GetCollocatedObserver(_adapter, requestId, outgoingRequest.Size); childObserver?.Attach(); } if (_adapter.Communicator.TraceLevels.Protocol >= 1) { ProtocolTrace.TraceFrame(_adapter.Communicator, requestId, outgoingRequest); } } Task <OutgoingResponseFrame> task; if (_adapter.TaskScheduler != null || !synchronous || oneway || cancel != CancellationToken.None) { // Don't invoke from the user thread if async or cancellation token is set. We also don't dispatch // oneway from the user thread to match the non-collocated behavior where the oneway synchronous // request returns as soon as it's sent over the transport. task = Task.Factory.StartNew(() => { progress.Report(false); return(DispatchAsync(outgoingRequest, requestId, cancel)); }, cancel, TaskCreationOptions.None, _adapter.TaskScheduler ?? TaskScheduler.Default).Unwrap(); if (oneway) { childObserver?.Detach(); return(IncomingResponseFrame.WithVoidReturnValue(outgoingRequest.Protocol, outgoingRequest.Encoding)); } } else // Optimization: directly call DispatchAsync { progress.Report(false); task = DispatchAsync(outgoingRequest, requestId, cancel); } Debug.Assert(!oneway); try { OutgoingResponseFrame outgoingResponseFrame = await task.WaitAsync(cancel).ConfigureAwait(false); var incomingResponse = new IncomingResponseFrame( outgoingRequest.Protocol, outgoingResponseFrame.Data.AsArraySegment(), _adapter.IncomingFrameSizeMax); if (_adapter.Communicator.TraceLevels.Protocol >= 1) { ProtocolTrace.TraceFrame(_adapter.Communicator, requestId, incomingResponse); } childObserver?.Reply(incomingResponse.Size); return(incomingResponse); } catch (Exception ex) { childObserver?.Failed(ex.GetType().FullName ?? "System.Exception"); throw; } finally { childObserver?.Detach(); } }
public virtual bool Response(IncomingResponseFrame responseFrame) { Debug.Assert(false); // Must be overridden by request that can handle responses return(false); }
/// <summary>The <see cref="ResponseReader{T}"/> reader for the return type of operation ice_isA. /// </summary> public static bool IceIsA(IObjectPrx proxy, IncomingResponseFrame response) => response.ReadReturnValue(proxy, InputStream.IceReaderIntoBool);
/// <summary>The <see cref="ResponseReader{T}"/> reader for the return type of operation ice_ids. /// </summary> public static string[] IceIds(IObjectPrx proxy, IncomingResponseFrame response) => response.ReadReturnValue( proxy, istr => istr.ReadArray(minElementSize: 1, InputStream.IceReaderIntoString));
/// <summary>The <see cref="ResponseReader{T}"/> reader for the return type of operation ice_id. /// </summary> public static string IceId(IObjectPrx proxy, IncomingResponseFrame response) => response.ReadReturnValue(proxy, InputStream.IceReaderIntoString);