/// <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; } }