internal async virtual ValueTask <IncomingRequestFrame> ReceiveRequestFrameAsync(CancellationToken cancel) { byte frameType = _socket.Endpoint.Protocol == Protocol.Ice1 ? (byte)Ice1FrameType.Request : (byte)Ice2FrameType.Request; ArraySegment <byte> data = await ReceiveFrameAsync(frameType, cancel).ConfigureAwait(false); IncomingRequestFrame request; if (ReceivedEndOfStream) { request = new IncomingRequestFrame(_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); request = new IncomingRequestFrame(_socket.Endpoint.Protocol, data, _socket.IncomingFrameMaxSize, this); } if (_socket.Endpoint.Communicator.TraceLevels.Protocol >= 1) { _socket.TraceFrame(Id, request); } return(request); }
static async ValueTask <OutgoingResponseFrame> WaitResponseAsync(IncomingRequestFrame request, ValueTask <IncomingResponseFrame> task) { IncomingResponseFrame response = await task.ConfigureAwait(false); return(new OutgoingResponseFrame(request.Encoding, response.Payload)); }
internal Current( ObjectAdapter adapter, IncomingRequestFrame incomingRequestFrame, bool oneway, Connection?connection = null) { Adapter = adapter; Connection = connection; IsOneway = oneway; IncomingRequestFrame = incomingRequestFrame; }
internal Current( ObjectAdapter adapter, IncomingRequestFrame incomingRequestFrame, SocketStream stream, Connection connection) { Adapter = adapter; Connection = connection; IncomingRequestFrame = incomingRequestFrame; Stream = stream; }
/// <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 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); ValueTask <IncomingResponseFrame> task = proxy.InvokeAsync(forwardedRequest, oneway: oneway, progress, cancel); return(WaitResponseAsync(request, task));
internal Current(ObjectAdapter adapter, IncomingRequestFrame request, int requestId, Connection?connection = null) { Adapter = adapter; Connection = connection; Context = new Dictionary <string, string>(request.Context); Encoding = request.Encoding; Facet = request.Facet; Identity = request.Identity; IsIdempotent = request.IsIdempotent; Operation = request.Operation; RequestId = requestId; }
internal Current( ObjectAdapter adapter, IncomingRequestFrame incomingRequestFrame, SocketStream stream, bool endOfStream, Connection connection) { Adapter = adapter; Connection = connection; EndOfStream = endOfStream; IsOneway = !stream.IsBidirectional; IncomingRequestFrame = incomingRequestFrame; Stream = stream; }
/// <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 Current( ObjectAdapter adapter, IncomingRequestFrame incomingRequestFrame, bool oneway, CancellationToken cancel, Connection? connection = null) { Adapter = adapter; CancellationToken = cancel; Connection = connection; Context = new Dictionary<string, string>(incomingRequestFrame.Context); IsOneway = oneway; IncomingRequestFrame = incomingRequestFrame; }
internal static void TraceFrame(Communicator communicator, ReadOnlySpan <byte> header, IncomingRequestFrame frame) => TraceRequest( "received request", 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.Identity, frame.Facet, frame.Operation, frame.IsIdempotent, frame.Context, frame.Encoding);
internal static void TraceFrame( Communicator communicator, ReadOnlySpan <byte> header, IncomingRequestFrame frame) => TraceRequest( "received request", communicator, frame.Protocol, header[8], // Frame type header[9], // Compression Status header.Slice(10, 4).ReadFixedLengthSize(frame.Protocol.GetEncoding()), // Request size header.Slice(14, 4).ReadInt(), // Request-Id, frame.Identity, frame.Facet, frame.Operation, frame.IsIdempotent, frame.Context, frame.Encoding);
internal async ValueTask <(IncomingRequestFrame, bool)> ReceiveRequestFrameAsync(CancellationToken cancel) { byte frameType = _socket.Endpoint.Protocol == Protocol.Ice1 ? (byte)Ice1Definitions.FrameType.Request : (byte)Ice2Definitions.FrameType.Request; (ArraySegment <byte> data, bool fin) = await ReceiveFrameAsync(frameType, cancel).ConfigureAwait(false); var request = new IncomingRequestFrame(_socket.Endpoint.Protocol, data, _socket.IncomingFrameMaxSize); if (_socket.Endpoint.Communicator.TraceLevels.Protocol >= 1) { _socket.TraceFrame(Id, request); } return(request, fin); }
private async Task <OutgoingResponseFrame> DispatchAsync( OutgoingRequestFrame outgoingRequest, int requestId, CancellationToken cancel) { // Increase the direct count to prevent the object adapter from being destroyed while the dispatch is in // progress. This will also throw if the object adapter has been deactivated. _adapter.IncDirectCount(); try { var incomingRequest = new IncomingRequestFrame(outgoingRequest, _adapter.IncomingFrameSizeMax); var current = new Current(_adapter, incomingRequest, oneway: requestId == 0, cancel); return(await _adapter.DispatchAsync(incomingRequest, requestId, current).ConfigureAwait(false)); } finally { _adapter.DecDirectCount(); } }
internal Current( ObjectAdapter adapter, IncomingRequestFrame request, bool oneway, CancellationToken cancel, Connection?connection = null) { Adapter = adapter; CancellationToken = cancel; Connection = connection; Context = new Dictionary <string, string>(request.Context); Encoding = request.Encoding; Facet = request.Facet; Identity = request.Identity; IsIdempotent = request.IsIdempotent; IsOneway = oneway; Operation = request.Operation; Protocol = request.Protocol; }
/// <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))); } }
private async Task <OutgoingResponseFrame> DispatchAsync( OutgoingRequestFrame outgoingRequest, int requestId, CancellationToken cancel) { // Increase the direct count to prevent the object adapter from being destroyed while the dispatch is in // progress. This will also throw if the object adapter has been deactivated. _adapter.IncDirectCount(); IDispatchObserver?dispatchObserver = null; try { var incomingRequest = new IncomingRequestFrame(outgoingRequest, _adapter.IncomingFrameSizeMax); var current = new Current(_adapter, incomingRequest, oneway: requestId == 0, cancel); // Then notify and set dispatch observer, if any. ICommunicatorObserver?communicatorObserver = _adapter.Communicator.Observer; if (communicatorObserver != null) { dispatchObserver = communicatorObserver.GetDispatchObserver(current, requestId, incomingRequest.Size); dispatchObserver?.Attach(); } OutgoingResponseFrame?outgoingResponseFrame = null; try { IObject?servant = current.Adapter.Find(current.Identity, current.Facet); if (servant == null) { throw new ObjectNotExistException(current.Identity, current.Facet, current.Operation); } ValueTask <OutgoingResponseFrame> vt = servant.DispatchAsync(incomingRequest, current); if (requestId != 0) { // We don't use the cancelable WaitAsync for the await here. The asynchronous dispatch is // not completed yet and we want to make sure the observer is detached only when the dispatch // completes, not when the caller cancels the request. outgoingResponseFrame = await vt.ConfigureAwait(false); outgoingResponseFrame.Finish(); dispatchObserver?.Reply(outgoingResponseFrame.Size); } } catch (Exception ex) { RemoteException actualEx; if (ex is RemoteException remoteEx && !remoteEx.ConvertToUnhandled) { actualEx = remoteEx; } else { actualEx = new UnhandledException(current.Identity, current.Facet, current.Operation, ex); } Incoming.ReportException(actualEx, dispatchObserver, current); if (requestId != 0) { outgoingResponseFrame = new OutgoingResponseFrame(incomingRequest, actualEx); outgoingResponseFrame.Finish(); dispatchObserver?.Reply(outgoingResponseFrame.Size); } }