Exemplo n.º 1
0
        /// <summary>
        /// Gets the Remote execution policy for a method.
        /// </summary>
        /// <param name="me">MethodInfo to get policy for.</param>
        /// <param name="defaultPolicy">Default policy (calculated from interface type).</param>
        /// <returns>Remote execution policy to be use when invoking this method.</returns>
        public static RemoteExecutionPolicy GetMethodPolicy(this MethodInfo me, RemoteExecutionPolicy defaultPolicy)
        {
            if (me == null)
            {
                throw new ArgumentNullException(nameof(me));
            }
            var timeoutPolicy = me.GetAttributeOrDefault <TimeoutPolicyAttribute>();
            var durablePolicy = me.GetAttributeOrDefault <DurablePolicyAttribute>();
            var ipPolicy      = me.GetAttributeOrDefault <IpEndPointPolicyAttribute>();
            var returnPolicy  = me.GetAttributeOrDefault <ForcedReturnPolicyAttribute>();

            var ans = me.GetAttributeOrDefault <RemoteExecutionPolicy>() ?? defaultPolicy.Clone();

            if (timeoutPolicy != null)
            {
                ans.Timeout = timeoutPolicy.Timeout;
            }
            if (durablePolicy != null)
            {
                ans.NoRetries       = durablePolicy.NoRetries;
                ans.TimeoutIsStrict = durablePolicy.TimeoutIsStrict;
            }
            if (ipPolicy != null)
            {
                ans.RequiresIpEndPoint = ipPolicy.Required;
            }
            if (returnPolicy != null)
            {
                ans.ForcedReturnPolicy = returnPolicy.ForcedReturnPolicy;
            }
            if (me.ReturnType != typeof(void))
            {
                ans.DefaultReturnPolicy = ReturnPolicy.TwoWay;
            }

            return(ans);
        }
        private void SendDurableStrict(IMethodInvocation invocation, IResponseHandler handler, RemoteExecutionPolicy policy)
        {
            var sent    = true;
            var timeout = policy.Timeout;
            var clock   = new Stopwatch();

            while (true)
            {
                if (sent)
                {
                    sent = SendMessage(invocation, handler);
                }
                var tokenSource = _tokenSource;
                clock.Start();
                handler.WaitForResponse(timeout, tokenSource.Token);
                clock.Stop();
                if (tokenSource.IsCancellationRequested)
                {
                    if (tokenSource.Aborted)
                    {
                        throw new ConnectionOpenException("Connection was closed.");
                    }
                    // Presently no difference between Restored / Interrupted.
                    timeout = timeout - clock.Elapsed;
                    clock.Reset();
                    sent = !sent;
                    if (!tokenSource.Restored)
                    {
                        tokenSource.Restored = false;
                    }
                    continue;
                }
                if (!handler.HasValue)
                {
                    // Cancellation not requested but value not received. This means that the operation timed out.
                    throw new TimeoutException();
                }
                break;
            }
        }
        private void SendDurable(IMethodInvocation invocation, IResponseHandler handler, RemoteExecutionPolicy policy)
        {
            var sent    = true;
            var timeout = policy.Timeout;

            while (true)
            {
                if (sent)
                {
                    sent = SendMessage(invocation, handler);
                }
                var tokenSource = _tokenSource;
                handler.WaitForResponse(timeout, tokenSource.Token);
                if (tokenSource.IsCancellationRequested)
                {
                    if (tokenSource.Aborted)
                    {
                        throw new ConnectionOpenException("Connection was closed.");
                    }
                    sent = !sent;
                    if (!tokenSource.Restored)
                    {
                        tokenSource.Restored = false;
                    }
                    continue;
                }
                if (!handler.HasValue)
                {
                    // Cancellation not requested but value not received. This means that the operation timed out.
                    throw new TimeoutException();
                }
                break;
            }
        }