|
6 | 6 |
|
7 | 7 | import java.lang.reflect.InvocationTargetException; |
8 | 8 | import java.time.Duration; |
| 9 | +import java.util.ArrayList; |
| 10 | +import java.util.Collections; |
9 | 11 | import java.util.HashMap; |
| 12 | +import java.util.List; |
10 | 13 | import java.util.Locale; |
11 | 14 |
|
12 | 15 | /** |
@@ -42,6 +45,8 @@ public final class DurableTaskGrpcWorkerBuilder { |
42 | 45 | DurableTaskGrpcWorkerVersioningOptions versioningOptions; |
43 | 46 | int maxConcurrentEntityWorkItems = 1; |
44 | 47 | int maxWorkItemThreads; |
| 48 | + private WorkItemFilter workItemFilter; |
| 49 | + private boolean autoGenerateWorkItemFilters; |
45 | 50 | PayloadStore payloadStore; |
46 | 51 | LargePayloadOptions largePayloadOptions; |
47 | 52 | int chunkSizeBytes = DEFAULT_CHUNK_SIZE_BYTES; |
@@ -309,6 +314,24 @@ public DurableTaskGrpcWorkerBuilder useVersioning(DurableTaskGrpcWorkerVersionin |
309 | 314 | return this; |
310 | 315 | } |
311 | 316 |
|
| 317 | + /** |
| 318 | + * Sets explicit work item filters for this worker. When set, only work items matching the filters |
| 319 | + * will be dispatched to this worker by the backend. |
| 320 | + * <p> |
| 321 | + * Work item filtering can improve efficiency in multi-worker deployments by ensuring each worker |
| 322 | + * only receives work items it can handle. However, if an orchestration calls a task type |
| 323 | + * (e.g., an activity or sub-orchestrator) that is not registered with any connected worker, |
| 324 | + * the call may hang indefinitely instead of failing with an error. |
| 325 | + * |
| 326 | + * @param workItemFilter the work item filter to use, or {@code null} to disable filtering |
| 327 | + * @return this builder object |
| 328 | + */ |
| 329 | + public DurableTaskGrpcWorkerBuilder useWorkItemFilters(WorkItemFilter workItemFilter) { |
| 330 | + this.workItemFilter = workItemFilter; |
| 331 | + this.autoGenerateWorkItemFilters = false; |
| 332 | + return this; |
| 333 | + } |
| 334 | + |
312 | 335 | /** |
313 | 336 | * Enables large payload externalization with default options. |
314 | 337 | * <p> |
@@ -346,6 +369,27 @@ public DurableTaskGrpcWorkerBuilder useExternalizedPayloads(PayloadStore payload |
346 | 369 | return this; |
347 | 370 | } |
348 | 371 |
|
| 372 | + /** |
| 373 | + * Enables automatic work item filtering by generating filters from the registered |
| 374 | + * orchestrations and activities. When enabled, the backend will only dispatch work items |
| 375 | + * for registered orchestrations and activities to this worker. |
| 376 | + * <p> |
| 377 | + * Work item filtering can improve efficiency in multi-worker deployments by ensuring each worker |
| 378 | + * only receives work items it can handle. However, if an orchestration calls a task type |
| 379 | + * (e.g., an activity or sub-orchestrator) that is not registered with any connected worker, |
| 380 | + * the call may hang indefinitely instead of failing with an error. |
| 381 | + * <p> |
| 382 | + * Only use this method when all task types referenced by orchestrations are guaranteed to be |
| 383 | + * registered with at least one connected worker. |
| 384 | + * |
| 385 | + * @return this builder object |
| 386 | + */ |
| 387 | + public DurableTaskGrpcWorkerBuilder useWorkItemFilters() { |
| 388 | + this.autoGenerateWorkItemFilters = true; |
| 389 | + this.workItemFilter = null; |
| 390 | + return this; |
| 391 | + } |
| 392 | + |
349 | 393 | /** |
350 | 394 | * Sets the maximum size in bytes for a single orchestrator response chunk sent over gRPC. |
351 | 395 | * Responses larger than this will be automatically split into multiple chunks. |
@@ -381,6 +425,31 @@ int getChunkSizeBytes() { |
381 | 425 | * @return a new {@link DurableTaskGrpcWorker} object |
382 | 426 | */ |
383 | 427 | public DurableTaskGrpcWorker build() { |
384 | | - return new DurableTaskGrpcWorker(this); |
| 428 | + WorkItemFilter resolvedFilter = this.autoGenerateWorkItemFilters |
| 429 | + ? buildAutoWorkItemFilter() |
| 430 | + : this.workItemFilter; |
| 431 | + return new DurableTaskGrpcWorker(this, resolvedFilter); |
| 432 | + } |
| 433 | + |
| 434 | + private WorkItemFilter buildAutoWorkItemFilter() { |
| 435 | + List<String> versions = Collections.emptyList(); |
| 436 | + if (this.versioningOptions != null |
| 437 | + && this.versioningOptions.getMatchStrategy() == DurableTaskGrpcWorkerVersioningOptions.VersionMatchStrategy.STRICT |
| 438 | + && this.versioningOptions.getVersion() != null) { |
| 439 | + versions = Collections.singletonList(this.versioningOptions.getVersion()); |
| 440 | + } |
| 441 | + |
| 442 | + WorkItemFilter.Builder builder = WorkItemFilter.newBuilder(); |
| 443 | + List<String> orchestrationNames = new ArrayList<>(this.orchestrationFactories.keySet()); |
| 444 | + Collections.sort(orchestrationNames); |
| 445 | + for (String name : orchestrationNames) { |
| 446 | + builder.addOrchestration(name, versions); |
| 447 | + } |
| 448 | + List<String> activityNames = new ArrayList<>(this.activityFactories.keySet()); |
| 449 | + Collections.sort(activityNames); |
| 450 | + for (String name : activityNames) { |
| 451 | + builder.addActivity(name, versions); |
| 452 | + } |
| 453 | + return builder.build(); |
385 | 454 | } |
386 | 455 | } |
0 commit comments