trigger.dev 3.0.0-beta.2 → 3.0.0-beta.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,8 +2,9 @@ import type { TriggerConfig } from "@trigger.dev/sdk/v3";
2
2
 
3
3
  export const config: TriggerConfig = {
4
4
  project: "${projectRef}",
5
+ logLevel: "log",
5
6
  retries: {
6
- enabledInDev: false,
7
+ enabledInDev: true,
7
8
  default: {
8
9
  maxAttempts: 3,
9
10
  minTimeoutInMs: 1000,
@@ -1,23 +1,31 @@
1
1
  // src/workers/dev/worker-facade.ts
2
2
  import {
3
- TaskExecutor,
4
- DurableClock,
5
- clock
3
+ clock,
4
+ taskCatalog
6
5
  } from "@trigger.dev/core/v3";
7
6
  import {
8
- ConsoleInterceptor,
9
- DevRuntimeManager,
7
+ TaskExecutor,
8
+ DurableClock,
9
+ getEnvVar,
10
+ logLevels,
10
11
  OtelTaskLogger,
12
+ ConsoleInterceptor
13
+ } from "@trigger.dev/core/v3/workers";
14
+ import {
11
15
  TaskRunErrorCodes,
12
16
  TriggerTracer,
13
- ZodMessageHandler,
14
17
  logger,
15
18
  runtime,
16
19
  workerToChildMessages
17
20
  } from "@trigger.dev/core/v3";
21
+ import { DevRuntimeManager } from "@trigger.dev/core/v3/dev";
22
+ import {
23
+ ZodMessageHandler,
24
+ ZodSchemaParsedError
25
+ } from "@trigger.dev/core/v3/zodMessageHandler";
18
26
 
19
27
  // package.json
20
- var version = "3.0.0-beta.2";
28
+ var version = "3.0.0-beta.21";
21
29
 
22
30
  // src/workers/dev/worker-facade.ts
23
31
  __WORKER_SETUP__;
@@ -27,62 +35,38 @@ var otelLogger = tracingSDK.getLogger("trigger-dev-worker", version);
27
35
  var durableClock = new DurableClock();
28
36
  clock.setGlobalClock(durableClock);
29
37
  var tracer = new TriggerTracer({ tracer: otelTracer, logger: otelLogger });
30
- var consoleInterceptor = new ConsoleInterceptor(otelLogger);
38
+ var consoleInterceptor = new ConsoleInterceptor(
39
+ otelLogger,
40
+ __PROJECT_CONFIG__.enableConsoleLogging ?? false
41
+ );
31
42
  var devRuntimeManager = new DevRuntimeManager();
32
43
  runtime.setGlobalRuntimeManager(devRuntimeManager);
44
+ var triggerLogLevel = getEnvVar("TRIGGER_LOG_LEVEL");
45
+ var configLogLevel = triggerLogLevel ? triggerLogLevel : importedConfig ? importedConfig.logLevel : __PROJECT_CONFIG__.logLevel;
33
46
  var otelTaskLogger = new OtelTaskLogger({
34
47
  logger: otelLogger,
35
48
  tracer,
36
- level: "info"
49
+ level: logLevels.includes(configLogLevel) ? configLogLevel : "log"
37
50
  });
38
51
  logger.setGlobalTaskLogger(otelTaskLogger);
39
52
  var TaskFileImports = {};
40
53
  var TaskFiles = {};
41
54
  __TASKS__;
42
- function getTasks() {
43
- const result = [];
55
+ (() => {
44
56
  for (const [importName, taskFile] of Object.entries(TaskFiles)) {
45
57
  const fileImports = TaskFileImports[importName];
46
58
  for (const [exportName, task] of Object.entries(fileImports ?? {})) {
47
- if (task.__trigger) {
48
- result.push({
49
- id: task.__trigger.id,
50
- exportName,
51
- packageVersion: task.__trigger.packageVersion,
52
- filePath: taskFile.filePath,
53
- queue: task.__trigger.queue,
54
- retry: task.__trigger.retry,
55
- machine: task.__trigger.machine,
56
- fns: task.__trigger.fns
57
- });
59
+ if (typeof task === "object" && task !== null && "id" in task && typeof task.id === "string") {
60
+ if (taskCatalog.taskExists(task.id)) {
61
+ taskCatalog.registerTaskFileMetadata(task.id, {
62
+ exportName,
63
+ filePath: taskFile.filePath
64
+ });
65
+ }
58
66
  }
59
67
  }
60
68
  }
61
- return result;
62
- }
63
- function getTaskMetadata() {
64
- const result = getTasks();
65
- return result.map((task) => {
66
- const { fns, ...metadata } = task;
67
- return metadata;
68
- });
69
- }
70
- var tasks = getTasks();
71
- runtime.registerTasks(tasks);
72
- var taskExecutors = /* @__PURE__ */ new Map();
73
- for (const task of tasks) {
74
- taskExecutors.set(
75
- task.id,
76
- new TaskExecutor(task, {
77
- tracer,
78
- tracingSDK,
79
- consoleInterceptor,
80
- projectConfig: __PROJECT_CONFIG__,
81
- importedConfig,
82
- handleErrorFn: handleError
83
- })
84
- );
85
- }
69
+ })();
86
70
  var _execution;
87
71
  var _isRunning = false;
88
72
  var handler = new ZodMessageHandler({
@@ -95,7 +79,7 @@ var handler = new ZodMessageHandler({
95
79
  execution,
96
80
  result: {
97
81
  ok: false,
98
- id: execution.attempt.id,
82
+ id: execution.run.id,
99
83
  error: {
100
84
  type: "INTERNAL_ERROR",
101
85
  code: TaskRunErrorCodes.TASK_ALREADY_RUNNING
@@ -105,14 +89,14 @@ var handler = new ZodMessageHandler({
105
89
  return;
106
90
  }
107
91
  process.title = `trigger-dev-worker: ${execution.task.id} ${execution.run.id}`;
108
- const executor = taskExecutors.get(execution.task.id);
109
- if (!executor) {
110
- console.error(`Could not find executor for task ${execution.task.id}`);
92
+ const task = taskCatalog.getTask(execution.task.id);
93
+ if (!task) {
94
+ console.error(`Could not find task ${execution.task.id}`);
111
95
  await sender.send("TASK_RUN_COMPLETED", {
112
96
  execution,
113
97
  result: {
114
98
  ok: false,
115
- id: execution.attempt.id,
99
+ id: execution.run.id,
116
100
  error: {
117
101
  type: "INTERNAL_ERROR",
118
102
  code: TaskRunErrorCodes.COULD_NOT_FIND_EXECUTOR
@@ -121,6 +105,14 @@ var handler = new ZodMessageHandler({
121
105
  });
122
106
  return;
123
107
  }
108
+ const executor = new TaskExecutor(task, {
109
+ tracer,
110
+ tracingSDK,
111
+ consoleInterceptor,
112
+ projectConfig: __PROJECT_CONFIG__,
113
+ importedConfig,
114
+ handleErrorFn: handleError
115
+ });
124
116
  try {
125
117
  _execution = execution;
126
118
  _isRunning = true;
@@ -152,8 +144,13 @@ var handler = new ZodMessageHandler({
152
144
  process.on("message", async (msg) => {
153
145
  await handler.handleMessage(msg);
154
146
  });
155
- sender.send("TASKS_READY", { tasks: getTaskMetadata() }).catch((err) => {
156
- console.error("Failed to send TASKS_READY message", err);
147
+ var TASK_METADATA = taskCatalog.getAllTaskMetadata();
148
+ sender.send("TASKS_READY", { tasks: TASK_METADATA }).catch((err) => {
149
+ if (err instanceof ZodSchemaParsedError) {
150
+ sender.send("TASKS_FAILED_TO_PARSE", { zodIssues: err.error.issues, tasks: TASK_METADATA });
151
+ } else {
152
+ console.error("Failed to send TASKS_READY message", err);
153
+ }
157
154
  });
158
155
  process.title = "trigger-dev-worker";
159
156
  async function asyncHeartbeat(initialDelayInSeconds = 30, intervalInSeconds = 5) {
@@ -3,10 +3,14 @@ import "source-map-support/register.js";
3
3
  import { Resource } from "@opentelemetry/resources";
4
4
  import {
5
5
  SemanticInternalAttributes,
6
- TracingSDK,
7
- ZodMessageSender,
8
- childToWorkerMessages
6
+ childToWorkerMessages,
7
+ taskCatalog
9
8
  } from "@trigger.dev/core/v3";
9
+ import {
10
+ TracingSDK,
11
+ StandardTaskCatalog
12
+ } from "@trigger.dev/core/v3/workers";
13
+ import { ZodMessageSender } from "@trigger.dev/core/v3/zodMessageHandler";
10
14
  __SETUP_IMPORTED_PROJECT_CONFIG__;
11
15
  var tracingSDK = new TracingSDK({
12
16
  url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT ?? "http://0.0.0.0:4318",
@@ -34,6 +38,7 @@ process.on("uncaughtException", (error, origin) => {
34
38
  console.error("Failed to send UNCAUGHT_EXCEPTION message", err);
35
39
  });
36
40
  });
41
+ taskCatalog.setGlobalTaskCatalog(new StandardTaskCatalog());
37
42
  export {
38
43
  sender,
39
44
  tracingSDK
@@ -3,9 +3,9 @@ import {
3
3
  CoordinatorToProdWorkerMessages,
4
4
  PostStartCauses,
5
5
  PreStopCauses,
6
- ProdWorkerToCoordinatorMessages,
7
- ZodSocketConnection as ZodSocketConnection2
6
+ ProdWorkerToCoordinatorMessages
8
7
  } from "@trigger.dev/core/v3";
8
+ import { ZodSocketConnection as ZodSocketConnection2 } from "@trigger.dev/core/v3/zodSocket";
9
9
 
10
10
  // ../core-apps/src/http.ts
11
11
  var HttpReply = class {
@@ -71,10 +71,10 @@ import {
71
71
  clientWebsocketMessages,
72
72
  PlatformToProviderMessages,
73
73
  ProviderToPlatformMessages,
74
- SharedQueueToClientMessages,
75
- ZodMessageSender,
76
- ZodSocketConnection
74
+ SharedQueueToClientMessages
77
75
  } from "@trigger.dev/core/v3";
76
+ import { ZodMessageSender } from "@trigger.dev/core/v3/zodMessageHandler";
77
+ import { ZodSocketConnection } from "@trigger.dev/core/v3/zodSocket";
78
78
  var HTTP_SERVER_PORT = Number(process.env.HTTP_SERVER_PORT || getRandomPortNumber());
79
79
  var MACHINE_NAME = process.env.MACHINE_NAME || "local";
80
80
  var PLATFORM_HOST = process.env.PLATFORM_HOST || "127.0.0.1";
@@ -93,9 +93,9 @@ import {
93
93
  ProdWorkerToChildMessages,
94
94
  SemanticInternalAttributes,
95
95
  TaskRunErrorCodes,
96
- ZodIpcConnection,
97
96
  correctErrorStackTrace
98
97
  } from "@trigger.dev/core/v3";
98
+ import { ZodIpcConnection } from "@trigger.dev/core/v3/zodIpc";
99
99
  import { Evt } from "evt";
100
100
  import { fork } from "node:child_process";
101
101
 
@@ -108,6 +108,14 @@ var UncaughtExceptionError = class extends Error {
108
108
  this.name = "UncaughtExceptionError";
109
109
  }
110
110
  };
111
+ var TaskMetadataParseError = class extends Error {
112
+ constructor(zodIssues, tasks) {
113
+ super(`Failed to parse task metadata`);
114
+ this.zodIssues = zodIssues;
115
+ this.tasks = tasks;
116
+ this.name = "TaskMetadataParseError";
117
+ }
118
+ };
111
119
 
112
120
  // src/workers/prod/backgroundWorker.ts
113
121
  var UnexpectedExitError = class extends Error {
@@ -206,6 +214,14 @@ var ProdBackgroundWorker = class {
206
214
  reject(new UncaughtExceptionError(message.error, message.origin));
207
215
  child.kill();
208
216
  }
217
+ },
218
+ TASKS_FAILED_TO_PARSE: async (message) => {
219
+ if (!resolved) {
220
+ clearTimeout(timeout);
221
+ resolved = true;
222
+ reject(new TaskMetadataParseError(message.zodIssues, message.tasks));
223
+ child.kill();
224
+ }
209
225
  }
210
226
  }
211
227
  });
@@ -247,6 +263,7 @@ var ProdBackgroundWorker = class {
247
263
  );
248
264
  if (!this._taskRunProcess) {
249
265
  const taskRunProcess = new TaskRunProcess(
266
+ payload.execution,
250
267
  this.path,
251
268
  {
252
269
  ...this.params.env,
@@ -289,7 +306,6 @@ var ProdBackgroundWorker = class {
289
306
  try {
290
307
  const taskRunProcess = await this.#initializeTaskRunProcess(payload);
291
308
  const result = await taskRunProcess.executeTaskRun(payload);
292
- await taskRunProcess.cleanup(result.ok || result.retry === void 0);
293
309
  if (result.ok) {
294
310
  return result;
295
311
  }
@@ -358,7 +374,8 @@ var ProdBackgroundWorker = class {
358
374
  }
359
375
  };
360
376
  var TaskRunProcess = class {
361
- constructor(path, env, metadata, worker) {
377
+ constructor(execution, path, env, metadata, worker) {
378
+ this.execution = execution;
362
379
  this.path = path;
363
380
  this.env = env;
364
381
  this.metadata = metadata;
@@ -391,6 +408,7 @@ var TaskRunProcess = class {
391
408
  "ipc"
392
409
  ],
393
410
  env: {
411
+ ...this.execution.run.isTest ? { TRIGGER_LOG_LEVEL: "debug" } : {},
394
412
  ...this.env,
395
413
  OTEL_RESOURCE_ATTRIBUTES: JSON.stringify({
396
414
  [SemanticInternalAttributes.PROJECT_DIR]: this.worker.projectConfig.projectDir
@@ -418,6 +436,7 @@ var TaskRunProcess = class {
418
436
  resolver(result);
419
437
  },
420
438
  READY_TO_DISPOSE: async (message) => {
439
+ process.exit(0);
421
440
  },
422
441
  TASK_HEARTBEAT: async (message) => {
423
442
  this.onTaskHeartbeat.post(message.id);
@@ -558,6 +577,7 @@ var logger2 = new SimpleLogger(`[${MACHINE_NAME2}][${SHORT_HASH}]`);
558
577
  var ProdWorker = class {
559
578
  constructor(port, host = "0.0.0.0") {
560
579
  this.host = host;
580
+ process.on("SIGTERM", this.#handleSignal.bind(this, "SIGTERM"));
561
581
  this.#coordinatorSocket = this.#createCoordinatorSocket(COORDINATOR_HOST);
562
582
  this.#backgroundWorker = new ProdBackgroundWorker("worker.js", {
563
583
  projectConfig: __PROJECT_CONFIG__,
@@ -650,31 +670,54 @@ var ProdWorker = class {
650
670
  #backgroundWorker;
651
671
  #httpServer;
652
672
  #coordinatorSocket;
653
- async #reconnect(isPostStart = false) {
673
+ async #handleSignal(signal) {
674
+ logger2.log("Received signal", { signal });
675
+ if (signal === "SIGTERM") {
676
+ if (this.executing) {
677
+ const terminationGracePeriodSeconds = 60 * 60;
678
+ logger2.log("Waiting for attempt to complete before exiting", {
679
+ terminationGracePeriodSeconds
680
+ });
681
+ await setTimeout2(terminationGracePeriodSeconds * 1e3 - 5e3);
682
+ logger2.log("Termination timeout reached, exiting gracefully.");
683
+ } else {
684
+ logger2.log("Not executing, exiting immediately.");
685
+ }
686
+ await this.#exitGracefully();
687
+ }
688
+ logger2.log("Unhandled signal", { signal });
689
+ }
690
+ async #exitGracefully() {
691
+ await this.#backgroundWorker.close();
692
+ process.exit(0);
693
+ }
694
+ async #reconnect(isPostStart = false, reconnectImmediately = false) {
654
695
  if (isPostStart) {
655
696
  this.waitForPostStart = false;
656
697
  }
657
698
  this.#coordinatorSocket.close();
658
- if (!this.runningInKubernetes) {
659
- this.#coordinatorSocket.connect();
660
- return;
699
+ if (!reconnectImmediately) {
700
+ await setTimeout2(1e3);
661
701
  }
702
+ let coordinatorHost = COORDINATOR_HOST;
662
703
  try {
663
- const coordinatorHost = (await readFile("/etc/taskinfo/coordinator-host", "utf-8")).replace(
664
- "\n",
665
- ""
666
- );
667
- logger2.log("reconnecting", {
668
- coordinatorHost: {
669
- fromEnv: COORDINATOR_HOST,
670
- fromVolume: coordinatorHost,
671
- current: this.#coordinatorSocket.socket.io.opts.hostname
672
- }
673
- });
674
- this.#coordinatorSocket = this.#createCoordinatorSocket(coordinatorHost);
704
+ if (this.runningInKubernetes) {
705
+ coordinatorHost = (await readFile("/etc/taskinfo/coordinator-host", "utf-8")).replace(
706
+ "\n",
707
+ ""
708
+ );
709
+ logger2.log("reconnecting", {
710
+ coordinatorHost: {
711
+ fromEnv: COORDINATOR_HOST,
712
+ fromVolume: coordinatorHost,
713
+ current: this.#coordinatorSocket.socket.io.opts.hostname
714
+ }
715
+ });
716
+ }
675
717
  } catch (error) {
676
718
  logger2.error("taskinfo read error during reconnect", { error });
677
- this.#coordinatorSocket.connect();
719
+ } finally {
720
+ this.#coordinatorSocket = this.#createCoordinatorSocket(coordinatorHost);
678
721
  }
679
722
  }
680
723
  #prepareForWait(reason, willCheckpointAndRestore) {
@@ -692,8 +735,7 @@ var ProdWorker = class {
692
735
  if (willCheckpointAndRestore) {
693
736
  logger2.log("WARNING: Will checkpoint but also requested exit. This won't end well.");
694
737
  }
695
- await this.#backgroundWorker.close();
696
- process.exit(0);
738
+ await this.#exitGracefully();
697
739
  }
698
740
  this.executing = false;
699
741
  this.attemptFriendlyId = void 0;
@@ -817,7 +859,6 @@ var ProdWorker = class {
817
859
  const completion = await this.#backgroundWorker.executeTaskRun(executionPayload);
818
860
  logger2.log("completed", completion);
819
861
  this.completed.add(executionPayload.execution.attempt.id);
820
- await this.#backgroundWorker.flushTelemetry();
821
862
  const { willCheckpointAndRestore, shouldExit } = await this.#coordinatorSocket.socket.emitWithAck("TASK_RUN_COMPLETED", {
822
863
  version: "v1",
823
864
  execution: executionPayload.execution,
@@ -868,30 +909,46 @@ var ProdWorker = class {
868
909
  process.exit(1);
869
910
  }
870
911
  } catch (e) {
871
- if (e instanceof UncaughtExceptionError) {
872
- logger3.error("uncaught exception", { message: e.originalError.message });
912
+ if (e instanceof TaskMetadataParseError) {
913
+ logger3.error("tasks metadata parse error", {
914
+ zodIssues: e.zodIssues,
915
+ tasks: e.tasks
916
+ });
873
917
  socket.emit("INDEXING_FAILED", {
874
918
  version: "v1",
875
919
  deploymentId: this.deploymentId,
876
920
  error: {
877
- name: e.originalError.name,
878
- message: e.originalError.message,
879
- stack: e.originalError.stack
921
+ name: "TaskMetadataParseError",
922
+ message: "There was an error parsing the task metadata",
923
+ stack: JSON.stringify({ zodIssues: e.zodIssues, tasks: e.tasks })
880
924
  }
881
925
  });
926
+ } else if (e instanceof UncaughtExceptionError) {
927
+ const error = {
928
+ name: e.originalError.name,
929
+ message: e.originalError.message,
930
+ stack: e.originalError.stack
931
+ };
932
+ logger3.error("uncaught exception", { originalError: error });
933
+ socket.emit("INDEXING_FAILED", {
934
+ version: "v1",
935
+ deploymentId: this.deploymentId,
936
+ error
937
+ });
882
938
  } else if (e instanceof Error) {
883
- logger3.error("error", { message: e.message });
939
+ const error = {
940
+ name: e.name,
941
+ message: e.message,
942
+ stack: e.stack
943
+ };
944
+ logger3.error("error", { error });
884
945
  socket.emit("INDEXING_FAILED", {
885
946
  version: "v1",
886
947
  deploymentId: this.deploymentId,
887
- error: {
888
- name: e.name,
889
- message: e.message,
890
- stack: e.stack
891
- }
948
+ error
892
949
  });
893
950
  } else if (typeof e === "string") {
894
- logger3.error("string error", { message: e });
951
+ logger3.error("string error", { error: { message: e } });
895
952
  socket.emit("INDEXING_FAILED", {
896
953
  version: "v1",
897
954
  deploymentId: this.deploymentId,
@@ -912,7 +969,7 @@ var ProdWorker = class {
912
969
  });
913
970
  }
914
971
  await setTimeout2(200);
915
- process.exit(1);
972
+ process.exit(111);
916
973
  }
917
974
  }
918
975
  if (this.paused) {
@@ -1008,7 +1065,6 @@ var ProdWorker = class {
1008
1065
  break;
1009
1066
  }
1010
1067
  }
1011
- logger2.log("preStop", { url: req.url });
1012
1068
  return reply.text("preStop ok");
1013
1069
  }
1014
1070
  case "/postStart": {
@@ -1025,7 +1081,7 @@ var ProdWorker = class {
1025
1081
  break;
1026
1082
  }
1027
1083
  case "restore": {
1028
- await this.#reconnect(true);
1084
+ await this.#reconnect(true, true);
1029
1085
  break;
1030
1086
  }
1031
1087
  default: {