@@ -73,6 +73,7 @@ protected WorkflowMutableInstance(WorkflowDefinition definition, String id, Work
7373 public CompletableFuture <WorkflowModel > start () {
7474 return startExecution (
7575 () -> {
76+ status (WorkflowStatus .RUNNING );
7677 startedAt = Instant .now ();
7778 return publishEvent (
7879 workflowContext , l -> l .onWorkflowStarted (new WorkflowStartedEvent (workflowContext )));
@@ -85,8 +86,6 @@ protected final CompletableFuture<WorkflowModel> startExecution(
8586 if (future != null ) {
8687 return future ;
8788 }
88- status (WorkflowStatus .RUNNING );
89-
9089 future =
9190 runnable
9291 .get ()
@@ -103,20 +102,23 @@ protected final CompletableFuture<WorkflowModel> startExecution(
103102 .orElse (input ))
104103 .whenComplete (this ::setCompleteDate )
105104 .thenApply (this ::filterAndValidate )
106- .whenComplete (this ::handleException )
107- .thenCompose (
108- model ->
109- publishEvent (
110- workflowContext ,
111- l ->
112- l .onWorkflowCompleted (
113- new WorkflowCompletedEvent (workflowContext , model )))
114- .thenApply (__ -> model )))
105+ .thenCompose (this ::publishEvents )
106+ .exceptionallyCompose (this ::handleException ))
115107 .whenComplete (this ::cleanUp );
116108 futureRef .set (future );
117109 return future ;
118110 }
119111
112+ private CompletableFuture <WorkflowModel > publishEvents (WorkflowModel model ) {
113+ return status (WorkflowStatus .COMPLETED )
114+ .thenCompose (
115+ __ ->
116+ publishEvent (
117+ workflowContext ,
118+ l -> l .onWorkflowCompleted (new WorkflowCompletedEvent (workflowContext , model ))))
119+ .thenApply (__ -> model );
120+ }
121+
120122 private void setCompleteDate (WorkflowModel result , Throwable ex ) {
121123 completedAt = Instant .now ();
122124 }
@@ -130,19 +132,19 @@ private void cleanUp(WorkflowModel result, Throwable ex) {
130132 workflowContext .definition ().removeInstance (this );
131133 }
132134
133- private void handleException (WorkflowModel result , Throwable exception ) {
134- if (exception != null ) {
135- final Throwable cause =
136- exception instanceof CompletionException ? exception .getCause () : exception ;
137- if (!(cause instanceof CancellationException )) {
138- status (WorkflowStatus .FAULTED );
139- publishEvent (
140- workflowContext ,
141- l -> l .onWorkflowFailed (new WorkflowFailedEvent (workflowContext , cause )));
142- }
143- } else {
144- status (WorkflowStatus .COMPLETED );
135+ private CompletableFuture <WorkflowModel > handleException (Throwable exception ) {
136+ final Throwable cause =
137+ exception instanceof CompletionException ? exception .getCause () : exception ;
138+ if (!(cause instanceof CancellationException )) {
139+ return status (WorkflowStatus .FAULTED )
140+ .thenCompose (
141+ __ ->
142+ publishEvent (
143+ workflowContext ,
144+ l -> l .onWorkflowFailed (new WorkflowFailedEvent (workflowContext , cause ))))
145+ .thenCompose (__ -> CompletableFuture .failedFuture (exception ));
145146 }
147+ return CompletableFuture .failedFuture (exception );
146148 }
147149
148150 private WorkflowModel filterAndValidate (WorkflowModel model ) {
@@ -208,15 +210,19 @@ public <T> T outputAs(Class<T> clazz) {
208210 : null ;
209211 }
210212
211- public void status (WorkflowStatus state ) {
213+ public CompletableFuture <?> status (WorkflowStatus state ) {
212214 WorkflowStatus prevState = this .status .getAndSet (state );
213- if (prevState != state ) {
214- publishEvent (
215- workflowContext ,
216- l ->
217- l .onWorkflowStatusChanged (
218- new WorkflowStatusEvent (workflowContext , prevState , state )));
219- }
215+ return prevState != state
216+ ? publishEvent (
217+ workflowContext ,
218+ l ->
219+ l .onWorkflowStatusChanged (
220+ new WorkflowStatusEvent (workflowContext , prevState , state )))
221+ : CompletableFuture .completedFuture (null );
222+ }
223+
224+ protected final void setStatus (WorkflowStatus state ) {
225+ this .status .set (state );
220226 }
221227
222228 @ Override
@@ -234,8 +240,9 @@ public String toString() {
234240
235241 @ Override
236242 public boolean suspend () {
237- boolean result = _suspend ();
243+ boolean result = internalSuspend ();
238244 if (result ) {
245+ status (WorkflowStatus .SUSPENDED );
239246 publishEvent (
240247 workflowContext , l -> l .onWorkflowSuspended (new WorkflowSuspendedEvent (workflowContext )));
241248 }
@@ -244,19 +251,22 @@ public boolean suspend() {
244251
245252 @ Override
246253 public CompletableFuture <Boolean > suspendFuture () {
247- return _suspend ()
248- ? publishEvent (
249- workflowContext ,
250- l -> l .onWorkflowSuspended (new WorkflowSuspendedEvent (workflowContext )))
254+ return internalSuspend ()
255+ ? status (WorkflowStatus .SUSPENDED )
256+ .thenCompose (
257+ __ ->
258+ publishEvent (
259+ workflowContext ,
260+ l -> l .onWorkflowSuspended (new WorkflowSuspendedEvent (workflowContext ))))
251261 .thenApply (__ -> true )
252262 : CompletableFuture .completedFuture (false );
253263 }
254264
255- private boolean _suspend () {
265+ private boolean internalSuspend () {
256266 try {
257267 statusLock .lock ();
258268 if (TaskExecutorHelper .isActive (status .get ()) && suspended == null ) {
259- internalSuspend ();
269+ setSuspended ();
260270 return true ;
261271 } else {
262272 return false ;
@@ -266,14 +276,13 @@ private boolean _suspend() {
266276 }
267277 }
268278
269- protected final void internalSuspend () {
279+ protected final void setSuspended () {
270280 suspended = new ConcurrentHashMap <>();
271- status (WorkflowStatus .SUSPENDED );
272281 }
273282
274283 @ Override
275284 public boolean resume () {
276- boolean result = _resume ();
285+ boolean result = internalResume ();
277286 if (result ) {
278287 publishEvent (
279288 workflowContext , l -> l .onWorkflowResumed (new WorkflowResumedEvent (workflowContext )));
@@ -283,15 +292,15 @@ public boolean resume() {
283292
284293 @ Override
285294 public CompletableFuture <Boolean > resumeFuture () {
286- return _resume ()
295+ return internalResume ()
287296 ? publishEvent (
288297 workflowContext ,
289298 l -> l .onWorkflowResumed (new WorkflowResumedEvent (workflowContext )))
290299 .thenApply (__ -> true )
291300 : CompletableFuture .completedFuture (false );
292301 }
293302
294- private boolean _resume () {
303+ private boolean internalResume () {
295304 boolean result ;
296305 try {
297306 statusLock .lock ();
@@ -327,25 +336,28 @@ public CompletableFuture<TaskContext> cancelCheck(TaskContext t) {
327336 }
328337
329338 public CompletableFuture <TaskContext > suspendedCheck (TaskContext t ) {
339+ boolean isActive ;
330340 try {
331341 statusLock .lock ();
332342 if (suspended != null ) {
333343 CompletableFuture <TaskContext > suspendedTask = new CompletableFuture <TaskContext >();
334344 suspended .put (suspendedTask , t );
335345 return suspendedTask ;
336- } else if (TaskExecutorHelper .isActive (status .get ())) {
337- status (WorkflowStatus .RUNNING );
338346 }
347+ isActive = TaskExecutorHelper .isActive (status .get ());
339348 } finally {
340349 statusLock .unlock ();
341350 }
342- return CompletableFuture .completedFuture (t );
351+ return isActive
352+ ? status (WorkflowStatus .RUNNING ).thenApply (__ -> t )
353+ : CompletableFuture .completedFuture (t );
343354 }
344355
345356 @ Override
346357 public boolean cancel () {
347- boolean result = _cancel ();
358+ boolean result = internalCancel ();
348359 if (result ) {
360+ status (WorkflowStatus .CANCELLED );
349361 publishEvent (
350362 workflowContext , l -> l .onWorkflowCancelled (new WorkflowCancelledEvent (workflowContext )));
351363 }
@@ -354,23 +366,25 @@ public boolean cancel() {
354366
355367 @ Override
356368 public CompletableFuture <Boolean > cancelFuture () {
357- return _cancel ()
358- ? publishEvent (
359- workflowContext ,
360- l -> l .onWorkflowCancelled (new WorkflowCancelledEvent (workflowContext )))
369+ return internalCancel ()
370+ ? status (WorkflowStatus .CANCELLED )
371+ .thenCompose (
372+ __ ->
373+ publishEvent (
374+ workflowContext ,
375+ l -> l .onWorkflowCancelled (new WorkflowCancelledEvent (workflowContext ))))
361376 .thenApply (__ -> true )
362377 : CompletableFuture .completedFuture (false );
363378 }
364379
365- private boolean _cancel () {
380+ private boolean internalCancel () {
366381 boolean result ;
367382 Collection <CompletableFuture <?>> toCancel = null ;
368383 try {
369384 statusLock .lock ();
370385 if (TaskExecutorHelper .isActive (status .get ())) {
371386 toCancel = new ArrayList <>(cancelables );
372387 cancelables .clear ();
373- status (WorkflowStatus .CANCELLED );
374388 result = true ;
375389 } else {
376390 result = false ;
0 commit comments