0
# Activity Execution and Configuration
1
2
Comprehensive APIs for implementing activities that handle external service calls, with built-in retry logic, heartbeat support, and async completion patterns.
3
4
## Capabilities
5
6
### Activity Utility Class
7
8
Central utility class providing access to activity execution context and exception handling.
9
10
```java { .api }
11
/**
12
* Central utility class for Activity execution, providing access to execution context and exception wrapping.
13
*/
14
public final class Activity {
15
/**
16
* Returns the ActivityExecutionContext for the current activity thread.
17
* @return the current activity execution context
18
* @throws IllegalStateException if called outside of activity execution
19
*/
20
public static ActivityExecutionContext getExecutionContext();
21
22
/**
23
* Wraps checked exceptions as RuntimeException for rethrowing from activities.
24
* @param e the exception to wrap
25
* @return RuntimeException wrapping the original exception
26
*/
27
public static RuntimeException wrap(Throwable e);
28
}
29
```
30
31
**Usage Examples:**
32
33
```java
34
@ActivityInterface
35
public interface FileProcessingActivity {
36
@ActivityMethod
37
String processFile(String filename);
38
}
39
40
public class FileProcessingActivityImpl implements FileProcessingActivity {
41
@Override
42
public String processFile(String filename) {
43
ActivityExecutionContext context = Activity.getExecutionContext();
44
45
try {
46
// Long running file processing
47
for (int i = 0; i < 100; i++) {
48
// Send heartbeat every 10 iterations
49
if (i % 10 == 0) {
50
context.heartbeat("Processing: " + i + "%");
51
}
52
// Process file chunk
53
Thread.sleep(1000);
54
}
55
return "File processed: " + filename;
56
} catch (InterruptedException e) {
57
throw Activity.wrap(e);
58
}
59
}
60
}
61
```
62
63
### Activity Execution Context
64
65
Context object providing information about the current Activity execution and tools for heartbeating and async completion.
66
67
```java { .api }
68
/**
69
* Context object providing information about the current Activity execution and tools for heartbeating and async completion.
70
*/
71
public interface ActivityExecutionContext {
72
/**
73
* Returns ActivityInfo with execution details.
74
* @return information about the current activity execution
75
*/
76
ActivityInfo getInfo();
77
78
/**
79
* Sends heartbeat with optional details, may throw ActivityCompletionException.
80
* @param details heartbeat details to send
81
* @throws ActivityCompletionException if activity should be completed
82
*/
83
<V> void heartbeat(V details) throws ActivityCompletionException;
84
85
/**
86
* Gets heartbeat details from last heartbeat or failed attempt.
87
* @param detailsClass class of the heartbeat details
88
* @return optional heartbeat details
89
*/
90
<V> Optional<V> getHeartbeatDetails(Class<V> detailsClass);
91
92
/**
93
* Type-safe version with generic type info for getting heartbeat details.
94
* @param detailsClass class of the heartbeat details
95
* @param detailsGenericType generic type information
96
* @return optional heartbeat details
97
*/
98
<V> Optional<V> getHeartbeatDetails(Class<V> detailsClass, Type detailsGenericType);
99
100
/**
101
* Gets details from last failed attempt only.
102
* @param detailsClass class of the heartbeat details
103
* @return optional heartbeat details from last failed attempt
104
*/
105
<V> Optional<V> getLastHeartbeatDetails(Class<V> detailsClass);
106
107
/**
108
* Type-safe version for getting details from last failed attempt.
109
* @param detailsClass class of the heartbeat details
110
* @param detailsGenericType generic type information
111
* @return optional heartbeat details from last failed attempt
112
*/
113
<V> Optional<V> getLastHeartbeatDetails(Class<V> detailsClass, Type detailsGenericType);
114
115
/**
116
* Returns task token for async completion.
117
* @return task token bytes
118
*/
119
byte[] getTaskToken();
120
121
/**
122
* Marks activity for async completion.
123
*/
124
void doNotCompleteOnReturn();
125
126
/**
127
* Checks if async completion is enabled.
128
* @return true if async completion is enabled
129
*/
130
boolean isDoNotCompleteOnReturn();
131
132
/**
133
* Returns ManualActivityCompletionClient for local async completion.
134
* @return client for manual activity completion
135
*/
136
ManualActivityCompletionClient useLocalManualCompletion();
137
138
/**
139
* Checks if local manual completion is enabled.
140
* @return true if local manual completion is enabled
141
*/
142
boolean isUseLocalManualCompletion();
143
144
/**
145
* Returns metrics scope for business metrics.
146
* @return metrics scope
147
*/
148
Scope getMetricsScope();
149
150
/**
151
* Returns WorkflowClient for service interaction.
152
* @return workflow client instance
153
*/
154
WorkflowClient getWorkflowClient();
155
156
/**
157
* Returns the currently running activity instance.
158
* @return activity instance
159
*/
160
Object getInstance();
161
}
162
```
163
164
**Usage Examples:**
165
166
```java
167
public class DataProcessingActivityImpl implements DataProcessingActivity {
168
@Override
169
public ProcessingResult processLargeDataset(DatasetRequest request) {
170
ActivityExecutionContext context = Activity.getExecutionContext();
171
ActivityInfo info = context.getInfo();
172
173
// Check for previous progress from heartbeat details
174
Optional<ProcessingState> previousState = context.getHeartbeatDetails(ProcessingState.class);
175
int startIndex = previousState.map(s -> s.getProcessedCount()).orElse(0);
176
177
for (int i = startIndex; i < request.getTotalItems(); i++) {
178
// Process item
179
processItem(request.getItem(i));
180
181
// Send heartbeat every 100 items
182
if (i % 100 == 0) {
183
ProcessingState state = new ProcessingState(i, request.getTotalItems());
184
context.heartbeat(state);
185
}
186
}
187
188
return new ProcessingResult(request.getTotalItems());
189
}
190
}
191
```
192
193
### Activity Information
194
195
Information about the Activity Task being executed.
196
197
```java { .api }
198
/**
199
* Information about the Activity Task being executed.
200
*/
201
public interface ActivityInfo {
202
/**
203
* Task token for async completion.
204
* @return task token bytes
205
*/
206
byte[] getTaskToken();
207
208
/**
209
* Workflow ID that scheduled this activity.
210
* @return workflow ID
211
*/
212
String getWorkflowId();
213
214
/**
215
* Run ID of the scheduling workflow.
216
* @return workflow run ID
217
*/
218
String getRunId();
219
220
/**
221
* Activity execution ID.
222
* @return activity ID
223
*/
224
String getActivityId();
225
226
/**
227
* Activity type name.
228
* @return activity type
229
*/
230
String getActivityType();
231
232
/**
233
* When activity was initially scheduled (UNIX epoch ms).
234
* @return scheduled timestamp in milliseconds
235
*/
236
long getScheduledTimestamp();
237
238
/**
239
* When current attempt started (UNIX epoch ms).
240
* @return started timestamp in milliseconds
241
*/
242
long getStartedTimestamp();
243
244
/**
245
* When current attempt was scheduled (UNIX epoch ms).
246
* @return current attempt scheduled timestamp in milliseconds
247
*/
248
long getCurrentAttemptScheduledTimestamp();
249
250
/**
251
* Schedule-to-close timeout duration.
252
* @return schedule to close timeout
253
*/
254
Duration getScheduleToCloseTimeout();
255
256
/**
257
* Start-to-close timeout duration.
258
* @return start to close timeout
259
*/
260
Duration getStartToCloseTimeout();
261
262
/**
263
* Heartbeat timeout duration.
264
* @return heartbeat timeout
265
*/
266
Duration getHeartbeatTimeout();
267
268
/**
269
* Raw heartbeat details as Payloads.
270
* @return optional payloads containing heartbeat details
271
*/
272
Optional<Payloads> getHeartbeatDetails();
273
274
/**
275
* Type of the scheduling workflow.
276
* @return workflow type
277
*/
278
String getWorkflowType();
279
280
/**
281
* Namespace of the activity execution.
282
* @return namespace name
283
*/
284
String getNamespace();
285
286
/**
287
* Task queue name.
288
* @return task queue name
289
*/
290
String getActivityTaskQueue();
291
292
/**
293
* Current attempt number (starts at 1).
294
* @return attempt number
295
*/
296
int getAttempt();
297
298
/**
299
* Whether this is a local activity.
300
* @return true if local activity
301
*/
302
boolean isLocal();
303
304
/**
305
* Priority of the activity task (Experimental).
306
* @return task priority
307
*/
308
@Experimental
309
Priority getPriority();
310
311
/**
312
* Retry options for the activity.
313
* @return retry options
314
*/
315
RetryOptions getRetryOptions();
316
}
317
```
318
319
### Dynamic Activities
320
321
Interface for implementing activities that can handle any activity type dynamically.
322
323
```java { .api }
324
/**
325
* Interface for implementing activities that can handle any activity type dynamically.
326
*/
327
public interface DynamicActivity {
328
/**
329
* Executes the dynamic activity with encoded arguments.
330
* @param args encoded activity arguments
331
* @return activity result
332
*/
333
Object execute(EncodedValues args);
334
}
335
```
336
337
**Usage Examples:**
338
339
```java
340
public class GenericActivityImpl implements DynamicActivity {
341
@Override
342
public Object execute(EncodedValues args) {
343
ActivityInfo info = Activity.getExecutionContext().getInfo();
344
String activityType = info.getActivityType();
345
346
switch (activityType) {
347
case "SendEmail":
348
return handleSendEmail(args);
349
case "ProcessPayment":
350
return handleProcessPayment(args);
351
case "GenerateReport":
352
return handleGenerateReport(args);
353
default:
354
throw new IllegalArgumentException("Unknown activity type: " + activityType);
355
}
356
}
357
358
private Object handleSendEmail(EncodedValues args) {
359
// Extract arguments and send email
360
String recipient = args.get(0, String.class);
361
String subject = args.get(1, String.class);
362
String body = args.get(2, String.class);
363
// Send email logic...
364
return "Email sent to " + recipient;
365
}
366
}
367
```
368
369
### Manual Activity Completion
370
371
Client for manually completing activities that were marked with `doNotCompleteOnReturn()`.
372
373
```java { .api }
374
/**
375
* Client for manually completing activities that were marked with doNotCompleteOnReturn().
376
*/
377
public interface ManualActivityCompletionClient {
378
/**
379
* Completes activity successfully with result.
380
* @param result the activity result
381
*/
382
void complete(@Nullable Object result);
383
384
/**
385
* Completes activity with failure.
386
* @param failure the failure to report
387
*/
388
void fail(@Nonnull Throwable failure);
389
390
/**
391
* Records heartbeat, may throw CanceledFailure.
392
* @param details heartbeat details
393
* @throws CanceledFailure if activity was canceled
394
*/
395
void recordHeartbeat(@Nullable Object details) throws CanceledFailure;
396
397
/**
398
* Reports successful cancellation.
399
* @param details cancellation details
400
*/
401
void reportCancellation(@Nullable Object details);
402
}
403
```
404
405
**Usage Examples:**
406
407
```java
408
public class AsyncProcessingActivityImpl implements AsyncProcessingActivity {
409
@Override
410
public String startAsyncProcess(String processId) {
411
ActivityExecutionContext context = Activity.getExecutionContext();
412
context.doNotCompleteOnReturn();
413
414
ManualActivityCompletionClient completionClient = context.useLocalManualCompletion();
415
416
// Start async process in separate thread
417
CompletableFuture.runAsync(() -> {
418
try {
419
// Long running async operation
420
String result = performAsyncOperation(processId);
421
completionClient.complete(result);
422
} catch (Exception e) {
423
completionClient.fail(e);
424
}
425
});
426
427
return null; // Activity will complete asynchronously
428
}
429
}
430
```
431
432
### Activity Configuration Options
433
434
Configuration options for activity invocation.
435
436
```java { .api }
437
/**
438
* Configuration options for activity invocation.
439
*/
440
public final class ActivityOptions {
441
/**
442
* Creates new builder.
443
* @return new ActivityOptions builder
444
*/
445
public static Builder newBuilder();
446
447
/**
448
* Creates builder from existing options.
449
* @param options existing options to copy
450
* @return new builder with copied options
451
*/
452
public static Builder newBuilder(ActivityOptions options);
453
454
/**
455
* Returns default instance (deprecated).
456
* @return default ActivityOptions instance
457
* @deprecated Use newBuilder() instead
458
*/
459
@Deprecated
460
public static ActivityOptions getDefaultInstance();
461
462
/**
463
* Builder for ActivityOptions.
464
*/
465
public static final class Builder {
466
/**
467
* Total time willing to wait including retries.
468
* @param timeout schedule to close timeout
469
* @return this builder
470
*/
471
public Builder setScheduleToCloseTimeout(Duration timeout);
472
473
/**
474
* Time activity can stay in queue.
475
* @param timeout schedule to start timeout
476
* @return this builder
477
*/
478
public Builder setScheduleToStartTimeout(Duration timeout);
479
480
/**
481
* Maximum time for single attempt.
482
* @param timeout start to close timeout
483
* @return this builder
484
*/
485
public Builder setStartToCloseTimeout(Duration timeout);
486
487
/**
488
* Heartbeat interval requirement.
489
* @param timeout heartbeat timeout
490
* @return this builder
491
*/
492
public Builder setHeartbeatTimeout(Duration timeout);
493
494
/**
495
* Task queue for activity dispatch.
496
* @param taskQueue task queue name
497
* @return this builder
498
*/
499
public Builder setTaskQueue(String taskQueue);
500
501
/**
502
* Retry policy configuration.
503
* @param retryOptions retry options
504
* @return this builder
505
*/
506
public Builder setRetryOptions(RetryOptions retryOptions);
507
508
/**
509
* Context propagation overrides.
510
* @param contextPropagators list of context propagators
511
* @return this builder
512
*/
513
public Builder setContextPropagators(List<ContextPropagator> contextPropagators);
514
515
/**
516
* Cancellation behavior.
517
* @param cancellationType cancellation type
518
* @return this builder
519
*/
520
public Builder setCancellationType(ActivityCancellationType cancellationType);
521
522
/**
523
* Disable eager execution.
524
* @param disable true to disable eager execution
525
* @return this builder
526
*/
527
public Builder setDisableEagerExecution(boolean disable);
528
529
/**
530
* Summary for UI/CLI (Experimental).
531
* @param summary activity summary
532
* @return this builder
533
*/
534
@Experimental
535
public Builder setSummary(String summary);
536
537
/**
538
* Priority settings (Experimental).
539
* @param priority task priority
540
* @return this builder
541
*/
542
@Experimental
543
public Builder setPriority(Priority priority);
544
545
/**
546
* Build the ActivityOptions.
547
* @return configured ActivityOptions
548
*/
549
public ActivityOptions build();
550
}
551
}
552
```
553
554
### Local Activity Options
555
556
Configuration options for local activity invocation.
557
558
```java { .api }
559
/**
560
* Configuration options for local activity invocation.
561
*/
562
public final class LocalActivityOptions {
563
/**
564
* Creates new builder.
565
* @return new LocalActivityOptions builder
566
*/
567
public static Builder newBuilder();
568
569
/**
570
* Creates builder from existing options.
571
* @param options existing options to copy
572
* @return new builder with copied options
573
*/
574
public static Builder newBuilder(LocalActivityOptions options);
575
576
/**
577
* Returns default instance.
578
* @return default LocalActivityOptions
579
*/
580
public static LocalActivityOptions getDefaultInstance();
581
582
/**
583
* Builder for LocalActivityOptions.
584
*/
585
public static final class Builder {
586
/**
587
* Total time including retries.
588
* @param timeout schedule to close timeout
589
* @return this builder
590
*/
591
public Builder setScheduleToCloseTimeout(Duration timeout);
592
593
/**
594
* Time in local queue.
595
* @param timeout schedule to start timeout
596
* @return this builder
597
*/
598
public Builder setScheduleToStartTimeout(Duration timeout);
599
600
/**
601
* Maximum single attempt time.
602
* @param timeout start to close timeout
603
* @return this builder
604
*/
605
public Builder setStartToCloseTimeout(Duration timeout);
606
607
/**
608
* Max local retry delay before using workflow timer.
609
* @param threshold local retry threshold
610
* @return this builder
611
*/
612
public Builder setLocalRetryThreshold(Duration threshold);
613
614
/**
615
* Retry policy.
616
* @param retryOptions retry options
617
* @return this builder
618
*/
619
public Builder setRetryOptions(RetryOptions retryOptions);
620
621
/**
622
* Exclude arguments from history marker.
623
* @param doNotInclude true to exclude arguments
624
* @return this builder
625
*/
626
public Builder setDoNotIncludeArgumentsIntoMarker(boolean doNotInclude);
627
628
/**
629
* Summary for UI/CLI (Experimental).
630
* @param summary activity summary
631
* @return this builder
632
*/
633
@Experimental
634
public Builder setSummary(String summary);
635
636
/**
637
* Build the LocalActivityOptions.
638
* @return configured LocalActivityOptions
639
*/
640
public LocalActivityOptions build();
641
}
642
}
643
```
644
645
### Activity Cancellation Types
646
647
Defines behavior when an activity's call scope is cancelled.
648
649
```java { .api }
650
/**
651
* Defines behavior when an activity's call scope is cancelled.
652
*/
653
public enum ActivityCancellationType {
654
/**
655
* Wait for activity to confirm cancellation via heartbeat.
656
*/
657
WAIT_CANCELLATION_COMPLETED,
658
659
/**
660
* Send cancellation request and immediately fail with CanceledFailure.
661
*/
662
TRY_CANCEL,
663
664
/**
665
* Don't request cancellation, immediately fail with CanceledFailure.
666
*/
667
ABANDON
668
}
669
```
670
671
### Activity Interface Annotations
672
673
Annotations for defining activity interfaces and methods.
674
675
```java { .api }
676
/**
677
* Marks an interface as an activity interface for workflow stub creation.
678
*/
679
@Target(ElementType.TYPE)
680
@Retention(RetentionPolicy.RUNTIME)
681
public @interface ActivityInterface {
682
/**
683
* Prefix for activity type names.
684
* @return name prefix (default: empty string)
685
*/
686
String namePrefix() default "";
687
}
688
689
/**
690
* Overrides the default activity type name for a method.
691
*/
692
@Target(ElementType.METHOD)
693
@Retention(RetentionPolicy.RUNTIME)
694
public @interface ActivityMethod {
695
/**
696
* Custom activity type name.
697
* @return activity type name (default: method name with first letter capitalized)
698
*/
699
String name() default "";
700
}
701
```
702
703
**Usage Examples:**
704
705
```java
706
@ActivityInterface
707
public interface OrderProcessingActivities {
708
@ActivityMethod(name = "ValidatePayment")
709
boolean validatePayment(PaymentInfo payment);
710
711
@ActivityMethod
712
void sendConfirmationEmail(String email, OrderInfo order);
713
714
@ActivityMethod
715
ShippingInfo calculateShipping(Address address, List<OrderItem> items);
716
}
717
718
@ActivityInterface(namePrefix = "Notification")
719
public interface NotificationActivities {
720
@ActivityMethod // Will be "NotificationSendEmail"
721
void sendEmail(EmailRequest request);
722
723
@ActivityMethod // Will be "NotificationSendSms"
724
void sendSms(SmsRequest request);
725
}
726
```