Skip to content

Commit 1efb3f0

Browse files
committed
inline options, lazily decode summary/details on workflow description
1 parent d496966 commit 1efb3f0

File tree

9 files changed

+145
-120
lines changed

9 files changed

+145
-120
lines changed

packages/client/src/schedule-helpers.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
import Long from 'long'; // eslint-disable-line import/no-named-as-default
2-
import {
3-
compileRetryPolicy,
4-
decompileRetryPolicy,
5-
extractWorkflowType,
6-
JsonPayloadConverter,
7-
LoadedDataConverter,
8-
} from '@temporalio/common';
2+
import { compileRetryPolicy, decompileRetryPolicy, extractWorkflowType, LoadedDataConverter } from '@temporalio/common';
93
import {
104
encodeUnifiedSearchAttributes,
115
decodeSearchAttributes,
@@ -340,8 +334,8 @@ export async function decodeScheduleAction(
340334
workflowExecutionTimeout: optionalTsToMs(pb.startWorkflow.workflowExecutionTimeout),
341335
workflowRunTimeout: optionalTsToMs(pb.startWorkflow.workflowRunTimeout),
342336
workflowTaskTimeout: optionalTsToMs(pb.startWorkflow.workflowTaskTimeout),
343-
staticSummary: await decodeOptionalSinglePayload(dataConverter, userMetadata?.summary) ?? undefined,
344-
staticDetails: await decodeOptionalSinglePayload(dataConverter, userMetadata?.details) ?? undefined,
337+
staticSummary: (await decodeOptionalSinglePayload(dataConverter, userMetadata?.summary)) ?? undefined,
338+
staticDetails: (await decodeOptionalSinglePayload(dataConverter, userMetadata?.details)) ?? undefined,
345339
};
346340
}
347341
throw new TypeError('Unsupported schedule action');

packages/client/src/types.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,25 @@ export interface CountWorkflowExecution {
6565
export type WorkflowExecutionDescription = Replace<
6666
WorkflowExecutionInfo,
6767
{
68-
staticSummary?: string;
69-
staticDetails?: string;
7068
raw: DescribeWorkflowExecutionResponse;
7169
}
72-
>;
70+
> & {
71+
/**
72+
* General fixed details for this workflow execution that may appear in UI/CLI.
73+
* This can be in Temporal markdown format and can span multiple lines.
74+
*
75+
* @experimental User metadata is a new API and suspectible to change.
76+
*/
77+
staticDetails: () => Promise<string | undefined>;
78+
79+
/**
80+
* A single-line fixed summary for this workflow execution that may appear in the UI/CLI.
81+
* This can be in single-line Temporal markdown format.
82+
*
83+
* @experimental User metadata is a new API and suspectible to change.
84+
*/
85+
staticSummary: () => Promise<string | undefined>;
86+
};
7387

7488
export type WorkflowService = proto.temporal.api.workflowservice.v1.WorkflowService;
7589
export const { WorkflowService } = proto.temporal.api.workflowservice.v1;

packages/client/src/workflow-client.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,8 +1438,10 @@ export class WorkflowClient extends BaseClient {
14381438
const userMetadata = raw.executionConfig?.userMetadata;
14391439
return {
14401440
...info,
1441-
staticDetails: await decodeOptionalSinglePayload(this.client.dataConverter, userMetadata?.details) ?? undefined,
1442-
staticSummary: await decodeOptionalSinglePayload(this.client.dataConverter, userMetadata?.summary) ?? undefined,
1441+
staticDetails: async () =>
1442+
(await decodeOptionalSinglePayload(this.client.dataConverter, userMetadata?.details)) ?? undefined,
1443+
staticSummary: async () =>
1444+
(await decodeOptionalSinglePayload(this.client.dataConverter, userMetadata?.summary)) ?? undefined,
14431445
raw,
14441446
};
14451447
},

packages/common/src/activity-options.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,14 @@ export interface ActivityOptions {
122122
* @experimental The Worker Versioning API is still being designed. Major changes are expected.
123123
*/
124124
versioningIntent?: VersioningIntent;
125+
126+
/**
127+
* A single-line fixed summary for this workflow execution that may appear in the UI/CLI.
128+
* This can be in single-line Temporal markdown format.
129+
*
130+
* @experimental User metadata is a new API and suspectible to change.
131+
*/
132+
staticSummary?: string;
125133
}
126134

127135
/**
@@ -186,4 +194,12 @@ export interface LocalActivityOptions {
186194
* - `ABANDON` - Do not request cancellation of the activity and immediately report cancellation to the workflow.
187195
*/
188196
cancellationType?: ActivityCancellationType;
197+
198+
/**
199+
* A single-line fixed summary for this workflow execution that may appear in the UI/CLI.
200+
* This can be in single-line Temporal markdown format.
201+
*
202+
* @experimental User metadata is a new API and suspectible to change.
203+
*/
204+
staticSummary?: string;
189205
}

packages/common/src/internal-non-workflow/codec-helpers.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,13 @@ export async function encodeToPayload(converter: LoadedDataConverter, value: unk
9595
* Run {@link PayloadConverter.toPayload} on an optional value, and then encode it.
9696
*/
9797
export async function encodeOptionalToPayload(
98-
converter: LoadedDataConverter,
98+
converter: LoadedDataConverter,
9999
value: unknown
100100
): Promise<Payload | null | undefined> {
101101
if (value == null) return value;
102-
102+
103103
const { payloadConverter, payloadCodecs } = converter;
104-
const payload = payloadConverter.toPayload(value);
104+
const payload = payloadConverter.toPayload(value);
105105
return await encodeSingle(payloadCodecs, payload);
106106
}
107107

packages/common/src/workflow-options.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,14 +195,14 @@ export interface BaseWorkflowOptions {
195195
* General fixed details for this workflow execution that may appear in UI/CLI.
196196
* This can be in Temporal markdown format and can span multiple lines.
197197
*
198-
* @experimental
198+
* @experimental User metadata is a new API and suspectible to change.
199199
*/
200200
staticDetails?: string;
201201
/**
202202
* A single-line fixed summary for this workflow execution that may appear in the UI/CLI.
203203
* This can be in single-line Temporal markdown format.
204204
*
205-
* @experimental
205+
* @experimental User metadata is a new API and suspectible to change.
206206
*/
207207
staticSummary?: string;
208208
}

packages/test/src/test-integration-workflows.ts

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ import {
1414
ActivityCancellationType,
1515
ApplicationFailure,
1616
defineSearchAttributeKey,
17-
JsonPayloadConverter,
1817
SearchAttributePair,
1918
SearchAttributeType,
2019
TypedSearchAttributes,
2120
WorkflowExecutionAlreadyStartedError,
2221
} from '@temporalio/common';
2322
import { temporal } from '@temporalio/proto';
23+
import { decodeOptionalSinglePayload } from '@temporalio/common/lib/internal-non-workflow';
2424
import { signalSchedulingWorkflow } from './activities/helpers';
2525
import { activityStartedSignal } from './workflows/definitions';
2626
import * as workflows from './workflows';
@@ -1348,12 +1348,15 @@ export async function userMetadataWorkflow(): Promise<string> {
13481348
});
13491349

13501350
// That workflow should call an activity (with summary)
1351-
const { activityWithSummary } = workflow.proxyActivities({ scheduleToCloseTimeout: '10s' }).withSummaries({
1352-
activityWithSummary: 'activity summary',
1353-
});
1354-
await activityWithSummary();
1351+
const { activityWithSummary } = workflow.proxyActivities({ scheduleToCloseTimeout: '10s' });
1352+
await activityWithSummary.runWithOptions(
1353+
{
1354+
staticSummary: 'activity summary',
1355+
},
1356+
[]
1357+
);
13551358
// Should have a timer (with summary)
1356-
await workflow.sleep(5, 'timer summary');
1359+
await workflow.sleep(5, { summary: 'timer summary' });
13571360
// Set current details
13581361
workflow.setCurrentDetails('current wf details');
13591362
// Unblock on var -> query current details (or return)
@@ -1377,8 +1380,8 @@ test('User metadata on workflow, timer, activity', async (t) => {
13771380
});
13781381
// Describe workflow -> static summary, static details
13791382
const desc = await handle.describe();
1380-
t.true(desc.staticSummary === 'wf static summary');
1381-
t.true(desc.staticDetails === 'wf static details');
1383+
t.true((await desc.staticSummary()) === 'wf static summary');
1384+
t.true((await desc.staticDetails()) === 'wf static details');
13821385

13831386
await handle.signal('done');
13841387
const res = await handle.result();
@@ -1392,15 +1395,38 @@ test('User metadata on workflow, timer, activity', async (t) => {
13921395
runId: handle.firstExecutionRunId,
13931396
},
13941397
});
1395-
const jsonConverter = new JsonPayloadConverter();
13961398
for (const event of resp.history?.events ?? []) {
13971399
if (event.eventType === temporal.api.enums.v1.EventType.EVENT_TYPE_WORKFLOW_EXECUTION_STARTED) {
1398-
t.deepEqual(jsonConverter.fromPayload(event.userMetadata?.summary ?? {}), 'wf static summary');
1399-
t.deepEqual(jsonConverter.fromPayload(event.userMetadata?.details ?? {}), 'wf static details');
1400+
t.deepEqual(
1401+
await decodeOptionalSinglePayload(
1402+
t.context.env.client.options.loadedDataConverter,
1403+
event.userMetadata?.summary ?? {}
1404+
),
1405+
'wf static summary'
1406+
);
1407+
t.deepEqual(
1408+
await decodeOptionalSinglePayload(
1409+
t.context.env.client.options.loadedDataConverter,
1410+
event.userMetadata?.details ?? {}
1411+
),
1412+
'wf static details'
1413+
);
14001414
} else if (event.eventType === temporal.api.enums.v1.EventType.EVENT_TYPE_ACTIVITY_TASK_SCHEDULED) {
1401-
t.deepEqual(jsonConverter.fromPayload(event.userMetadata?.summary ?? {}), 'activity summary');
1415+
t.deepEqual(
1416+
await decodeOptionalSinglePayload(
1417+
t.context.env.client.options.loadedDataConverter,
1418+
event.userMetadata?.summary ?? {}
1419+
),
1420+
'activity summary'
1421+
);
14021422
} else if (event.eventType === temporal.api.enums.v1.EventType.EVENT_TYPE_TIMER_STARTED) {
1403-
t.deepEqual(jsonConverter.fromPayload(event.userMetadata?.summary ?? {}), 'timer summary');
1423+
t.deepEqual(
1424+
await decodeOptionalSinglePayload(
1425+
t.context.env.client.options.loadedDataConverter,
1426+
event.userMetadata?.summary ?? {}
1427+
),
1428+
'timer summary'
1429+
);
14041430
}
14051431
}
14061432

packages/workflow/src/interceptors.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ export interface ActivityInput {
8080
readonly options: ActivityOptions;
8181
readonly headers: Headers;
8282
readonly seq: number;
83-
readonly cmdOpts?: WorkflowCommandOptions;
8483
}
8584

8685
/** Input for WorkflowOutboundCallsInterceptor.scheduleLocalActivity */
@@ -92,7 +91,6 @@ export interface LocalActivityInput {
9291
readonly seq: number;
9392
readonly originalScheduleTime?: Timestamp;
9493
readonly attempt: number;
95-
readonly cmdOpts?: WorkflowCommandOptions;
9694
}
9795

9896
/** Input for WorkflowOutboundCallsInterceptor.startChildWorkflowExecution */
@@ -117,19 +115,17 @@ export interface UserMetadata {
117115
details?: string;
118116
}
119117

120-
/**
121-
* Options that can be attached to workflow commands.
122-
*/
123-
export interface WorkflowCommandOptions {
124-
/** User metadata for the command that may be persisted to history */
125-
readonly userMetadata?: UserMetadata;
126-
}
127-
128118
/** Input for WorkflowOutboundCallsInterceptor.startTimer */
129119
export interface TimerInput {
130120
readonly durationMs: number;
131121
readonly seq: number;
132-
readonly cmdOpts?: WorkflowCommandOptions;
122+
readonly options?: TimerOptions;
123+
}
124+
125+
/** Options for starting a timer (i.e. sleep) */
126+
export interface TimerOptions {
127+
/** @experimental A single line summary of the command's purpose */
128+
readonly summary?: string;
133129
}
134130

135131
/**

0 commit comments

Comments
 (0)