annotate Implab/AbstractPromiseT.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
144
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
1 using System;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
2 using Implab.Parallels;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
3
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
4 namespace Implab {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
5 public abstract class AbstractPromise<T> : AbstractEvent<AbstractPromise<T>.HandlerDescriptor>, IPromise<T> {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
6 public struct HandlerDescriptor {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
7 readonly Action m_handler;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
8 readonly Action<T> m_success;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
9 readonly Action<Exception> m_error;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
10 readonly Action<Exception> m_cancel;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
11 readonly PromiseEventType m_mask;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
12
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
13 public HandlerDescriptor(Action<T> success, Action<Exception> error, Action<Exception> cancel) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
14 m_success = success;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
15 m_error = error;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
16 m_cancel = cancel;
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
17
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
18 m_handler = null;
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
19 m_mask = 0;
144
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
20 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
21
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
22 public HandlerDescriptor(Action success, Action<Exception> error, Action<Exception> cancel) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
23 m_handler = success;
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
24 m_success = null;
144
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
25 m_error = error;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
26 m_cancel = cancel;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
27 m_mask = PromiseEventType.Success;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
28 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
29
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
30 public HandlerDescriptor(Action handler, PromiseEventType mask) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
31 m_handler = handler;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
32 m_mask = mask;
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
33 m_success = null;
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
34 m_error = null;
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
35 m_cancel = null;
144
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
36 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
37
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
38 public void SignalSuccess(T result) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
39 if (m_success != null) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
40 try {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
41 m_success(result);
197
86187b01c4e0 fixed: the error handler should not handle handlers errors
cin
parents: 156
diff changeset
42 // Analysis disable once EmptyGeneralCatchClause
86187b01c4e0 fixed: the error handler should not handle handlers errors
cin
parents: 156
diff changeset
43 } catch {
144
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
44 }
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
45 } else if ((m_mask & PromiseEventType.Success) != 0 && m_handler != null) {
144
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
46 try {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
47 m_handler();
197
86187b01c4e0 fixed: the error handler should not handle handlers errors
cin
parents: 156
diff changeset
48 // Analysis disable once EmptyGeneralCatchClause
86187b01c4e0 fixed: the error handler should not handle handlers errors
cin
parents: 156
diff changeset
49 } catch {
144
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
50 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
51 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
52 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
53
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
54 public void SignalError(Exception err) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
55 if (m_error != null) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
56 try {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
57 m_error(err);
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
58 // Analysis disable once EmptyGeneralCatchClause
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
59 } catch {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
60 }
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
61 } else if ((m_mask & PromiseEventType.Error) != 0 && m_handler != null) {
144
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
62 try {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
63 m_handler();
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
64 // Analysis disable once EmptyGeneralCatchClause
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
65 } catch {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
66 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
67 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
68 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
69
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
70 public void SignalCancel(Exception reason) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
71 if (m_cancel != null) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
72 try {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
73 m_cancel(reason);
197
86187b01c4e0 fixed: the error handler should not handle handlers errors
cin
parents: 156
diff changeset
74 // Analysis disable once EmptyGeneralCatchClause
86187b01c4e0 fixed: the error handler should not handle handlers errors
cin
parents: 156
diff changeset
75 } catch {
144
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
76 }
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
77 } else if ((m_mask & PromiseEventType.Cancelled) != 0 && m_handler != null) {
144
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
78 try {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
79 m_handler();
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
80 // Analysis disable once EmptyGeneralCatchClause
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
81 } catch {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
82 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
83 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
84 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
85 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
86
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
87 public Type PromiseType {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
88 get {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
89 return typeof(T);
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
90 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
91 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
92
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
93 public T Join() {
144
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
94 WaitResult(-1);
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
95 return m_result;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
96 }
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
97 public T Join(int timeout) {
144
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
98 WaitResult(timeout);
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
99 return m_result;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
100 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
101
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
102 void IPromise.Join() {
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
103 WaitResult(-1);
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
104 }
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
105 void IPromise.Join(int timeout) {
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
106 WaitResult(timeout);
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
107 }
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
108
144
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
109 public IPromise<T> On(Action<T> success, Action<Exception> error, Action<Exception> cancel) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
110 AddHandler(new HandlerDescriptor(success, error, cancel));
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
111 return this;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
112 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
113
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
114 public IPromise<T> On(Action<T> success, Action<Exception> error) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
115 AddHandler(new HandlerDescriptor(success, error, null));
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
116 return this;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
117 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
118
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
119 public IPromise<T> On(Action<T> success) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
120 AddHandler(new HandlerDescriptor(success, null, null));
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
121 return this;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
122 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
123
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
124 public IPromise<T> On(Action handler, PromiseEventType events) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
125 AddHandler(new HandlerDescriptor(handler, events));
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
126 return this;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
127 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
128
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
129 public IPromise<T> On(Action success, Action<Exception> error, Action<Exception> cancel) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
130 AddHandler(new HandlerDescriptor(success, error, cancel));
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
131 return this;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
132 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
133
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
134 public IPromise<T> On(Action success, Action<Exception> error) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
135 AddHandler(new HandlerDescriptor(success, error, null));
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
136 return this;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
137 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
138
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
139 public IPromise<T> On(Action success) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
140 AddHandler(new HandlerDescriptor(success, null, null));
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
141 return this;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
142 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
143
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
144 IPromise IPromise.On(Action success, Action<Exception> error, Action<Exception> cancel) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
145 AddHandler(new HandlerDescriptor(success, error, cancel));
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
146 return this;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
147 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
148
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
149 IPromise IPromise.On(Action success, Action<Exception> error) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
150 AddHandler(new HandlerDescriptor(success, error, null));
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
151 return this;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
152 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
153
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
154 IPromise IPromise.On(Action success) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
155 AddHandler(new HandlerDescriptor(success, null, null));
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
156 return this;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
157 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
158
145
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
159 IPromise IPromise.On(Action handler, PromiseEventType events) {
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
160 AddHandler(new HandlerDescriptor(handler, events));
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
161 return this;
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
162 }
706fccb85524 RC: cancellation support for promises + tests
cin
parents: 144
diff changeset
163
144
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
164 public IPromise<T2> Cast<T2>() {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
165 return (IPromise<T2>)this;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
166 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
167
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
168 #region implemented abstract members of AbstractPromise
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
169
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
170 protected override Signal GetResolveSignal() {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
171 var signal = new Signal();
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
172 AddHandler(new HandlerDescriptor(signal.Set, PromiseEventType.All));
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
173 return signal;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
174 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
175
156
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
176 protected override void SignalHandler(HandlerDescriptor handler, int signal) {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
177 switch (signal) {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
178 case SUCCEEDED_STATE:
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
179 handler.SignalSuccess(m_result);
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
180 break;
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
181 case REJECTED_STATE:
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
182 handler.SignalError(Error);
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
183 break;
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
184 case CANCELLED_STATE:
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
185 handler.SignalCancel(CancellationReason);
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
186 break;
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
187 default:
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
188 throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", signal));
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents: 145
diff changeset
189 }
144
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
190 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
191
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
192 #endregion
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
193
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
194 T m_result;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
195
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
196 protected void SetResult(T value) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
197 if (BeginSetResult()) {
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
198 m_result = value;
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
199 EndSetResult();
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
200 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
201 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
202 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
203 }
8c0b95069066 DRAFT: refactoring
cin
parents:
diff changeset
204