Skip to content

Commit 38d855b

Browse files
committed
fix: change work item filters from auto opt-in to explicit opt-in
1 parent ed22a5d commit 38d855b

5 files changed

Lines changed: 50 additions & 32 deletions

File tree

packages/durabletask-js-azuremanaged/src/worker-builder.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export class DurableTaskAzureManagedWorkerBuilder {
2828
private _logger: Logger = new ConsoleLogger();
2929
private _shutdownTimeoutMs?: number;
3030
private _versioning?: VersioningOptions;
31-
private _workItemFilters?: WorkItemFilters | null;
31+
private _workItemFilters?: WorkItemFilters | "auto";
3232

3333
/**
3434
* Creates a new instance of DurableTaskAzureManagedWorkerBuilder.
@@ -223,17 +223,17 @@ export class DurableTaskAzureManagedWorkerBuilder {
223223
}
224224

225225
/**
226-
* Sets work item filters for the worker.
227-
* When provided, the sidecar will only send work items matching these filters.
228-
* Pass null to explicitly disable filtering and receive all work items.
229-
* When not called, filters are auto-generated from the registered orchestrations,
230-
* activities, and entities.
226+
* Enables work item filters for the worker.
227+
* When called without arguments, filters are auto-generated from the registered
228+
* orchestrations, activities, and entities.
229+
* When called with a WorkItemFilters object, those specific filters are used.
230+
* By default (when not called), no filters are sent and the worker processes all work items.
231231
*
232-
* @param filters The work item filters, or null to disable filtering.
232+
* @param filters Optional explicit filters. Omit to auto-generate from registry.
233233
* @returns This builder instance.
234234
*/
235-
useWorkItemFilters(filters: WorkItemFilters | null): DurableTaskAzureManagedWorkerBuilder {
236-
this._workItemFilters = filters;
235+
useWorkItemFilters(filters?: WorkItemFilters): DurableTaskAzureManagedWorkerBuilder {
236+
this._workItemFilters = filters ?? "auto";
237237
return this;
238238
}
239239

packages/durabletask-js/src/worker/task-hub-grpc-worker.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@ export interface TaskHubGrpcWorkerOptions {
6363
versioning?: VersioningOptions;
6464
/**
6565
* Optional work item filters to control which work items the worker receives.
66-
* When set, only work items matching these filters will be dispatched to this worker.
67-
* When undefined (default), filters are auto-generated from the registered
68-
* orchestrations, activities, and entities.
69-
* Set to null to explicitly disable filtering (receive all work items).
66+
* By default, no filters are sent and the worker processes all work items.
67+
* Set to a WorkItemFilters object to use explicit filters.
68+
* Set to "auto" to auto-generate filters from the registered orchestrations,
69+
* activities, and entities.
7070
*/
71-
workItemFilters?: WorkItemFilters | null;
71+
workItemFilters?: WorkItemFilters | "auto";
7272
}
7373

7474
export class TaskHubGrpcWorker {
@@ -87,7 +87,7 @@ export class TaskHubGrpcWorker {
8787
private _shutdownTimeoutMs: number;
8888
private _backoff: ExponentialBackoff;
8989
private _versioning?: VersioningOptions;
90-
private _workItemFilters?: WorkItemFilters | null;
90+
private _workItemFilters?: WorkItemFilters | "auto";
9191

9292
/**
9393
* Creates a new TaskHubGrpcWorker instance.
@@ -135,7 +135,7 @@ export class TaskHubGrpcWorker {
135135
let resolvedLogger: Logger | undefined;
136136
let resolvedShutdownTimeoutMs: number | undefined;
137137
let resolvedVersioning: VersioningOptions | undefined;
138-
let resolvedWorkItemFilters: WorkItemFilters | null | undefined;
138+
let resolvedWorkItemFilters: WorkItemFilters | "auto" | undefined;
139139

140140
if (typeof hostAddressOrOptions === "object" && hostAddressOrOptions !== null) {
141141
// Options object constructor
@@ -506,15 +506,18 @@ export class TaskHubGrpcWorker {
506506

507507
/**
508508
* Builds the GetWorkItemsRequest, attaching work item filters based on configuration.
509-
* - null: no filters sent (receive all work items)
510-
* - undefined: auto-generate from the registry
509+
* - undefined (default): no filters sent, worker receives all work items
510+
* - "auto": auto-generate filters from the registry
511511
* - explicit WorkItemFilters: use as provided
512512
*/
513513
private _buildGetWorkItemsRequest(): pb.GetWorkItemsRequest {
514514
const request = new pb.GetWorkItemsRequest();
515515

516-
if (this._workItemFilters !== null) {
517-
const filters = this._workItemFilters ?? generateWorkItemFiltersFromRegistry(this._registry, this._versioning);
516+
if (this._workItemFilters !== undefined) {
517+
const filters =
518+
this._workItemFilters === "auto"
519+
? generateWorkItemFiltersFromRegistry(this._registry, this._versioning)
520+
: this._workItemFilters;
518521
request.setWorkitemfilters(toGrpcWorkItemFilters(filters));
519522
}
520523

packages/durabletask-js/test/work-item-filters.spec.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ describe("WorkItemFilters", () => {
633633
});
634634

635635
describe("TaskHubGrpcWorker._buildGetWorkItemsRequest", () => {
636-
it("should auto-generate filters from registry when workItemFilters is undefined", () => {
636+
it("should not send filters when workItemFilters is undefined (default)", () => {
637637
// Arrange
638638
const worker = new TaskHubGrpcWorker({
639639
hostAddress: "localhost:4001",
@@ -644,6 +644,22 @@ describe("WorkItemFilters", () => {
644644
// Act
645645
const request = (worker as any)._buildGetWorkItemsRequest();
646646

647+
// Assert — no filters sent by default (opt-in only)
648+
expect(request.hasWorkitemfilters()).toBe(false);
649+
});
650+
651+
it("should auto-generate filters from registry when workItemFilters is 'auto'", () => {
652+
// Arrange
653+
const worker = new TaskHubGrpcWorker({
654+
hostAddress: "localhost:4001",
655+
workItemFilters: "auto",
656+
});
657+
worker.addOrchestrator(myOrchestrator);
658+
worker.addActivity(myActivity);
659+
660+
// Act
661+
const request = (worker as any)._buildGetWorkItemsRequest();
662+
647663
// Assert
648664
expect(request.hasWorkitemfilters()).toBe(true);
649665
const filters = request.getWorkitemfilters()!;
@@ -653,18 +669,17 @@ describe("WorkItemFilters", () => {
653669
expect(actNames).toContain("myActivity");
654670
});
655671

656-
it("should omit filters when workItemFilters is null", () => {
672+
it("should not send filters when workItemFilters is not configured (default)", () => {
657673
// Arrange
658674
const worker = new TaskHubGrpcWorker({
659675
hostAddress: "localhost:4001",
660-
workItemFilters: null,
661676
});
662677
worker.addOrchestrator(myOrchestrator);
663678

664679
// Act
665680
const request = (worker as any)._buildGetWorkItemsRequest();
666681

667-
// Assert
682+
// Assert — default is no filters (opt-in only)
668683
expect(request.hasWorkitemfilters()).toBe(false);
669684
});
670685

@@ -706,6 +721,7 @@ describe("WorkItemFilters", () => {
706721
// Arrange
707722
const worker = new TaskHubGrpcWorker({
708723
hostAddress: "localhost:4001",
724+
workItemFilters: "auto",
709725
versioning: {
710726
version: "3.0.0",
711727
matchStrategy: VersionMatchStrategy.Strict,

test/e2e-azuremanaged/orchestration.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ function createWorkerWithVersioning(
6666
? new DurableTaskAzureManagedWorkerBuilder().connectionString(connectionString)
6767
: new DurableTaskAzureManagedWorkerBuilder().endpoint(endpoint, taskHub, null);
6868

69-
// Disable auto-generated work item filters so version mismatches are handled
70-
// by the SDK's local versioning logic, not by server-side filter enforcement.
71-
return builder.versioning({ version, matchStrategy, failureStrategy }).useWorkItemFilters(null).build();
69+
// No need to disable work item filters — they are opt-in (off by default),
70+
// so version mismatches are handled by the SDK's local versioning logic.
71+
return builder.versioning({ version, matchStrategy, failureStrategy }).build();
7272
}
7373

7474
describe("Durable Task Scheduler (DTS) E2E Tests", () => {

test/e2e-azuremanaged/work-item-filters.spec.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ describe("Work Item Filters E2E Tests", () => {
6767
await taskHubClient.stop();
6868
});
6969

70-
describe("Disabled filters (null)", () => {
71-
it("should process all orchestrations when filters are explicitly disabled", async () => {
72-
// Arrange — worker with filters explicitly set to null (receive all work items)
70+
describe("Default behavior (no filters)", () => {
71+
it("should process all orchestrations when no filters are configured (default)", async () => {
72+
// Arrange — worker with default config (no useWorkItemFilters call)
7373
const echo = async (_: ActivityContext, input: string) => input;
7474

7575
const echoOrchestrator: TOrchestrator = async function* (ctx: OrchestrationContext, input: string): any {
@@ -80,7 +80,6 @@ describe("Work Item Filters E2E Tests", () => {
8080
taskHubWorker = createWorkerBuilder()
8181
.addOrchestrator(echoOrchestrator)
8282
.addActivity(echo)
83-
.useWorkItemFilters(null)
8483
.build();
8584
await taskHubWorker.start();
8685

@@ -139,7 +138,7 @@ describe("Work Item Filters E2E Tests", () => {
139138
return "registered";
140139
};
141140

142-
taskHubWorker = createWorkerBuilder().addOrchestrator(registeredOrch).build();
141+
taskHubWorker = createWorkerBuilder().addOrchestrator(registeredOrch).useWorkItemFilters().build();
143142
await taskHubWorker.start();
144143

145144
// Act — schedule an orchestration by name that doesn't match any filter

0 commit comments

Comments
 (0)