From a58f2de5bcd41f713949cb8be9597146431aabd6 Mon Sep 17 00:00:00 2001 From: Maciej Dudkowski Date: Tue, 23 Sep 2025 13:40:21 -0400 Subject: [PATCH 1/2] Added retry policy to activity info --- packages/activity/src/index.ts | 9 ++++++ packages/test/src/test-local-activities.ts | 32 ++++++++++++++++++- .../src/mocking-activity-environment.ts | 1 + packages/worker/src/worker.ts | 1 + 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/packages/activity/src/index.ts b/packages/activity/src/index.ts index d9591ce09..4c780ea0d 100644 --- a/packages/activity/src/index.ts +++ b/packages/activity/src/index.ts @@ -79,6 +79,7 @@ import { Priority, ActivityCancellationDetails, IllegalStateError, + RetryPolicy, } from '@temporalio/common'; import { msToNumber } from '@temporalio/common/lib/time'; import { SymbolBasedInstanceOfError } from '@temporalio/common/lib/type-helpers'; @@ -213,6 +214,14 @@ export interface Info { * Priority of this activity */ readonly priority?: Priority; + /** + * The retry policy of this activity. + * + * Note that the server may have set a different policy than the one provided when scheduling the activity. + * If the value is undefined, it means the server didn't send information about retry policy (e.g. due to old server + * version), but it may still be defined server-side. + */ + readonly retryPolicy?: RetryPolicy; } /** diff --git a/packages/test/src/test-local-activities.ts b/packages/test/src/test-local-activities.ts index 10f4de2bc..182681c7c 100644 --- a/packages/test/src/test-local-activities.ts +++ b/packages/test/src/test-local-activities.ts @@ -9,7 +9,7 @@ import { WorkflowHandle, WorkflowStartOptions, } from '@temporalio/client'; -import { LocalActivityOptions } from '@temporalio/common'; +import { LocalActivityOptions, RetryPolicy } from '@temporalio/common'; import { msToNumber } from '@temporalio/common/lib/time'; import { temporal } from '@temporalio/proto'; import { workflowInterceptorModules } from '@temporalio/testing'; @@ -624,3 +624,33 @@ export const interceptors: workflow.WorkflowInterceptorsFactory = () => { ], }; }; + +export async function getRetryPolicyFromActivityInfo(retryPolicy: RetryPolicy, fromInsideLocal: boolean): Promise { + return await (fromInsideLocal + ? workflow.proxyLocalActivities({ startToCloseTimeout: '1m', retry: retryPolicy }).retryPolicy() + : workflow.proxyActivities({ startToCloseTimeout: '1m', retry: retryPolicy }).retryPolicy()); +} + +test.serial('retryPolicy is set correctly', async (t) => { + const { executeWorkflow, createWorker } = helpers(t); + const worker = await createWorker({ + activities: { + async retryPolicy(): Promise { + return ActivityContext.current().info.retryPolicy; + }, + }, + }); + + const retryPolicy: RetryPolicy = { + backoffCoefficient: 1.5, + initialInterval: 2.0, + maximumAttempts: 3, + maximumInterval: 10.0, + nonRetryableErrorTypes: ["nonRetryableError"], + }; + + await worker.runUntil(async () => { + t.deepEqual(await executeWorkflow(getRetryPolicyFromActivityInfo, { args: [retryPolicy, true] }), retryPolicy); + t.deepEqual(await executeWorkflow(getRetryPolicyFromActivityInfo, { args: [retryPolicy, false] }), retryPolicy); + }); +}); diff --git a/packages/testing/src/mocking-activity-environment.ts b/packages/testing/src/mocking-activity-environment.ts index cc6aaa531..eaae7b0ad 100644 --- a/packages/testing/src/mocking-activity-environment.ts +++ b/packages/testing/src/mocking-activity-environment.ts @@ -96,4 +96,5 @@ export const defaultActivityInfo: activity.Info = { scheduleToCloseTimeoutMs: 1000, currentAttemptScheduledTimestampMs: 1, priority: undefined, + retryPolicy: undefined, }; diff --git a/packages/worker/src/worker.ts b/packages/worker/src/worker.ts index 9a949235d..47a392d94 100644 --- a/packages/worker/src/worker.ts +++ b/packages/worker/src/worker.ts @@ -2132,6 +2132,7 @@ async function extractActivityInfo( 'currentAttemptScheduledTime' ), priority: decodePriority(start.priority), + retryPolicy: decompileRetryPolicy(start.retryPolicy), }; } From df11c4ea9600a56aeb093ced24e8ece6128b8078 Mon Sep 17 00:00:00 2001 From: Maciej Dudkowski Date: Tue, 23 Sep 2025 14:07:11 -0400 Subject: [PATCH 2/2] Formatting --- packages/test/src/test-local-activities.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/test/src/test-local-activities.ts b/packages/test/src/test-local-activities.ts index 182681c7c..ae73518b9 100644 --- a/packages/test/src/test-local-activities.ts +++ b/packages/test/src/test-local-activities.ts @@ -625,7 +625,10 @@ export const interceptors: workflow.WorkflowInterceptorsFactory = () => { }; }; -export async function getRetryPolicyFromActivityInfo(retryPolicy: RetryPolicy, fromInsideLocal: boolean): Promise { +export async function getRetryPolicyFromActivityInfo( + retryPolicy: RetryPolicy, + fromInsideLocal: boolean +): Promise { return await (fromInsideLocal ? workflow.proxyLocalActivities({ startToCloseTimeout: '1m', retry: retryPolicy }).retryPolicy() : workflow.proxyActivities({ startToCloseTimeout: '1m', retry: retryPolicy }).retryPolicy()); @@ -646,7 +649,7 @@ test.serial('retryPolicy is set correctly', async (t) => { initialInterval: 2.0, maximumAttempts: 3, maximumInterval: 10.0, - nonRetryableErrorTypes: ["nonRetryableError"], + nonRetryableErrorTypes: ['nonRetryableError'], }; await worker.runUntil(async () => {