예제 #1
0
        /// <summary>
        /// Dispatches a call allocating new or re-using existing transport if needed. The strategy depends on particular Binding implementation.
        /// This call is thread-safe
        /// </summary>
        public CallSlot DispatchCall(ClientEndPoint client, RequestMsg request)
        {
            CheckRunningState();

            //Binding level inspectors
            foreach (var insp in m_ClientMsgInspectors.OrderedValues)
            {
                request = insp.ClientDispatchCall(client, request);
            }

            //Glue level inspectors
            request = Glue.ClientDispatchingRequest(client, request);

            //==============================================================

            CallOptions options;

            options.DispatchTimeoutMs = client.DispatchTimeoutMs;
            options.TimeoutMs         = client.TimeoutMs;

            var reserve = client.ReserveTransport;

            var transport = client.m_ReservedTransport ?? AcquireClientTransportForCall(client, request);

            CallSlot slot = null;

            try
            {
                if (reserve)
                {
                    client.m_ReservedTransport = transport;
                }

                slot = transport.SendRequest(client, request, options);

                // If execution pauses here and server sends response BEFORE call
                //then Glue.Deliver response will retry to fimnd the missing call slot for some fixed interval
                if (slot != null)
                {
                    Glue.ClientDispatchedRequest(client, request, slot);
                }
            }
            finally
            {
                if (!reserve)
                {
                    ReleaseClientTransportAfterCall(transport);
                }
            }

            return(slot);
        }