Example #1
0
 public ValueTask <Task <IncomingResponseFrame>?> SendRequestAsync(
     OutgoingRequestFrame outgoingRequestFrame,
     bool oneway,
     bool synchronous,
     IInvocationObserver?observer,
     CancellationToken cancel) =>
 _connection.SendRequestAsync(outgoingRequestFrame, oneway, _compress, synchronous, observer, cancel);
Example #2
0
        public ValueTask <Task <IncomingResponseFrame>?> SendRequestAsync(
            OutgoingRequestFrame outgoingRequestFrame,
            bool oneway,
            bool synchronous,
            IInvocationObserver?observer,
            CancellationToken cancel)
        {
            cancel.ThrowIfCancellationRequested();

            //
            // Increase the direct count to prevent the thread pool from being destroyed before
            // invokeAll is called. This will also throw if the object adapter has been deactivated.
            //
            _adapter.IncDirectCount();

            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, outgoingRequestFrame.Size);
                    childObserver?.Attach();
                }

                if (_adapter.Communicator.TraceLevels.Protocol >= 1)
                {
                    ProtocolTrace.TraceCollocatedFrame(_adapter.Communicator,
                                                       (byte)Ice1Definitions.FrameType.Request,
                                                       requestId,
                                                       outgoingRequestFrame);
                }
            }

            Task <IncomingResponseFrame?> task;

            if (_adapter.TaskScheduler != null || !synchronous || oneway || _reference.InvocationTimeout > 0)
            {
                // Don't invoke from the user thread if async or invocation timeout 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(() => InvokeAllAsync(outgoingRequestFrame, requestId, cancel),
                                             cancel,
                                             TaskCreationOptions.None,
                                             _adapter.TaskScheduler ?? TaskScheduler.Default).Unwrap();

                if (oneway)
                {
                    childObserver?.Detach();
                    return(default);
        /// <summary>Creates a new <see cref="OutgoingRequestFrame"/> for an operation with a single non-struct
        /// parameter.</summary>
        /// <typeparam name="T">The type of the operation's parameter.</typeparam>
        /// <param name="proxy">A proxy to the target Ice object. This method uses the communicator, identity, facet,
        /// encoding and context of this proxy to create the request frame.</param>
        /// <param name="operation">The operation to invoke on the target Ice object.</param>
        /// <param name="idempotent">True when operation is idempotent, otherwise false.</param>
        /// <param name="compress">True if the request should be compressed, false otherwise.</param>
        /// <param name="format">The format to use when writing class instances in case <c>args</c> contains class
        /// instances.</param>
        /// <param name="context">An optional explicit context. When non null, it overrides both the context of the
        /// proxy and the communicator's current context (if any).</param>
        /// <param name="args">The argument(s) to write into the frame.</param>
        /// <param name="writer">The <see cref="OutputStreamWriter{T}"/> that writes the arguments into the frame.
        /// </param>
        /// <returns>A new OutgoingRequestFrame.</returns>
        public static OutgoingRequestFrame WithArgs <T>(
            IObjectPrx proxy,
            string operation,
            bool idempotent,
            bool compress,
            FormatType format,
            IReadOnlyDictionary <string, string>?context,
            T args,
            OutputStreamWriter <T> writer)
        {
            var request = new OutgoingRequestFrame(proxy, operation, idempotent, compress, context);
            var ostr    = new OutputStream(proxy.Protocol.GetEncoding(),
                                           request.Data,
                                           request.PayloadStart,
                                           request.Encoding,
                                           format);

            writer(ostr, args);
            request.PayloadEnd = ostr.Finish();
            if (compress && proxy.Encoding == Encoding.V20)
            {
                request.CompressPayload();
            }
            return(request);
        }
Example #4
0
 private protected Task <TReturnValue> InvokeAsync(IObjectPrx prx,
                                                   OutgoingRequestFrame request,
                                                   IProgress <bool>?progress,
                                                   CancellationToken cancel)
 {
     return(ReadReturnValueAsync(prx.InvokeAsync(request, oneway: false, progress, cancel),
                                 prx.Communicator,
                                 _reader));
Example #5
0
 public OutgoingAsync(IObjectPrx prx, IOutgoingAsyncCompletionCallback completionCallback,
                      OutgoingRequestFrame requestFrame, bool oneway = false)
     : base(prx, completionCallback, requestFrame)
 {
     Encoding     = Proxy.Encoding;
     Synchronous  = false;
     IsOneway     = oneway;
     IsIdempotent = requestFrame.IsIdempotent;
 }
Example #6
0
 protected ProxyOutgoingAsyncBase(IObjectPrx prx,
                                  IOutgoingAsyncCompletionCallback completionCallback,
                                  OutgoingRequestFrame requestFrame) :
     base(prx.Communicator, completionCallback)
 {
     Proxy        = prx;
     IsOneway     = false;
     _cnt         = 0;
     _sent        = false;
     RequestFrame = requestFrame;
 }
Example #7
0
        /// <summary>Sends a request asynchronously.</summary>
        /// <param name="proxy">The proxy for the target Ice object.</param>
        /// <param name="request">The outgoing request frame for this invocation. Usually this request frame should have
        /// been created using the same proxy, however some differences are acceptable, for example proxy can have
        /// different endpoints.</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 Task <IncomingResponseFrame> InvokeAsync(this IObjectPrx proxy,
                                                               OutgoingRequestFrame request,
                                                               bool oneway = false,
                                                               IProgress <bool>?progress = null,
                                                               CancellationToken cancel  = default)
        {
            var completed = new IObjectPrx.InvokeTaskCompletionCallback(progress, cancel);

            new OutgoingAsync(proxy, completed, request, oneway: oneway).Invoke(request.Operation, request.Context,
                                                                                synchronous: false);
            return(completed.Task);
        }
Example #8
0
        /// <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));
Example #9
0
 /// <summary>Sends a request synchronously.</summary>
 /// <param name="proxy">The proxy for the target Ice object.</param>
 /// <param name="request">The outgoing request frame for this invocation. Usually this request frame should have
 /// been created using the same proxy, however some differences are acceptable, for example proxy can have
 /// different endpoints.</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>
 /// <returns>The response frame.</returns>
 public static IncomingResponseFrame Invoke(this IObjectPrx proxy, OutgoingRequestFrame request,
                                            bool oneway = false)
 {
     try
     {
         return(InvokeAsync(proxy, request, oneway, synchronous: true).Result);
     }
     catch (AggregateException ex)
     {
         Debug.Assert(ex.InnerException != null);
         throw ex.InnerException;
     }
 }
Example #10
0
 /// <summary>Creates an <see cref="OutgoingRequestFrame"/> for operation ice_isA.</summary>
 /// <param name="proxy">Proxy to the target Ice Object.</param>
 /// <param name="id">The type ID argument to write into the request.</param>
 /// <param name="context">The context to write into the request.</param>
 /// <returns>A new <see cref="OutgoingRequestFrame"/>.</returns>
 public static OutgoingRequestFrame IceIsA(
     IObjectPrx proxy,
     string id,
     IReadOnlyDictionary <string, string>?context) =>
 OutgoingRequestFrame.WithArgs(
     proxy,
     "ice_isA",
     idempotent: true,
     compress: false,
     format: default,
     context,
     id,
     OutputStream.IceWriterFromString);
Example #11
0
        /// <summary>Create a new OutgoingRequestFrame.</summary>
        /// <param name="proxy">A proxy to the target Ice object. This method uses the communicator, identity, facet,
        /// encoding and context of this proxy to create the request frame.</param>
        /// <param name="operation">The operation to invoke on the target Ice object.</param>
        /// <param name="idempotent">True when operation is idempotent, otherwise false.</param>
        /// <param name="format">The format type used to marshal classes and exceptions, when this parameter is null
        /// the communicator's default format is used.</param>
        /// <param name="context">An optional explicit context. When non null, it overrides both the context of the
        /// proxy and the communicator's current context (if any).</param>
        /// <param name="value">The parameter to marshal in the frame.</param>
        /// <param name="writer">The delegate into marshal the parameter to the frame.</param>
        /// <returns>A new OutgoingRequestFrame</returns>
        public static OutgoingRequestFrame WithParamList <T>(
            IObjectPrx proxy, string operation, bool idempotent, FormatType?format,
            IReadOnlyDictionary <string, string>?context,
            T value, OutputStreamWriter <T> writer)
        {
            var request = new OutgoingRequestFrame(proxy, operation, idempotent, context);
            var ostr    = new OutputStream(proxy.Protocol.GetEncoding(), request.Data, request._payloadStart,
                                           request.Encoding, format ?? proxy.Communicator.DefaultFormat);

            writer(ostr, value);
            request.Finish(ostr.Save());
            return(request);
        }
Example #12
0
        /// <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));
        }
Example #13
0
 internal static void TraceFrame(Communicator communicator, ReadOnlySpan <byte> header,
                                 OutgoingRequestFrame frame) =>
 TraceRequest(
     "sending 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);
Example #14
0
 internal static void TraceCollocatedFrame(Communicator communicator, byte messageType, int requestId,
                                           OutgoingRequestFrame frame) =>
 TraceRequest(
     "sending request",
     communicator,
     messageType,
     0,
     frame.Size + Ice1Definitions.HeaderSize + 4,
     requestId,
     frame.Identity,
     frame.Facet,
     frame.Operation,
     frame.IsIdempotent,
     frame.Context,
     frame.Encoding);
Example #15
0
 /// <summary>Creates a new <see cref="OutgoingRequestFrame"/> for an operation with a single non-struct
 /// parameter.</summary>
 /// <typeparam name="T">The type of the operation's parameter.</typeparam>
 /// <param name="proxy">A proxy to the target Ice object. This method uses the communicator, identity, facet,
 /// encoding and context of this proxy to create the request frame.</param>
 /// <param name="operation">The operation to invoke on the target Ice object.</param>
 /// <param name="idempotent">True when operation is idempotent, otherwise false.</param>
 /// <param name="compress">True if the request should be compressed, false otherwise.</param>
 /// <param name="format">The format to use when writing class instances in case <c>args</c> contains class
 /// instances.</param>
 /// <param name="context">An optional explicit context. When non null, it overrides both the context of the
 /// proxy and the communicator's current context (if any).</param>
 /// <param name="args">The argument(s) to write into the frame.</param>
 /// <param name="writer">The <see cref="OutputStreamWriter{T}"/> that writes the arguments into the frame.
 /// </param>
 /// <param name="cancel">A cancellation token that receives the cancellation requests.</param>
 /// <returns>A new OutgoingRequestFrame.</returns>
 public static OutgoingRequestFrame WithArgs <T>(
     IObjectPrx proxy,
     string operation,
     bool idempotent,
     bool compress,
     FormatType format,
     IReadOnlyDictionary <string, string>?context,
     T args,
     OutputStreamWriter <T> writer,
     CancellationToken cancel = default)
 {
     var request = new OutgoingRequestFrame(proxy, operation, idempotent, compress, context, cancel);
     var ostr    = new OutputStream(proxy.Protocol.GetEncoding(),
                                    request.Payload,
                                    startAt: default,
Example #16
0
        internal static List <ArraySegment <byte> > GetRequestData(OutgoingRequestFrame frame, int requestId)
        {
            byte[] headerData = new byte[HeaderSize + 4];
            RequestHeader.CopyTo(headerData.AsSpan());

            OutputStream.WriteInt(frame.Size + HeaderSize + 4, headerData.AsSpan(10, 4));
            OutputStream.WriteInt(requestId, headerData.AsSpan(HeaderSize, 4));

            var data = new List <ArraySegment <byte> >()
            {
                headerData
            };

            data.AddRange(frame.Data);
            return(data);
        }
Example #17
0
 /// <summary>Sends a request synchronously.</summary>
 /// <param name="proxy">The proxy for the target Ice object.</param>
 /// <param name="request">The outgoing request frame for this invocation. Usually this request frame should have
 /// been created using the same proxy, however some differences are acceptable, for example proxy can have
 /// different endpoints.</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>
 /// <returns>The response frame.</returns>
 public static IncomingResponseFrame Invoke(this IObjectPrx proxy, OutgoingRequestFrame request,
                                            bool oneway = false)
 {
     try
     {
         var completed = new IObjectPrx.InvokeTaskCompletionCallback(null, default);
         new OutgoingAsync(proxy, completed, request, oneway: oneway).Invoke(request.Operation, request.Context,
                                                                             synchronous: true);
         return(completed.Task.Result);
     }
     catch (AggregateException ex)
     {
         Debug.Assert(ex.InnerException != null);
         throw ex.InnerException;
     }
 }
Example #18
0
        internal static List <ArraySegment <byte> > GetRequestData(OutgoingRequestFrame frame, long streamId)
        {
            byte[] headerData = new byte[HeaderSize + 4];
            RequestHeader.CopyTo(headerData.AsSpan());

            OutputStream.WriteSize20(frame.Size + HeaderSize + 4, headerData.AsSpan(10, 4));
            // TODO: Fix to support long streamId
            OutputStream.WriteInt((int)streamId, headerData.AsSpan(HeaderSize, 4));

            var data = new List <ArraySegment <byte> >()
            {
                headerData
            };

            data.AddRange(frame.Data);
            return(data);
        }
Example #19
0
 internal static void TraceFrame(
     Communicator communicator,
     ReadOnlySpan <byte> header,
     OutgoingRequestFrame frame) =>
 TraceRequest(
     "sending 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);
Example #20
0
 internal static void TraceCollocatedFrame(
     Communicator communicator,
     byte frameType,
     int requestId,
     OutgoingRequestFrame frame) =>
 TraceRequest(
     "sending request",
     communicator,
     frame.Protocol,
     frameType,
     0,
     frame.Size + Ice1Definitions.HeaderSize + 4,     // TODO: where is this size coming from?
     requestId,
     frame.Identity,
     frame.Facet,
     frame.Operation,
     frame.IsIdempotent,
     frame.Context,
     frame.Encoding);
Example #21
0
 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();
     }
 }
Example #22
0
        /// <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)));
            }
        }
Example #23
0
 /// <summary>Creates an <see cref="OutgoingRequestFrame"/> for operation ice_ids.</summary>
 /// <param name="proxy">Proxy to the target Ice Object.</param>
 /// <param name="context">The context to write into the request.</param>
 /// <returns>A new <see cref="OutgoingRequestFrame"/>.</returns>
 public static OutgoingRequestFrame IceIds(IObjectPrx proxy, IReadOnlyDictionary <string, string>?context) =>
 OutgoingRequestFrame.WithEmptyArgs(proxy, "ice_ids", idempotent: true, context);
Example #24
0
 // TODO avoid copy payload (ToArray) creates a copy, that should be possible when
 // the frame has a single segment.
 internal IncomingRequestFrame(OutgoingRequestFrame frame)
     : this(frame.Protocol, VectoredBufferExtensions.ToArray(frame.Data))
 {
 }
Example #25
0
 /// <summary>Invokes a request on a proxy.</summary>
 /// <remarks>request.CancellationToken holds the cancellation token.</remarks>
 /// <param name="proxy">The proxy for the target Ice object.</param>
 /// <param name="request">The request frame.</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>
 /// <returns>A task holding the response frame.</returns>
 public static Task <IncomingResponseFrame> InvokeAsync(
     this IObjectPrx proxy,
     OutgoingRequestFrame request,
     bool oneway = false,
     IProgress <bool>?progress = null) =>
 Reference.InvokeAsync(proxy, request, oneway, progress);
Example #26
0
        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();
            }
        }
Example #27
0
 internal IncomingRequestFrame(OutgoingRequestFrame frame, int sizeMax)
     : this(frame.Protocol, frame.Data.AsArraySegment(), sizeMax)
 {
 }
Example #28
0
        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);
                    }
                }
Example #29
0
 /// <summary>Creates an <see cref="OutgoingRequestFrame"/> for operation ice_ping.</summary>
 /// <param name="proxy">Proxy to the target Ice Object.</param>
 /// <param name="context">The context to write into the request.</param>
 /// <param name="cancel">A cancellation token that receives the cancellation requests.</param>
 /// <returns>A new <see cref="OutgoingRequestFrame"/>.</returns>
 public static OutgoingRequestFrame IcePing(
     IObjectPrx proxy,
     IReadOnlyDictionary <string, string>?context,
     CancellationToken cancel) =>
 OutgoingRequestFrame.WithEmptyArgs(proxy, "ice_ping", idempotent: true, context, cancel);
Example #30
0
 private protected TReturnValue Invoke(IObjectPrx prx, OutgoingRequestFrame request) =>
 prx.Invoke(request, oneway: false).ReadReturnValue(prx.Communicator, _reader);