annotate Implab/AbstractPromise.cs @ 209:a867536c68fc v2

Bound promise to CancellationToken Added new states to ExecutionSate enum. Added Safe.Guard() method to handle cleanup of the result of the promise
author cin
date Wed, 16 Nov 2016 03:06:08 +0300
parents 86187b01c4e0
children cbe10ac0731e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
1 using System;
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
2 using Implab.Parallels;
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
3
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
4 namespace Implab {
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
5 public abstract class AbstractPromise : AbstractEvent<AbstractPromise.HandlerDescriptor>, IPromise {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
6 public struct HandlerDescriptor {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
7 readonly Action m_handler;
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
8 readonly Action<Exception> m_error;
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
9 readonly Action<Exception> m_cancel;
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
10 readonly PromiseEventType m_mask;
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
11
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
12 public HandlerDescriptor(Action success, Action<Exception> error, Action<Exception> cancel) {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
13 m_handler = success;
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
14 m_error = error;
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
15 m_cancel = cancel;
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
16 m_mask = PromiseEventType.Success;
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
17 }
125
f803565868a4 improved performance of promises
cin
parents: 119
diff changeset
18
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
19 public HandlerDescriptor(Action handler, PromiseEventType mask) {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
20 m_handler = handler;
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
21 m_error = null;
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
22 m_cancel = null;
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
23 m_mask = mask;
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
24 }
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
25
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
26 public void SignalSuccess() {
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
27 if ((m_mask & PromiseEventType.Success) != 0 && m_handler != null) {
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
28 try {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
29 m_handler();
197
86187b01c4e0 fixed: the error handler should not handle handlers errors
cin
parents: 186
diff changeset
30 // Analysis disable once EmptyGeneralCatchClause
86187b01c4e0 fixed: the error handler should not handle handlers errors
cin
parents: 186
diff changeset
31 } catch {
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
32 }
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
33 }
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
34 }
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
35
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
36 public void SignalError(Exception err) {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
37 if (m_error != null) {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
38 try {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
39 m_error(err);
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
40 // Analysis disable once EmptyGeneralCatchClause
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
41 } catch {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
42 }
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
43 } else if ((m_mask & PromiseEventType.Error ) != 0 && m_handler != null) {
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
44 try {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
45 m_handler();
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
46 // Analysis disable once EmptyGeneralCatchClause
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
47 } catch {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
48 }
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
49 }
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
50 }
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
51
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
52 public void SignalCancel(Exception reason) {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
53 if (m_cancel != null) {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
54 try {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
55 m_cancel(reason);
197
86187b01c4e0 fixed: the error handler should not handle handlers errors
cin
parents: 186
diff changeset
56 // Analysis disable once EmptyGeneralCatchClause
86187b01c4e0 fixed: the error handler should not handle handlers errors
cin
parents: 186
diff changeset
57 } catch {
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
58 }
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
59 } else if ( (m_mask & PromiseEventType.Cancelled) != 0 && m_handler != null) {
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
60 try {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
61 m_handler();
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
62 // Analysis disable once EmptyGeneralCatchClause
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
63 } catch {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
64 }
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
65 }
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
66 }
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
67 }
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
68
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
69
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
70 #region implemented abstract members of AbstractPromise
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
71
156
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
72 protected override void SignalHandler(HandlerDescriptor handler, int signal) {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
73 switch (signal) {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
74 case SUCCEEDED_STATE:
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
75 handler.SignalSuccess();
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
76 break;
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
77 case REJECTED_STATE:
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
78 handler.SignalError(Error);
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
79 break;
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
80 case CANCELLED_STATE:
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
81 handler.SignalCancel(CancellationReason);
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
82 break;
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
83 default:
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
84 throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", signal));
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
85 }
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
86 }
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
87
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
88 protected override Signal GetResolveSignal() {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
89 var signal = new Signal();
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
90 On(signal.Set, PromiseEventType.All);
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
91 return signal;
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
92 }
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
93
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
94 #endregion
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
95
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
96 public Type PromiseType {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
97 get {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
98 return typeof(void);
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
99 }
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
100 }
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
101
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
102 public IPromise On(Action success, Action<Exception> error, Action<Exception> cancel) {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
103 AddHandler(new HandlerDescriptor(success, error, cancel));
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
104 return this;
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
105 }
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
106
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
107 public IPromise On(Action success, Action<Exception> error) {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
108 AddHandler(new HandlerDescriptor(success, error, null));
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
109 return this;
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
110 }
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
111
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
112 public IPromise On(Action success) {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
113 AddHandler(new HandlerDescriptor(success, null, null));
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
114 return this;
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
115 }
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
116
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
117 public IPromise On(Action handler, PromiseEventType events) {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
118 AddHandler(new HandlerDescriptor(handler,events));
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
119 return this;
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
120 }
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
121
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
122 public IPromise<T> Cast<T>() {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
123 throw new InvalidCastException();
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
124 }
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
125
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
126 public void Join() {
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
127 WaitResult(-1);
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
128 }
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
129
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
130 public void Join(int timeout) {
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
131 WaitResult(timeout);
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
132 }
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
133
144
8c0b95069066 DRAFT: refactoring
cin
parents: 143
diff changeset
134 protected void SetResult() {
186
75103928da09 working on cancelation and error handling
cin
parents: 156
diff changeset
135 if(BeginSetResult())
75103928da09 working on cancelation and error handling
cin
parents: 156
diff changeset
136 EndSetResult();
138
f75cfa58e3d4 added ICancellable.Cancel(Exception) to allow specify the reason of cancellation
cin
parents: 130
diff changeset
137 }
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
138 }
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
139 }
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents:
diff changeset
140