changeset 186:75103928da09 ref20160224

working on cancelation and error handling
author cin
date Tue, 19 Apr 2016 00:50:14 +0300
parents 822aab37b107
children dd4a3590f9c6
files Implab/AbstractEvent.cs Implab/AbstractPromise.cs Implab/ActionChainTaskBase.cs Implab/Components/RunnableComponent.cs
diffstat 4 files changed, 34 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/Implab/AbstractEvent.cs	Mon Apr 18 16:41:17 2016 +0300
+++ b/Implab/AbstractEvent.cs	Tue Apr 19 00:50:14 2016 +0300
@@ -77,19 +77,14 @@
         /// <param name="error">Исключение возникшее при выполнении операции</param>
         /// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception>
         protected void SetError(Exception error) {
-            while (error is PromiseTransientException)
-                error = error.InnerException;
-
-            var isCancel = error is OperationCanceledException;
-            
             if (BeginTransit()) {
-                m_error = isCancel ? error.InnerException : error;
-                CompleteTransit(isCancel ? CANCELLED_STATE : REJECTED_STATE);
+                m_error = error;
+                CompleteTransit(REJECTED_STATE);
 
                 Signal();
             } else {
                 WaitTransition();
-                if (!isCancel || m_state == SUCCEEDED_STATE)
+                if (m_state == SUCCEEDED_STATE)
                     throw new InvalidOperationException("The promise is already resolved");
             }
         }
@@ -140,11 +135,11 @@
                 case SUCCEEDED_STATE:
                     return;
                 case CANCELLED_STATE:
-                    throw new OperationCanceledException();
+                    throw new OperationCanceledException("The operation has been cancelled", m_error);
                 case REJECTED_STATE:
                     throw new TargetInvocationException(m_error);
                 default:
-                    throw new ApplicationException(String.Format("Invalid promise state {0}", m_state));
+                    throw new ApplicationException(String.Format("The promise state {0} is invalid", m_state));
             }
         }
         #endregion
--- a/Implab/AbstractPromise.cs	Mon Apr 18 16:41:17 2016 +0300
+++ b/Implab/AbstractPromise.cs	Tue Apr 19 00:50:14 2016 +0300
@@ -134,8 +134,8 @@
         }
 
         protected void SetResult() {
-            BeginSetResult();
-            EndSetResult();
+            if(BeginSetResult())
+                EndSetResult();
         }
     }
 }
--- a/Implab/ActionChainTaskBase.cs	Mon Apr 18 16:41:17 2016 +0300
+++ b/Implab/ActionChainTaskBase.cs	Tue Apr 19 00:50:14 2016 +0300
@@ -20,34 +20,51 @@
                 HandleErrorInternal(error);
         }
 
-
-
         public override void CancelOperation(Exception reason) {
             if (LockCancelation()) {
+                if (!(reason is OperationCanceledException))
+                    reason = reason != null ? new OperationCanceledException(null, reason) : new OperationCanceledException();
+                
                 if (m_cancel != null) {
                     try {
-                        m_cancel(reason).On(SetResult, SetError, SetCancelled);
+                        m_cancel(reason).On(SetResult, HandleErrorInternal, HandleCancelInternal);
                     } catch (Exception err) {
                         HandleErrorInternal(err);
                     }
                 } else {
-                    SetCancelled(reason);
+                    HandleErrorInternal(reason);
                 }
             }
         }
 
-        protected void HandleErrorInternal(Exception error) {
+        void HandleCancelInternal(Exception reason) {
+            if (!(reason is OperationCanceledException))
+                reason = reason != null ? new OperationCanceledException(null, reason) : new OperationCanceledException();
+            HandleErrorInternal(reason);
+        }
+
+        void HandleErrorInternal(Exception error) {
             if (m_error != null) {
                 try {
                     var p = m_error(error);
-                    p.On(SetResult,SetError,SetCancelled);
+                    p.On(SetResult, SetError, SetCancelled);
                     CancellationRequested(p.Cancel);
                 } catch (Exception err) {
-                    SetError(err);
+                    error = err;
                 }
             } else {
+                SetErrorInternal(error);
+            }
+        }
+
+        void SetErrorInternal(Exception error) {
+            while (error is PromiseTransientException)
+                error = error.InnerException;
+
+            if (error is OperationCanceledException)
+                SetCancelled(error);
+            else
                 SetError(error);
-            }
         }
 
         protected bool LockCancelation() {
--- a/Implab/Components/RunnableComponent.cs	Mon Apr 18 16:41:17 2016 +0300
+++ b/Implab/Components/RunnableComponent.cs	Tue Apr 19 00:50:14 2016 +0300
@@ -139,14 +139,7 @@
                         throw new PromiseTransientException(e);
                     },
                     r => {
-                        lock(m_stateMachine) {
-                            if (m_pending == promise) {
-                                Move(Commands.Fail);
-                                m_pending = null;
-                                m_lastError = new OperationCanceledException("The operation has been cancelled", r);
-                            }
-
-                        }
+                        // handle cancellation as exception
                         throw new OperationCanceledException("The operation has been cancelled", r);
                     }
                 );
@@ -201,7 +194,7 @@
             if (current == null) {
                 stop.Resolve();
             } else {
-                current.On(stop.Resolve, stop.Reject, stop.CancelOperation);
+                current.On(stop.Resolve, stop.Reject, e => stop.Resolve());
                 current.Cancel();
             }
         }