Skip to content

Commit 1777ff4

Browse files
committed
move onStart to the new lifecycle hook system
1 parent 17e1623 commit 1777ff4

File tree

11 files changed

+208
-53
lines changed

11 files changed

+208
-53
lines changed

packages/cli-v3/src/entryPoints/dev-run-worker.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,13 @@ async function bootstrap() {
183183
});
184184
}
185185

186+
if (config.onStart) {
187+
lifecycleHooks.registerGlobalStartHook({
188+
id: "trigger-dev-worker",
189+
fn: lifecycleHooksAdapters.createStartHookAdapter(config.onStart),
190+
});
191+
}
192+
186193
return {
187194
tracer,
188195
tracingSDK,

packages/core/src/v3/lifecycle-hooks-api.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ export type {
99
AnyOnInitHookFunction,
1010
RegisteredHookFunction,
1111
TaskInitHookParams,
12+
TaskStartHookParams,
13+
OnStartHookFunction,
14+
AnyOnStartHookFunction,
1215
} from "./lifecycleHooks/types.js";
1316

1417
export * as lifecycleHooksAdapters from "./lifecycleHooks/adapters.js";

packages/core/src/v3/lifecycleHooks/adapters.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { TaskOptions } from "../types/index.js";
2-
import { AnyOnInitHookFunction } from "./types.js";
2+
import { AnyOnInitHookFunction, AnyOnStartHookFunction } from "./types.js";
33

44
export function createInitHookAdapter<TPayload>(
55
fn: NonNullable<TaskOptions<string, TPayload, unknown, any>["init"]>
@@ -14,3 +14,17 @@ export function createInitHookAdapter<TPayload>(
1414
return await fn(params.payload as unknown as TPayload, paramsWithoutPayload);
1515
};
1616
}
17+
18+
export function createStartHookAdapter<TPayload>(
19+
fn: NonNullable<TaskOptions<string, TPayload, unknown, any>["onStart"]>
20+
): AnyOnStartHookFunction {
21+
return async (params) => {
22+
const paramsWithoutPayload = {
23+
...params,
24+
};
25+
26+
delete paramsWithoutPayload["payload"];
27+
28+
return await fn(params.payload as unknown as TPayload, paramsWithoutPayload);
29+
};
30+
}

packages/core/src/v3/lifecycleHooks/index.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { getGlobal, registerGlobal, unregisterGlobal } from "../utils/globals.js
44
import { NoopLifecycleHooksManager } from "./manager.js";
55
import {
66
AnyOnInitHookFunction,
7+
AnyOnStartHookFunction,
78
RegisteredHookFunction,
89
RegisterHookFunctionParams,
910
type LifecycleHooksManager,
@@ -51,6 +52,25 @@ export class LifecycleHooksAPI {
5152
return this.#getManager().getGlobalInitHooks();
5253
}
5354

55+
public registerGlobalStartHook(hook: RegisterHookFunctionParams<AnyOnStartHookFunction>): void {
56+
this.#getManager().registerGlobalStartHook(hook);
57+
}
58+
59+
public getTaskStartHook(taskId: string): AnyOnStartHookFunction | undefined {
60+
return this.#getManager().getTaskStartHook(taskId);
61+
}
62+
63+
public getGlobalStartHooks(): RegisteredHookFunction<AnyOnStartHookFunction>[] {
64+
return this.#getManager().getGlobalStartHooks();
65+
}
66+
67+
public registerTaskStartHook(
68+
taskId: string,
69+
hook: RegisterHookFunctionParams<AnyOnStartHookFunction>
70+
): void {
71+
this.#getManager().registerTaskStartHook(taskId, hook);
72+
}
73+
5474
#getManager(): LifecycleHooksManager {
5575
return getGlobal(API_NAME) ?? NOOP_LIFECYCLE_HOOKS_MANAGER;
5676
}

packages/core/src/v3/lifecycleHooks/manager.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
AnyOnInitHookFunction,
3+
AnyOnStartHookFunction,
34
LifecycleHooksManager,
45
RegisteredHookFunction,
56
RegisterHookFunctionParams,
@@ -9,6 +10,40 @@ export class StandardLifecycleHooksManager implements LifecycleHooksManager {
910
private globalInitHooks: Map<string, RegisteredHookFunction<AnyOnInitHookFunction>> = new Map();
1011
private taskInitHooks: Map<string, RegisteredHookFunction<AnyOnInitHookFunction>> = new Map();
1112

13+
private globalStartHooks: Map<string, RegisteredHookFunction<AnyOnStartHookFunction>> = new Map();
14+
private taskStartHooks: Map<string, RegisteredHookFunction<AnyOnStartHookFunction>> = new Map();
15+
16+
registerGlobalStartHook(hook: RegisterHookFunctionParams<AnyOnStartHookFunction>): void {
17+
const id = generateHookId(hook);
18+
19+
this.globalStartHooks.set(id, {
20+
id,
21+
name: hook.id ?? hook.fn.name ? (hook.fn.name === "" ? undefined : hook.fn.name) : undefined,
22+
fn: hook.fn,
23+
});
24+
}
25+
26+
registerTaskStartHook(
27+
taskId: string,
28+
hook: RegisterHookFunctionParams<AnyOnStartHookFunction>
29+
): void {
30+
const id = generateHookId(hook);
31+
32+
this.taskStartHooks.set(taskId, {
33+
id,
34+
name: hook.id ?? hook.fn.name ? (hook.fn.name === "" ? undefined : hook.fn.name) : undefined,
35+
fn: hook.fn,
36+
});
37+
}
38+
39+
getTaskStartHook(taskId: string): AnyOnStartHookFunction | undefined {
40+
return this.taskStartHooks.get(taskId)?.fn;
41+
}
42+
43+
getGlobalStartHooks(): RegisteredHookFunction<AnyOnStartHookFunction>[] {
44+
return Array.from(this.globalStartHooks.values());
45+
}
46+
1247
registerGlobalInitHook(hook: RegisterHookFunctionParams<AnyOnInitHookFunction>): void {
1348
// if there is no id, lets generate one based on the contents of the function
1449
const id = generateHookId(hook);
@@ -63,6 +98,25 @@ export class NoopLifecycleHooksManager implements LifecycleHooksManager {
6398
getGlobalInitHooks(): RegisteredHookFunction<AnyOnInitHookFunction>[] {
6499
return [];
65100
}
101+
102+
registerGlobalStartHook(hook: RegisterHookFunctionParams<AnyOnStartHookFunction>): void {
103+
// Noop
104+
}
105+
106+
registerTaskStartHook(
107+
taskId: string,
108+
hook: RegisterHookFunctionParams<AnyOnStartHookFunction>
109+
): void {
110+
// Noop
111+
}
112+
113+
getTaskStartHook(taskId: string): AnyOnStartHookFunction | undefined {
114+
return undefined;
115+
}
116+
117+
getGlobalStartHooks(): RegisteredHookFunction<AnyOnStartHookFunction>[] {
118+
return [];
119+
}
66120
}
67121

68122
function generateHookId(hook: RegisterHookFunctionParams<any>): string {

packages/core/src/v3/lifecycleHooks/types.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,19 @@ export type OnInitHookFunction<TPayload, TInitOutput extends Record<string, unkn
1313

1414
export type AnyOnInitHookFunction = OnInitHookFunction<unknown, Record<string, unknown>>;
1515

16+
export type TaskStartHookParams<TPayload = unknown> = {
17+
ctx: TaskRunContext;
18+
payload: TPayload;
19+
task: string;
20+
signal?: AbortSignal;
21+
};
22+
23+
export type OnStartHookFunction<TPayload> = (
24+
params: TaskStartHookParams<TPayload>
25+
) => undefined | void | Promise<undefined | void>;
26+
27+
export type AnyOnStartHookFunction = OnStartHookFunction<unknown>;
28+
1629
export type RegisterHookFunctionParams<THookFunction extends (params: any) => any> = {
1730
id?: string;
1831
fn: THookFunction;
@@ -32,4 +45,11 @@ export interface LifecycleHooksManager {
3245
): void;
3346
getTaskInitHook(taskId: string): AnyOnInitHookFunction | undefined;
3447
getGlobalInitHooks(): RegisteredHookFunction<AnyOnInitHookFunction>[];
48+
registerGlobalStartHook(hook: RegisterHookFunctionParams<AnyOnStartHookFunction>): void;
49+
registerTaskStartHook(
50+
taskId: string,
51+
hook: RegisterHookFunctionParams<AnyOnStartHookFunction>
52+
): void;
53+
getTaskStartHook(taskId: string): AnyOnStartHookFunction | undefined;
54+
getGlobalStartHooks(): RegisteredHookFunction<AnyOnStartHookFunction>[];
3555
}

packages/core/src/v3/workers/taskExecutor.ts

Lines changed: 45 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -513,54 +513,56 @@ export class TaskExecutor {
513513
}
514514

515515
async #callOnStartFunctions(payload: unknown, ctx: TaskRunContext, signal?: AbortSignal) {
516-
await this.#callOnStartFunction(
517-
this._importedConfig?.onStart,
518-
"config.onStart",
519-
payload,
520-
ctx,
521-
{},
522-
signal
523-
);
524-
525-
await this.#callOnStartFunction(
526-
this.task.fns.onStart,
527-
"task.onStart",
528-
payload,
529-
ctx,
530-
{},
531-
signal
532-
);
533-
}
516+
const globalStartHooks = lifecycleHooks.getGlobalStartHooks();
517+
const taskStartHook = lifecycleHooks.getTaskStartHook(this.task.id);
534518

535-
async #callOnStartFunction(
536-
onStartFn: TaskMetadataWithFunctions["fns"]["onStart"],
537-
name: string,
538-
payload: unknown,
539-
ctx: TaskRunContext,
540-
initOutput: any,
541-
signal?: AbortSignal
542-
) {
543-
if (!onStartFn) {
519+
if (globalStartHooks.length === 0 && !taskStartHook) {
544520
return;
545521
}
546522

547-
try {
548-
await this._tracer.startActiveSpan(
549-
name,
550-
async (span) => {
551-
return await runTimelineMetrics.measureMetric("trigger.dev/execution", name, () =>
552-
onStartFn(payload, { ctx, signal })
553-
);
523+
return this._tracer.startActiveSpan(
524+
"hooks.start",
525+
async (span) => {
526+
return await runTimelineMetrics.measureMetric(
527+
"trigger.dev/execution",
528+
"start",
529+
async () => {
530+
for (const hook of globalStartHooks) {
531+
await this._tracer.startActiveSpan(
532+
hook.name ?? "global",
533+
async (span) => {
534+
await hook.fn({ payload, ctx, signal, task: this.task.id });
535+
},
536+
{
537+
attributes: {
538+
[SemanticInternalAttributes.STYLE_ICON]: "tabler-function",
539+
},
540+
}
541+
);
542+
}
543+
544+
if (taskStartHook) {
545+
await this._tracer.startActiveSpan(
546+
"task",
547+
async (span) => {
548+
await taskStartHook({ payload, ctx, signal, task: this.task.id });
549+
},
550+
{
551+
attributes: {
552+
[SemanticInternalAttributes.STYLE_ICON]: "tabler-function",
553+
},
554+
}
555+
);
556+
}
557+
}
558+
);
559+
},
560+
{
561+
attributes: {
562+
[SemanticInternalAttributes.STYLE_ICON]: "tabler-function",
554563
},
555-
{
556-
attributes: {
557-
[SemanticInternalAttributes.STYLE_ICON]: "function",
558-
},
559-
}
560-
);
561-
} catch {
562-
// Ignore errors from onStart functions
563-
}
564+
}
565+
);
564566
}
565567

566568
async #callTaskCleanup(

packages/trigger-sdk/src/v3/hooks.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,19 @@ import {
33
type AnyOnInitHookFunction,
44
type TaskInitHookParams,
55
type OnInitHookFunction,
6+
type AnyOnStartHookFunction,
7+
type TaskStartHookParams,
8+
type OnStartHookFunction,
69
} from "@trigger.dev/core/v3";
710

8-
export type { AnyOnInitHookFunction, TaskInitHookParams, OnInitHookFunction };
11+
export type {
12+
AnyOnInitHookFunction,
13+
TaskInitHookParams,
14+
OnInitHookFunction,
15+
AnyOnStartHookFunction,
16+
TaskStartHookParams,
17+
OnStartHookFunction,
18+
};
919

1020
export function onInit(name: string, fn: AnyOnInitHookFunction): void;
1121
export function onInit(fn: AnyOnInitHookFunction): void;
@@ -15,3 +25,15 @@ export function onInit(fnOrName: string | AnyOnInitHookFunction, fn?: AnyOnInitH
1525
fn: typeof fnOrName === "function" ? fnOrName : fn!,
1626
});
1727
}
28+
29+
export function onStart(name: string, fn: AnyOnStartHookFunction): void;
30+
export function onStart(fn: AnyOnStartHookFunction): void;
31+
export function onStart(
32+
fnOrName: string | AnyOnStartHookFunction,
33+
fn?: AnyOnStartHookFunction
34+
): void {
35+
lifecycleHooks.registerGlobalStartHook({
36+
id: typeof fnOrName === "string" ? fnOrName : fnOrName.name ? fnOrName.name : undefined,
37+
fn: typeof fnOrName === "function" ? fnOrName : fn!,
38+
});
39+
}

packages/trigger-sdk/src/v3/shared.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,12 @@ export function createTask<
193193
});
194194
}
195195

196+
if (params.onStart) {
197+
lifecycleHooks.registerTaskStartHook(params.id, {
198+
fn: lifecycleHooksAdapters.createStartHookAdapter(params.onStart),
199+
});
200+
}
201+
196202
resourceCatalog.registerTaskMetadata({
197203
id: params.id,
198204
description: params.description,
@@ -331,6 +337,12 @@ export function createSchemaTask<
331337
});
332338
}
333339

340+
if (params.onStart) {
341+
lifecycleHooks.registerTaskStartHook(params.id, {
342+
fn: lifecycleHooksAdapters.createStartHookAdapter(params.onStart),
343+
});
344+
}
345+
334346
resourceCatalog.registerTaskMetadata({
335347
id: params.id,
336348
description: params.description,

packages/trigger-sdk/src/v3/tasks.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { onInit } from "./hooks.js";
1+
import { onInit, onStart } from "./hooks.js";
22
import {
33
batchTrigger,
44
batchTriggerAndWait,
@@ -79,5 +79,6 @@ export const tasks = {
7979
batchTrigger,
8080
triggerAndWait,
8181
batchTriggerAndWait,
82-
onInit,
82+
init: onInit,
83+
onStart,
8384
};

0 commit comments

Comments
 (0)