45
45
import java .util .Optional ;
46
46
import java .util .Set ;
47
47
import java .util .UUID ;
48
+ import java .util .function .Consumer ;
49
+ import java .util .function .Function ;
48
50
import lombok .extern .slf4j .Slf4j ;
49
51
50
52
@ Slf4j
@@ -95,19 +97,23 @@ public void run(final ConnectionUpdaterInput connectionUpdaterInput) throws Retr
95
97
final ScheduleRetrieverOutput scheduleRetrieverOutput = configFetchActivity .getTimeToWait (scheduleRetrieverInput );
96
98
Workflow .await (scheduleRetrieverOutput .getTimeToWait (),
97
99
() -> skipScheduling () || connectionUpdaterInput .isFromFailure ());
98
-
99
100
if (!workflowState .isUpdated () && !workflowState .isDeleted ()) {
100
- // Job and attempt creation
101
101
maybeJobId = Optional .ofNullable (connectionUpdaterInput .getJobId ()).or (() -> {
102
- final JobCreationOutput jobCreationOutput = jobCreationAndStatusUpdateActivity .createNewJob (new JobCreationInput (
103
- connectionUpdaterInput .getConnectionId (), workflowState .isResetConnection ()));
102
+ final JobCreationOutput jobCreationOutput =
103
+ runMandatoryActivityWithOutput (
104
+ (input ) -> jobCreationAndStatusUpdateActivity .createNewJob (input ),
105
+ new JobCreationInput (
106
+ connectionUpdaterInput .getConnectionId (), workflowState .isResetConnection ()));
104
107
connectionUpdaterInput .setJobId (jobCreationOutput .getJobId ());
105
108
return Optional .ofNullable (jobCreationOutput .getJobId ());
106
109
});
107
110
108
111
maybeAttemptId = Optional .ofNullable (connectionUpdaterInput .getAttemptId ()).or (() -> maybeJobId .map (jobId -> {
109
- final AttemptCreationOutput attemptCreationOutput = jobCreationAndStatusUpdateActivity .createNewAttempt (new AttemptCreationInput (
110
- jobId ));
112
+ final AttemptCreationOutput attemptCreationOutput =
113
+ runMandatoryActivityWithOutput (
114
+ (input ) -> jobCreationAndStatusUpdateActivity .createNewAttempt (input ),
115
+ new AttemptCreationInput (
116
+ jobId ));
111
117
connectionUpdaterInput .setAttemptId (attemptCreationOutput .getAttemptId ());
112
118
return attemptCreationOutput .getAttemptId ();
113
119
}));
@@ -118,10 +124,14 @@ public void run(final ConnectionUpdaterInput connectionUpdaterInput) throws Retr
118
124
maybeJobId .get (),
119
125
workflowState .isResetConnection ());
120
126
121
- jobCreationAndStatusUpdateActivity .reportJobStart (new ReportJobStartInput (
122
- maybeJobId .get ()));
127
+ runMandatoryActivity (
128
+ (input ) -> jobCreationAndStatusUpdateActivity .reportJobStart (input ),
129
+ new ReportJobStartInput (
130
+ maybeJobId .get ()));
123
131
124
- final SyncOutput syncWorkflowInputs = getSyncInputActivity .getSyncWorkflowInput (getSyncInputActivitySyncInput );
132
+ final SyncOutput syncWorkflowInputs = runMandatoryActivityWithOutput (
133
+ (input ) -> getSyncInputActivity .getSyncWorkflowInput (input ),
134
+ getSyncInputActivitySyncInput );
125
135
126
136
workflowState .setRunning (true );
127
137
@@ -203,13 +213,14 @@ public void run(final ConnectionUpdaterInput connectionUpdaterInput) throws Retr
203
213
} else if (workflowState .isDeleted ()) {
204
214
// Stop the runs
205
215
final ConnectionDeletionInput connectionDeletionInput = new ConnectionDeletionInput (connectionUpdaterInput .getConnectionId ());
206
- connectionDeletionActivity .deleteConnection (connectionDeletionInput );
216
+ runMandatoryActivity (( input ) -> connectionDeletionActivity .deleteConnection (input ), connectionDeletionInput );
207
217
return ;
208
218
} else if (workflowState .isCancelled () || workflowState .isCancelledForReset ()) {
209
- jobCreationAndStatusUpdateActivity .jobCancelled (new JobCancelledInput (
210
- maybeJobId .get (),
211
- maybeAttemptId .get (),
212
- FailureHelper .failureSummaryForCancellation (maybeJobId .get (), maybeAttemptId .get (), failures , partialSuccess )));
219
+ runMandatoryActivity ((input ) -> jobCreationAndStatusUpdateActivity .jobCancelled (input ),
220
+ new JobCancelledInput (
221
+ maybeJobId .get (),
222
+ maybeAttemptId .get (),
223
+ FailureHelper .failureSummaryForCancellation (maybeJobId .get (), maybeAttemptId .get (), failures , partialSuccess )));
213
224
resetNewConnectionInput (connectionUpdaterInput );
214
225
} else if (workflowState .isFailed ()) {
215
226
reportFailure (connectionUpdaterInput );
@@ -227,7 +238,8 @@ public void run(final ConnectionUpdaterInput connectionUpdaterInput) throws Retr
227
238
}
228
239
229
240
private void reportSuccess (final ConnectionUpdaterInput connectionUpdaterInput ) {
230
- jobCreationAndStatusUpdateActivity .jobSuccess (new JobSuccessInput (
241
+ workflowState .setSuccess (true );
242
+ runMandatoryActivity ((input ) -> jobCreationAndStatusUpdateActivity .jobSuccess (input ), new JobSuccessInput (
231
243
maybeJobId .get (),
232
244
maybeAttemptId .get (),
233
245
standardSyncOutput .orElse (null )));
@@ -236,7 +248,7 @@ private void reportSuccess(final ConnectionUpdaterInput connectionUpdaterInput)
236
248
}
237
249
238
250
private void reportFailure (final ConnectionUpdaterInput connectionUpdaterInput ) {
239
- jobCreationAndStatusUpdateActivity .attemptFailure (new AttemptFailureInput (
251
+ runMandatoryActivity (( input ) -> jobCreationAndStatusUpdateActivity .attemptFailure (input ), new AttemptFailureInput (
240
252
connectionUpdaterInput .getJobId (),
241
253
connectionUpdaterInput .getAttemptId (),
242
254
standardSyncOutput .orElse (null ),
@@ -250,7 +262,7 @@ private void reportFailure(final ConnectionUpdaterInput connectionUpdaterInput)
250
262
connectionUpdaterInput .setAttemptNumber (attemptNumber + 1 );
251
263
connectionUpdaterInput .setFromFailure (true );
252
264
} else {
253
- jobCreationAndStatusUpdateActivity .jobFailure (new JobFailureInput (
265
+ runMandatoryActivity (( input ) -> jobCreationAndStatusUpdateActivity .jobFailure (input ), new JobFailureInput (
254
266
connectionUpdaterInput .getJobId (),
255
267
"Job failed after too many retries for connection " + connectionId ));
256
268
@@ -306,6 +318,16 @@ public void resetConnection() {
306
318
}
307
319
}
308
320
321
+ @ Override
322
+ public void retryFailedActivity () {
323
+ workflowState .setRetryFailedActivity (true );
324
+ }
325
+
326
+ @ Override
327
+ public void simulateFailure () {
328
+ workflowState .setFailed (true );
329
+ }
330
+
309
331
@ Override
310
332
public WorkflowState getState () {
311
333
return workflowState ;
@@ -318,6 +340,15 @@ public JobInformation getJobInformation() {
318
340
maybeAttemptId .orElse (NON_RUNNING_ATTEMPT_ID ));
319
341
}
320
342
343
+ @ Override
344
+ public QuarantinedInformation getQuarantinedInformation () {
345
+ return new QuarantinedInformation (
346
+ connectionId ,
347
+ maybeJobId .orElse (NON_RUNNING_JOB_ID ),
348
+ maybeAttemptId .orElse (NON_RUNNING_ATTEMPT_ID ),
349
+ workflowState .isQuarantined ());
350
+ }
351
+
321
352
private Boolean skipScheduling () {
322
353
return workflowState .isSkipScheduling () || workflowState .isDeleted () || workflowState .isUpdated () || workflowState .isResetConnection ();
323
354
}
@@ -335,4 +366,36 @@ private void continueAsNew(final ConnectionUpdaterInput connectionUpdaterInput)
335
366
}
336
367
}
337
368
369
+ /**
370
+ * This is running a lambda function that takes {@param input} as an input. If the run of the lambda
371
+ * is thowing an exception, the workflow will be in a quarantined state and can then be manual
372
+ * un-quarantined or a retry of the failed lambda can be trigger through a signal method.
373
+ *
374
+ * We aimed to use this method for call of the temporal activity.
375
+ */
376
+ private <INPUT , OUTPUT > OUTPUT runMandatoryActivityWithOutput (Function <INPUT , OUTPUT > mapper , INPUT input ) {
377
+ try {
378
+ return mapper .apply (input );
379
+ } catch (Exception e ) {
380
+ log .error ("Failed to run an activity for the connection " + connectionId , e );
381
+ workflowState .setQuarantined (true );
382
+ workflowState .setRetryFailedActivity (false );
383
+ Workflow .await (() -> workflowState .isRetryFailedActivity ());
384
+ log .error ("Retrying an activity for the connection " + connectionId , e );
385
+ workflowState .setQuarantined (false );
386
+ workflowState .setRetryFailedActivity (false );
387
+ return runMandatoryActivityWithOutput (mapper , input );
388
+ }
389
+ }
390
+
391
+ /**
392
+ * Similar to runMandatoryActivityWithOutput but for methods that don't return
393
+ */
394
+ private <INPUT > void runMandatoryActivity (Consumer <INPUT > consumer , INPUT input ) {
395
+ runMandatoryActivityWithOutput ((inputInternal ) -> {
396
+ consumer .accept (inputInternal );
397
+ return null ;
398
+ }, input );
399
+ }
400
+
338
401
}
0 commit comments