Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6f9f25481e | |||
| 67aaffb6fc | |||
| e3cf456c69 | |||
| bf7827e7b8 | |||
| bc020a3ffe | |||
| b361afbfe4 | |||
| a3d809740d | |||
| f93eae300e | |||
| a2365e406d | |||
| 42d319c2d1 | |||
| b66d5525ef | |||
| 719c0a0b94 | |||
| f1c768a255 | |||
| d9c9e80bc4 | |||
| d39932ebf7 | |||
| 9bcb8cb42a | |||
| 2374f8e8ac | |||
| a22b5869e4 | |||
| f1571cbfab |
@@ -0,0 +1,8 @@
|
||||
---
|
||||
"@trigger.dev/sdk": patch
|
||||
"@trigger.dev/core-apps": patch
|
||||
"trigger.dev": patch
|
||||
"@trigger.dev/core": patch
|
||||
---
|
||||
|
||||
add machine config and secure zod connection
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"trigger.dev": patch
|
||||
---
|
||||
|
||||
Changed "Worker" to "Version" in the dev command key
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"trigger.dev": patch
|
||||
"@trigger.dev/core": patch
|
||||
---
|
||||
|
||||
Handle string and non-stringifiable outputs like functions
|
||||
+8
-1
@@ -45,7 +45,14 @@
|
||||
},
|
||||
"changesets": [
|
||||
"chilled-hornets-move",
|
||||
"clean-pianos-listen",
|
||||
"lemon-jobs-repair",
|
||||
"sweet-lizards-press"
|
||||
"light-bulldogs-press",
|
||||
"many-ligers-pump",
|
||||
"real-planets-stare",
|
||||
"strange-ghosts-matter",
|
||||
"stupid-bulldogs-applaud",
|
||||
"sweet-lizards-press",
|
||||
"tall-bees-wave"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@trigger.dev/sdk": patch
|
||||
"trigger.dev": patch
|
||||
"@trigger.dev/core": patch
|
||||
---
|
||||
|
||||
Fixed incorrect span timings around checkpoints by implementing a precise wall clock that resets after restores
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"trigger.dev": patch
|
||||
---
|
||||
|
||||
Added DEBUG to the ignored env vars
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"trigger.dev": patch
|
||||
---
|
||||
|
||||
Fixed an issue where the trigger.dev package was not being built before publishing to npm
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@trigger.dev/sdk": patch
|
||||
"trigger.dev": patch
|
||||
"@trigger.dev/core": patch
|
||||
---
|
||||
|
||||
Dynamically import superjson and fix some bundling issues
|
||||
+10
-1
@@ -63,4 +63,13 @@ COORDINATOR_SECRET=coordinator-secret # generate the actual secret with `openssl
|
||||
# These are needed for the object store (for handling large payloads/outputs)
|
||||
# OBJECT_STORE_BASE_URL="https://{bucket}.{accountId}.r2.cloudflarestorage.com"
|
||||
# OBJECT_STORE_ACCESS_KEY_ID=
|
||||
# OBJECT_STORE_SECRET_ACCESS_KEY=
|
||||
# OBJECT_STORE_SECRET_ACCESS_KEY=
|
||||
# RUNTIME_WAIT_THRESHOLD_IN_MS=10000
|
||||
|
||||
# These control the server-side internal telemetry
|
||||
# INTERNAL_OTEL_TRACE_EXPORTER_URL=<URL to send traces to>
|
||||
# INTERNAL_OTEL_TRACE_EXPORTER_AUTH_HEADER_NAME=<Header name for the auth token>
|
||||
# INTERNAL_OTEL_TRACE_EXPORTER_AUTH_HEADER_VALUE=<Auth token value>
|
||||
# INTERNAL_OTEL_TRACE_LOGGING_ENABLED=1
|
||||
# INTERNAL_OTEL_TRACE_SAMPING_RATE=20 # this means 1/20 traces or 5% of traces will be sampled (sampled = recorded)
|
||||
# INTERNAL_OTEL_TRACE_INSTRUMENT_PRISMA_ENABLED=0,
|
||||
@@ -1,3 +1,4 @@
|
||||
HTTP_SERVER_PORT=8020
|
||||
PLATFORM_ENABLED=true
|
||||
PLATFORM_WS_PORT=3030
|
||||
PLATFORM_WS_PORT=3030
|
||||
SECURE_CONNECTION=false
|
||||
@@ -26,6 +26,7 @@ const PLATFORM_ENABLED = ["1", "true"].includes(process.env.PLATFORM_ENABLED ??
|
||||
const PLATFORM_HOST = process.env.PLATFORM_HOST || "127.0.0.1";
|
||||
const PLATFORM_WS_PORT = process.env.PLATFORM_WS_PORT || 3030;
|
||||
const PLATFORM_SECRET = process.env.PLATFORM_SECRET || "coordinator-secret";
|
||||
const SECURE_CONNECTION = ["1", "true"].includes(process.env.SECURE_CONNECTION ?? "false");
|
||||
|
||||
const logger = new SimpleLogger(`[${NODE_NAME}]`);
|
||||
|
||||
@@ -365,6 +366,7 @@ class TaskCoordinator {
|
||||
namespace: "coordinator",
|
||||
host: PLATFORM_HOST,
|
||||
port: Number(PLATFORM_WS_PORT),
|
||||
secure: SECURE_CONNECTION,
|
||||
clientMessages: CoordinatorToPlatformMessages,
|
||||
serverMessages: PlatformToCoordinatorMessages,
|
||||
authToken: PLATFORM_SECRET,
|
||||
|
||||
@@ -2,6 +2,7 @@ HTTP_SERVER_PORT=8050
|
||||
|
||||
PLATFORM_WS_PORT=3030
|
||||
PLATFORM_SECRET=provider-secret
|
||||
SECURE_CONNECTION=false
|
||||
|
||||
# Use this if you are on macOS
|
||||
# COORDINATOR_HOST="host.docker.internal"
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
TaskOperationsIndexOptions,
|
||||
} from "@trigger.dev/core-apps";
|
||||
import { setTimeout } from "node:timers/promises";
|
||||
import { PostStartCauses, PreStopCauses } from "@trigger.dev/core/v3";
|
||||
|
||||
const MACHINE_NAME = process.env.MACHINE_NAME || "local";
|
||||
const COORDINATOR_PORT = process.env.COORDINATOR_PORT || 8020;
|
||||
@@ -190,6 +191,9 @@ class DockerTaskOperations implements TaskOperations {
|
||||
async delete(opts: { runId: string }) {
|
||||
await this.#initialize();
|
||||
|
||||
const containerName = this.#getRunContainerName(opts.runId);
|
||||
await this.#sendPreStop(containerName);
|
||||
|
||||
logger.log("noop: delete");
|
||||
}
|
||||
|
||||
@@ -208,6 +212,26 @@ class DockerTaskOperations implements TaskOperations {
|
||||
}
|
||||
|
||||
async #sendPostStart(containerName: string): Promise<void> {
|
||||
try {
|
||||
const port = await this.#getHttpServerPort(containerName);
|
||||
logger.debug(await this.#runLifecycleCommand(containerName, port, "postStart", "restore"));
|
||||
} catch (error) {
|
||||
logger.error("postStart error", { error });
|
||||
throw new Error("postStart command failed");
|
||||
}
|
||||
}
|
||||
|
||||
async #sendPreStop(containerName: string): Promise<void> {
|
||||
try {
|
||||
const port = await this.#getHttpServerPort(containerName);
|
||||
logger.debug(await this.#runLifecycleCommand(containerName, port, "preStop", "terminate"));
|
||||
} catch (error) {
|
||||
logger.error("preStop error", { error });
|
||||
throw new Error("preStop command failed");
|
||||
}
|
||||
}
|
||||
|
||||
async #getHttpServerPort(containerName: string): Promise<number> {
|
||||
// We first get the correct port, which is random during dev as we run with host networking and need to avoid clashes
|
||||
// FIXME: Skip this in prod
|
||||
const logs = logger.debug(await $`docker logs ${containerName}`);
|
||||
@@ -219,19 +243,14 @@ class DockerTaskOperations implements TaskOperations {
|
||||
throw new Error("failed to extract port from logs");
|
||||
}
|
||||
|
||||
try {
|
||||
logger.debug(await this.#runLifecycleCommand(containerName, port, "postStart", "restore"));
|
||||
} catch (error) {
|
||||
logger.error("postStart error", { error });
|
||||
throw new Error("postStart command failed");
|
||||
}
|
||||
return port;
|
||||
}
|
||||
|
||||
async #runLifecycleCommand(
|
||||
async #runLifecycleCommand<THookType extends "postStart" | "preStop">(
|
||||
containerName: string,
|
||||
port: number,
|
||||
type: "postStart" | "preStop",
|
||||
cause: "index" | "create" | "restore",
|
||||
type: THookType,
|
||||
cause: THookType extends "postStart" ? PostStartCauses : PreStopCauses,
|
||||
retryCount = 0
|
||||
): Promise<ExecaChildProcess> {
|
||||
try {
|
||||
@@ -244,15 +263,15 @@ class DockerTaskOperations implements TaskOperations {
|
||||
`127.0.0.1:${port}/${type}?cause=${cause}`,
|
||||
]);
|
||||
} catch (error: any) {
|
||||
if (retryCount < 6) {
|
||||
logger.debug("retriable postStart error", { retryCount, message: error?.message });
|
||||
if (type === "postStart" && retryCount < 6) {
|
||||
logger.debug(`retriable ${type} error`, { retryCount, message: error?.message });
|
||||
await setTimeout(exponentialBackoff(retryCount + 1, 2, 50, 1150, 50));
|
||||
|
||||
return this.#runLifecycleCommand(containerName, port, type, cause, retryCount + 1);
|
||||
}
|
||||
|
||||
logger.error("final postStart error", { message: error?.message });
|
||||
throw new Error(`postStart command failed after ${retryCount - 1} retries`);
|
||||
logger.error(`final ${type} error`, { message: error?.message });
|
||||
throw new Error(`${type} command failed after ${retryCount - 1} retries`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ HTTP_SERVER_PORT=8060
|
||||
|
||||
PLATFORM_WS_PORT=3030
|
||||
PLATFORM_SECRET=provider-secret
|
||||
SECURE_CONNECTION=false
|
||||
|
||||
# Use this if you are on macOS
|
||||
# COORDINATOR_HOST="host.docker.internal"
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
TaskOperationsIndexOptions,
|
||||
TaskOperationsRestoreOptions,
|
||||
} from "@trigger.dev/core-apps";
|
||||
import { Machine, PostStartCauses, PreStopCauses, EnvironmentType } from "@trigger.dev/core/v3";
|
||||
import { randomUUID } from "crypto";
|
||||
|
||||
const RUNTIME_ENV = process.env.KUBERNETES_PORT ? "kubernetes" : "local";
|
||||
@@ -55,6 +56,12 @@ class KubernetesTaskOperations implements TaskOperations {
|
||||
metadata: {
|
||||
labels: {
|
||||
app: "task-index",
|
||||
"app.kubernetes.io/part-of": "trigger-worker",
|
||||
"app.kubernetes.io/component": "index",
|
||||
env: opts.envId,
|
||||
envtype: this.#envTypeToLabelValue(opts.envType),
|
||||
org: opts.orgId,
|
||||
project: opts.projectId,
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
@@ -64,6 +71,9 @@ class KubernetesTaskOperations implements TaskOperations {
|
||||
name: "registry-trigger",
|
||||
},
|
||||
],
|
||||
nodeSelector: {
|
||||
nodetype: "worker",
|
||||
},
|
||||
containers: [
|
||||
{
|
||||
name: this.#getIndexContainerName(opts.shortCode),
|
||||
@@ -79,6 +89,13 @@ class KubernetesTaskOperations implements TaskOperations {
|
||||
// memory: "50Mi",
|
||||
// },
|
||||
// },
|
||||
lifecycle: {
|
||||
preStop: {
|
||||
exec: {
|
||||
command: this.#getLifecycleCommand("preStop", "terminate"),
|
||||
},
|
||||
},
|
||||
},
|
||||
env: [
|
||||
{
|
||||
name: "DEBUG",
|
||||
@@ -151,6 +168,13 @@ class KubernetesTaskOperations implements TaskOperations {
|
||||
namespace: this.#namespace.metadata.name,
|
||||
labels: {
|
||||
app: "task-run",
|
||||
"app.kubernetes.io/part-of": "trigger-worker",
|
||||
"app.kubernetes.io/component": "create",
|
||||
env: opts.envId,
|
||||
envtype: this.#envTypeToLabelValue(opts.envType),
|
||||
org: opts.orgId,
|
||||
project: opts.projectId,
|
||||
run: opts.runId,
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
@@ -160,6 +184,9 @@ class KubernetesTaskOperations implements TaskOperations {
|
||||
name: "registry-trigger",
|
||||
},
|
||||
],
|
||||
nodeSelector: {
|
||||
nodetype: "worker",
|
||||
},
|
||||
containers: [
|
||||
{
|
||||
name: this.#getRunContainerName(opts.runId),
|
||||
@@ -169,9 +196,9 @@ class KubernetesTaskOperations implements TaskOperations {
|
||||
containerPort: 8000,
|
||||
},
|
||||
],
|
||||
// resources: {
|
||||
// limits: opts.machine,
|
||||
// },
|
||||
resources: {
|
||||
limits: this.#getResourcesFromMachineConfig(opts.machine),
|
||||
},
|
||||
lifecycle: {
|
||||
postStart: {
|
||||
exec: {
|
||||
@@ -180,7 +207,7 @@ class KubernetesTaskOperations implements TaskOperations {
|
||||
},
|
||||
preStop: {
|
||||
exec: {
|
||||
command: this.#getLifecycleCommand("preStop", "create"),
|
||||
command: this.#getLifecycleCommand("preStop", "terminate"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -262,6 +289,14 @@ class KubernetesTaskOperations implements TaskOperations {
|
||||
namespace: this.#namespace.metadata.name,
|
||||
labels: {
|
||||
app: "task-run",
|
||||
"app.kubernetes.io/part-of": "trigger-worker",
|
||||
"app.kubernetes.io/component": "restore",
|
||||
env: opts.envId,
|
||||
envtype: this.#envTypeToLabelValue(opts.envType),
|
||||
org: opts.orgId,
|
||||
project: opts.projectId,
|
||||
run: opts.runId,
|
||||
checkpoint: opts.checkpointId,
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
@@ -271,6 +306,9 @@ class KubernetesTaskOperations implements TaskOperations {
|
||||
name: "registry-trigger",
|
||||
},
|
||||
],
|
||||
nodeSelector: {
|
||||
nodetype: "worker",
|
||||
},
|
||||
initContainers: [
|
||||
{
|
||||
name: "pull-base-image",
|
||||
@@ -309,9 +347,9 @@ class KubernetesTaskOperations implements TaskOperations {
|
||||
containerPort: 8000,
|
||||
},
|
||||
],
|
||||
// resources: {
|
||||
// limits: opts.machine,
|
||||
// },
|
||||
resources: {
|
||||
limits: this.#getResourcesFromMachineConfig(opts.machine),
|
||||
},
|
||||
lifecycle: {
|
||||
postStart: {
|
||||
exec: {
|
||||
@@ -320,7 +358,7 @@ class KubernetesTaskOperations implements TaskOperations {
|
||||
},
|
||||
preStop: {
|
||||
exec: {
|
||||
command: this.#getLifecycleCommand("preStop", "restore"),
|
||||
command: this.#getLifecycleCommand("preStop", "terminate"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -355,7 +393,30 @@ class KubernetesTaskOperations implements TaskOperations {
|
||||
await this.#getPod(opts.runId, this.#namespace);
|
||||
}
|
||||
|
||||
#getLifecycleCommand(type: "postStart" | "preStop", cause: "index" | "create" | "restore") {
|
||||
#envTypeToLabelValue(type: EnvironmentType) {
|
||||
switch (type) {
|
||||
case "PRODUCTION":
|
||||
return "prod";
|
||||
case "STAGING":
|
||||
return "stg";
|
||||
case "DEVELOPMENT":
|
||||
return "dev";
|
||||
case "PREVIEW":
|
||||
return "preview";
|
||||
}
|
||||
}
|
||||
|
||||
#getResourcesFromMachineConfig(config: Machine) {
|
||||
return {
|
||||
cpu: `${config.cpu}`,
|
||||
memory: `${config.memory}G`,
|
||||
};
|
||||
}
|
||||
|
||||
#getLifecycleCommand<THookType extends "postStart" | "preStop">(
|
||||
type: THookType,
|
||||
cause: THookType extends "postStart" ? PostStartCauses : PreStopCauses
|
||||
) {
|
||||
return ["/bin/sh", "-c", `sleep 1; wget -q -O- 127.0.0.1:8000/${type}?cause=${cause}`];
|
||||
}
|
||||
|
||||
|
||||
@@ -264,7 +264,7 @@ export function SideMenu({ user, project, organization, organizations }: SideMen
|
||||
<SideMenuItem
|
||||
name="Documentation (v3)"
|
||||
icon="docs"
|
||||
to="https://trigger.dev/docs"
|
||||
to="https://trigger.dev/docs/v3"
|
||||
data-action="documentation"
|
||||
target="_blank"
|
||||
/>
|
||||
@@ -556,7 +556,7 @@ function V3ProjectSideMenu({
|
||||
data-action="test"
|
||||
/>
|
||||
<SideMenuItem
|
||||
name="API Keys"
|
||||
name="API keys"
|
||||
icon={KeyIcon}
|
||||
iconColor="text-amber-500"
|
||||
to={v3ApiKeysPath(organization, project)}
|
||||
|
||||
@@ -14,9 +14,9 @@ import {
|
||||
OperatingSystemContextProvider,
|
||||
OperatingSystemPlatform,
|
||||
} from "./components/primitives/OperatingSystemProvider";
|
||||
import { env } from "./env.server";
|
||||
import { getSharedSqsEventConsumer } from "./services/events/sqsEventConsumer";
|
||||
import { singleton } from "./utils/singleton";
|
||||
import { logger } from "./services/logger.server";
|
||||
|
||||
const ABORT_DELAY = 30000;
|
||||
|
||||
@@ -178,7 +178,7 @@ function logError(error: unknown, request?: Request) {
|
||||
|
||||
const sqsEventConsumer = singleton("sqsEventConsumer", getSharedSqsEventConsumer);
|
||||
|
||||
export { wss } from "./v3/handleWebsockets.server";
|
||||
export { socketIo } from "./v3/handleSocketIo.server";
|
||||
export { registryProxy } from "./v3/registryProxy.server";
|
||||
export { apiRateLimiter } from "./services/apiRateLimit.server";
|
||||
export { socketIo } from "./v3/handleSocketIo.server";
|
||||
export { wss } from "./v3/handleWebsockets.server";
|
||||
export { registryProxy } from "./v3/registryProxy.server";
|
||||
|
||||
@@ -85,8 +85,6 @@ const EnvironmentSchema = z.object({
|
||||
|
||||
//v3
|
||||
V3_ENABLED: z.string().default("false"),
|
||||
OTLP_EXPORTER_TRACES_URL: z.string().optional(),
|
||||
LOG_TELEMETRY: z.string().default("true"),
|
||||
IMAGE_REGISTRY: z.string().default("docker.io"),
|
||||
IMAGE_REPO: z.string().default("task"),
|
||||
PROVIDER_SECRET: z.string().default("provider-secret"),
|
||||
@@ -97,13 +95,35 @@ const EnvironmentSchema = z.object({
|
||||
CONTAINER_REGISTRY_USERNAME: z.string().optional(),
|
||||
CONTAINER_REGISTRY_PASSWORD: z.string().optional(),
|
||||
DEPLOY_REGISTRY_HOST: z.string().optional(),
|
||||
DEV_OTEL_EXPORTER_OTLP_ENDPOINT: z.string().optional(),
|
||||
OBJECT_STORE_BASE_URL: z.string().optional(),
|
||||
OBJECT_STORE_ACCESS_KEY_ID: z.string().optional(),
|
||||
OBJECT_STORE_SECRET_ACCESS_KEY: z.string().optional(),
|
||||
EVENTS_BATCH_SIZE: z.coerce.number().int().default(100),
|
||||
EVENTS_BATCH_INTERVAL: z.coerce.number().int().default(1000),
|
||||
EVENTS_DEFAULT_LOG_RETENTION: z.coerce.number().int().default(7),
|
||||
|
||||
// Development OTEL environment variables
|
||||
DEV_OTEL_EXPORTER_OTLP_ENDPOINT: z.string().optional(),
|
||||
// If this is set to 1, then the below variables are used to configure the batch processor for spans and logs
|
||||
DEV_OTEL_BATCH_PROCESSING_ENABLED: z.string().default("0"),
|
||||
DEV_OTEL_SPAN_MAX_EXPORT_BATCH_SIZE: z.string().default("64"),
|
||||
DEV_OTEL_SPAN_SCHEDULED_DELAY_MILLIS: z.string().default("200"),
|
||||
DEV_OTEL_SPAN_EXPORT_TIMEOUT_MILLIS: z.string().default("30000"),
|
||||
DEV_OTEL_SPAN_MAX_QUEUE_SIZE: z.string().default("512"),
|
||||
DEV_OTEL_LOG_MAX_EXPORT_BATCH_SIZE: z.string().default("64"),
|
||||
DEV_OTEL_LOG_SCHEDULED_DELAY_MILLIS: z.string().default("200"),
|
||||
DEV_OTEL_LOG_EXPORT_TIMEOUT_MILLIS: z.string().default("30000"),
|
||||
DEV_OTEL_LOG_MAX_QUEUE_SIZE: z.string().default("512"),
|
||||
RUNTIME_WAIT_THRESHOLD_IN_MS: z.coerce.number().int().default(30000),
|
||||
|
||||
// Internal OTEL environment variables
|
||||
INTERNAL_OTEL_TRACE_EXPORTER_URL: z.string().optional(),
|
||||
INTERNAL_OTEL_TRACE_EXPORTER_AUTH_HEADER_NAME: z.string().optional(),
|
||||
INTERNAL_OTEL_TRACE_EXPORTER_AUTH_HEADER_VALUE: z.string().optional(),
|
||||
INTERNAL_OTEL_TRACE_LOGGING_ENABLED: z.string().default("1"),
|
||||
// this means 1/20 traces or 5% of traces will be sampled (sampled = recorded)
|
||||
INTERNAL_OTEL_TRACE_SAMPING_RATE: z.string().default("20"),
|
||||
INTERNAL_OTEL_TRACE_INSTRUMENT_PRISMA_ENABLED: z.string().default("0"),
|
||||
});
|
||||
|
||||
export type Environment = z.infer<typeof EnvironmentSchema>;
|
||||
|
||||
@@ -43,14 +43,14 @@ export class SpanPresenter {
|
||||
span.outputType === "application/store"
|
||||
? `/resources/packets/${span.environmentId}/${span.output}`
|
||||
: typeof span.output !== "undefined" && span.output !== null
|
||||
? prettyPrintPacket(span.output, span.outputType ?? undefined)
|
||||
? await prettyPrintPacket(span.output, span.outputType ?? undefined)
|
||||
: undefined;
|
||||
|
||||
const payload =
|
||||
span.payloadType === "application/store"
|
||||
? `/resources/packets/${span.environmentId}/${span.payload}`
|
||||
: typeof span.payload !== "undefined" && span.payload !== null
|
||||
? prettyPrintPacket(span.payload, span.payloadType ?? undefined)
|
||||
? await prettyPrintPacket(span.payload, span.payloadType ?? undefined)
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
|
||||
@@ -69,7 +69,8 @@ export class TestTaskPresenter {
|
||||
ON
|
||||
tr."taskIdentifier" = bwt.slug
|
||||
WHERE
|
||||
bwt."friendlyId" = ${taskFriendlyId}
|
||||
bwt."friendlyId" = ${taskFriendlyId} AND
|
||||
tr."runtimeEnvironmentId" = ${task.runtimeEnvironment.id}
|
||||
ORDER BY
|
||||
tr."createdAt" DESC
|
||||
LIMIT 5
|
||||
|
||||
+7
-5
@@ -19,6 +19,7 @@ import {
|
||||
TableHeaderCell,
|
||||
TableRow,
|
||||
} from "~/components/primitives/Table";
|
||||
import { TextLink } from "~/components/primitives/TextLink";
|
||||
import { useProject } from "~/hooks/useProject";
|
||||
import { ApiKeysPresenter } from "~/presenters/v3/ApiKeysPresenter.server";
|
||||
import { requireUserId } from "~/services/session.server";
|
||||
@@ -55,12 +56,12 @@ export default function Page() {
|
||||
return (
|
||||
<PageContainer>
|
||||
<NavBar>
|
||||
<PageTitle title="API Keys" />
|
||||
<PageTitle title="API keys" />
|
||||
<PageAccessories>
|
||||
<LinkButton
|
||||
variant={"minimal/small"}
|
||||
LeadingIcon={BookOpenIcon}
|
||||
to={docsPath("/documentation/concepts/environments-endpoints#environments")}
|
||||
to={docsPath("/v3/apikeys")}
|
||||
>
|
||||
API keys docs
|
||||
</LinkButton>
|
||||
@@ -68,9 +69,10 @@ export default function Page() {
|
||||
</NavBar>
|
||||
<PageBody>
|
||||
<div className={cn("h-full")}>
|
||||
<Header3 spacing>Server API keys</Header3>
|
||||
<Header3 spacing>Secret keys</Header3>
|
||||
<Paragraph variant="small" spacing>
|
||||
Server API keys should be used on your server – they give full API access.
|
||||
Secret keys should be used on your server – they give full API access and allow you to{" "}
|
||||
<TextLink to={docsPath("v3/triggering")}>trigger tasks</TextLink> from your backend.
|
||||
</Paragraph>
|
||||
<Header3 spacing>Public API keys</Header3>
|
||||
<Paragraph variant="small" spacing>
|
||||
@@ -81,7 +83,7 @@ export default function Page() {
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHeaderCell>Environment</TableHeaderCell>
|
||||
<TableHeaderCell>Server API key</TableHeaderCell>
|
||||
<TableHeaderCell>Secret key</TableHeaderCell>
|
||||
<TableHeaderCell>Public API key</TableHeaderCell>
|
||||
<TableHeaderCell>Keys generated</TableHeaderCell>
|
||||
<TableHeaderCell>Latest version</TableHeaderCell>
|
||||
|
||||
+1
-1
@@ -167,7 +167,7 @@ export default function Page() {
|
||||
<PageAccessories>
|
||||
<LinkButton
|
||||
LeadingIcon={BookOpenIcon}
|
||||
to={docsPath("/documentation/concepts/environments-endpoints#environments")}
|
||||
to={docsPath("v3/deploy-environment-variables")}
|
||||
variant="minimal/small"
|
||||
>
|
||||
Environment variables docs
|
||||
|
||||
+19
-13
@@ -222,19 +222,25 @@ function PacketDisplay({
|
||||
dataType: string;
|
||||
title: string;
|
||||
}) {
|
||||
if (dataType === "application/store") {
|
||||
return (
|
||||
<div className="flex flex-col">
|
||||
<Paragraph variant="base/bright" className="w-full border-b border-grid-dimmed py-2.5">
|
||||
{title}
|
||||
</Paragraph>
|
||||
<LinkButton LeadingIcon={CloudArrowDownIcon} to={data} variant="tertiary/medium" download>
|
||||
Download
|
||||
</LinkButton>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return <CodeBlock rowTitle={title} code={data} maxLines={20} />;
|
||||
switch (dataType) {
|
||||
case "application/store": {
|
||||
return (
|
||||
<div className="flex flex-col">
|
||||
<Paragraph variant="base/bright" className="w-full border-b border-grid-dimmed py-2.5">
|
||||
{title}
|
||||
</Paragraph>
|
||||
<LinkButton LeadingIcon={CloudArrowDownIcon} to={data} variant="tertiary/medium" download>
|
||||
Download
|
||||
</LinkButton>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
case "text/plain": {
|
||||
return <CodeBlock language="markdown" rowTitle={title} code={data} maxLines={20} />;
|
||||
}
|
||||
default: {
|
||||
return <CodeBlock language="json" rowTitle={title} code={data} maxLines={20} />;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
//From: https://kettanaito.com/blog/debounce-vs-throttle
|
||||
|
||||
/** A very simple throttle. Will execute the function every Xms and discard any other calls during that period. */
|
||||
/** A very simple throttle. Will execute the function at the end of each period and discard any other calls during that period. */
|
||||
export function throttle(
|
||||
func: (...args: any[]) => void,
|
||||
duration: number
|
||||
durationMs: number
|
||||
): (...args: any[]) => void {
|
||||
let shouldWait = false;
|
||||
let isPrimedToFire = false;
|
||||
|
||||
return (...args: any[]) => {
|
||||
if (!shouldWait) {
|
||||
func(...args);
|
||||
shouldWait = true;
|
||||
if (!isPrimedToFire) {
|
||||
isPrimedToFire = true;
|
||||
|
||||
setTimeout(() => {
|
||||
shouldWait = false;
|
||||
}, duration);
|
||||
func(...args);
|
||||
isPrimedToFire = false;
|
||||
}, durationMs);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ function parseSecretKey(key: string) {
|
||||
const SecretValue = z.object({ secret: z.string() });
|
||||
|
||||
export class EnvironmentVariablesRepository implements Repository {
|
||||
constructor(private prismaClient: PrismaClient = prisma) { }
|
||||
constructor(private prismaClient: PrismaClient = prisma) {}
|
||||
|
||||
async create(
|
||||
projectId: string,
|
||||
@@ -419,8 +419,49 @@ export class EnvironmentVariablesRepository implements Repository {
|
||||
{
|
||||
key: "OTEL_EXPORTER_OTLP_ENDPOINT",
|
||||
value: env.DEV_OTEL_EXPORTER_OTLP_ENDPOINT ?? env.APP_ORIGIN,
|
||||
}
|
||||
];
|
||||
},
|
||||
].concat(
|
||||
env.DEV_OTEL_BATCH_PROCESSING_ENABLED === "1"
|
||||
? [
|
||||
{
|
||||
key: "OTEL_BATCH_PROCESSING_ENABLED",
|
||||
value: "1",
|
||||
},
|
||||
{
|
||||
key: "OTEL_SPAN_MAX_EXPORT_BATCH_SIZE",
|
||||
value: env.DEV_OTEL_SPAN_MAX_EXPORT_BATCH_SIZE,
|
||||
},
|
||||
{
|
||||
key: "OTEL_SPAN_SCHEDULED_DELAY_MILLIS",
|
||||
value: env.DEV_OTEL_SPAN_SCHEDULED_DELAY_MILLIS,
|
||||
},
|
||||
{
|
||||
key: "OTEL_SPAN_EXPORT_TIMEOUT_MILLIS",
|
||||
value: env.DEV_OTEL_SPAN_EXPORT_TIMEOUT_MILLIS,
|
||||
},
|
||||
{
|
||||
key: "OTEL_SPAN_MAX_QUEUE_SIZE",
|
||||
value: env.DEV_OTEL_SPAN_MAX_QUEUE_SIZE,
|
||||
},
|
||||
{
|
||||
key: "OTEL_LOG_MAX_EXPORT_BATCH_SIZE",
|
||||
value: env.DEV_OTEL_LOG_MAX_EXPORT_BATCH_SIZE,
|
||||
},
|
||||
{
|
||||
key: "OTEL_LOG_SCHEDULED_DELAY_MILLIS",
|
||||
value: env.DEV_OTEL_LOG_SCHEDULED_DELAY_MILLIS,
|
||||
},
|
||||
{
|
||||
key: "OTEL_LOG_EXPORT_TIMEOUT_MILLIS",
|
||||
value: env.DEV_OTEL_LOG_EXPORT_TIMEOUT_MILLIS,
|
||||
},
|
||||
{
|
||||
key: "OTEL_LOG_MAX_QUEUE_SIZE",
|
||||
value: env.DEV_OTEL_LOG_MAX_QUEUE_SIZE,
|
||||
},
|
||||
]
|
||||
: []
|
||||
);
|
||||
}
|
||||
|
||||
return [
|
||||
@@ -432,6 +473,10 @@ export class EnvironmentVariablesRepository implements Repository {
|
||||
key: "TRIGGER_API_URL",
|
||||
value: env.APP_ORIGIN,
|
||||
},
|
||||
{
|
||||
key: "TRIGGER_RUNTIME_WAIT_THRESHOLD_IN_MS",
|
||||
value: String(env.RUNTIME_WAIT_THRESHOLD_IN_MS),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
SpanMessagingEvent,
|
||||
TaskEventStyle,
|
||||
correctErrorStackTrace,
|
||||
createPackageAttributesAsJson,
|
||||
createPacketAttributesAsJson,
|
||||
flattenAttributes,
|
||||
isExceptionSpanEvent,
|
||||
omit,
|
||||
@@ -188,7 +188,7 @@ export class EventRepository {
|
||||
const event = events[0];
|
||||
|
||||
const output = options?.attributes.output
|
||||
? createPackageAttributesAsJson(
|
||||
? await createPacketAttributesAsJson(
|
||||
options?.attributes.output,
|
||||
options?.attributes.outputType ?? "application/json"
|
||||
)
|
||||
@@ -213,8 +213,9 @@ export class EventRepository {
|
||||
style: event.style as Attributes,
|
||||
output: output,
|
||||
outputType:
|
||||
options?.attributes.outputType === "application/store"
|
||||
? "application/store"
|
||||
options?.attributes.outputType === "application/store" ||
|
||||
options?.attributes.outputType === "text/plain"
|
||||
? options?.attributes.outputType
|
||||
: "application/json",
|
||||
payload: event.payload as Attributes,
|
||||
payloadType: event.payloadType,
|
||||
|
||||
@@ -591,14 +591,6 @@ export class MarQS {
|
||||
concurrencyLimitKey: string;
|
||||
currentConcurrencyKey: string;
|
||||
}) {
|
||||
logger.debug("Calling dequeueMessage", {
|
||||
messageQueue,
|
||||
parentQueue,
|
||||
visibilityQueue,
|
||||
concurrencyLimitKey,
|
||||
currentConcurrencyKey,
|
||||
});
|
||||
|
||||
const result = await this.redis.dequeueMessage(
|
||||
messageQueue,
|
||||
parentQueue,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Context, ROOT_CONTEXT, Span, SpanKind, context, trace } from "@opentelemetry/api";
|
||||
import {
|
||||
Machine,
|
||||
ProdTaskRunExecution,
|
||||
ProdTaskRunExecutionPayload,
|
||||
TaskRunError,
|
||||
@@ -438,10 +439,27 @@ export class SharedQueueConsumer {
|
||||
queueId: queue.id,
|
||||
runtimeEnvironmentId: environment.id,
|
||||
},
|
||||
include: {
|
||||
backgroundWorkerTask: true,
|
||||
},
|
||||
});
|
||||
|
||||
const isRetry = taskRunAttempt.number > 1;
|
||||
|
||||
const { machineConfig } = taskRunAttempt.backgroundWorkerTask;
|
||||
const machine = Machine.safeParse(machineConfig ?? {});
|
||||
|
||||
if (!machine.success) {
|
||||
logger.error("Failed to parse machine config", {
|
||||
queueMessage: message.data,
|
||||
messageId: message.messageId,
|
||||
attemptId: taskRunAttempt.id,
|
||||
machineConfig,
|
||||
});
|
||||
|
||||
await this.#ackAndDoMoreWork(message.messageId);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (messageBody.data.checkpointEventId) {
|
||||
const restoreService = new RestoreCheckpointService();
|
||||
@@ -470,11 +488,16 @@ export class SharedQueueConsumer {
|
||||
backgroundWorkerId: deployment.worker.friendlyId,
|
||||
data: {
|
||||
type: "SCHEDULE_ATTEMPT",
|
||||
id: taskRunAttempt.id,
|
||||
image: deployment.imageReference,
|
||||
envId: environment.id,
|
||||
runId: taskRunAttempt.taskRunId,
|
||||
version: deployment.version,
|
||||
machine: machine.data,
|
||||
// identifiers
|
||||
id: taskRunAttempt.id,
|
||||
envId: environment.id,
|
||||
envType: environment.type,
|
||||
orgId: environment.organizationId,
|
||||
projectId: environment.projectId,
|
||||
runId: taskRunAttempt.taskRunId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -259,6 +259,18 @@ export class RegistryProxy {
|
||||
proxyRes.pipe(response, { end: true });
|
||||
});
|
||||
|
||||
request.on("close", () => {
|
||||
logger.debug("Client closed the connection");
|
||||
proxyReq.destroy();
|
||||
cleanupTempFile();
|
||||
});
|
||||
|
||||
request.on("abort", () => {
|
||||
logger.debug("Client aborted the connection");
|
||||
proxyReq.destroy(); // Abort the proxied request
|
||||
cleanupTempFile(); // Clean up the temporary file if necessary
|
||||
});
|
||||
|
||||
if (tempFilePath) {
|
||||
const readStream = createReadStream(tempFilePath);
|
||||
|
||||
@@ -427,14 +439,22 @@ function initializeProxy() {
|
||||
});
|
||||
}
|
||||
|
||||
async function streamRequestBodyToTempFile(request: IncomingMessage): Promise<string> {
|
||||
const tempDir = await mkdtemp(`${tmpdir()}/`);
|
||||
const tempFilePath = `${tempDir}/requestBody.tmp`;
|
||||
const writeStream = createWriteStream(tempFilePath);
|
||||
async function streamRequestBodyToTempFile(request: IncomingMessage): Promise<string | undefined> {
|
||||
try {
|
||||
const tempDir = await mkdtemp(`${tmpdir()}/`);
|
||||
const tempFilePath = `${tempDir}/requestBody.tmp`;
|
||||
const writeStream = createWriteStream(tempFilePath);
|
||||
|
||||
await pipeline(request, writeStream);
|
||||
await pipeline(request, writeStream);
|
||||
|
||||
return tempFilePath;
|
||||
return tempFilePath;
|
||||
} catch (error) {
|
||||
logger.error("Failed to stream request body to temp file", {
|
||||
error: error instanceof Error ? error.message : error,
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
type DockerImageParts = {
|
||||
|
||||
@@ -105,7 +105,7 @@ export class CompleteAttemptService extends BaseService {
|
||||
attributes: {
|
||||
isError: false,
|
||||
output:
|
||||
completion.outputType === "application/store"
|
||||
completion.outputType === "application/store" || completion.outputType === "text/plain"
|
||||
? completion.output
|
||||
: completion.output
|
||||
? (safeJsonParse(completion.output) as Attributes)
|
||||
|
||||
@@ -101,6 +101,7 @@ export async function createBackgroundTasks(
|
||||
exportName: task.exportName,
|
||||
retryConfig: task.retry,
|
||||
queueConfig: task.queue,
|
||||
machineConfig: task.machine,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -49,9 +49,13 @@ export class IndexDeploymentService extends BaseService {
|
||||
version: "v1",
|
||||
shortCode: deployment.shortCode,
|
||||
imageTag: deployment.imageReference,
|
||||
envId: deployment.environmentId,
|
||||
apiKey: deployment.environment.apiKey,
|
||||
apiUrl: env.APP_ORIGIN,
|
||||
// identifiers
|
||||
envId: deployment.environmentId,
|
||||
envType: deployment.environment.type,
|
||||
projectId: deployment.projectId,
|
||||
orgId: deployment.environment.organizationId,
|
||||
});
|
||||
|
||||
logger.debug("Index ACK received", { responses });
|
||||
|
||||
@@ -3,6 +3,7 @@ import { logger } from "~/services/logger.server";
|
||||
import { socketIo } from "../handleSocketIo.server";
|
||||
import { CreateCheckpointRestoreEventService } from "./createCheckpointRestoreEvent.server";
|
||||
import { BaseService } from "./baseService.server";
|
||||
import { Machine } from "@trigger.dev/core/v3";
|
||||
|
||||
const RESTORABLE_RUN_STATUSES: TaskRunStatus[] = ["WAITING_TO_RESUME"];
|
||||
const RESTORABLE_ATTEMPT_STATUSES: TaskRunAttemptStatus[] = ["PAUSED"];
|
||||
@@ -30,8 +31,14 @@ export class RestoreCheckpointService extends BaseService {
|
||||
attempt: {
|
||||
select: {
|
||||
status: true,
|
||||
backgroundWorkerTask: {
|
||||
select: {
|
||||
machineConfig: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
runtimeEnvironment: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -63,17 +70,34 @@ export class RestoreCheckpointService extends BaseService {
|
||||
return;
|
||||
}
|
||||
|
||||
const { machineConfig } = checkpoint.attempt.backgroundWorkerTask;
|
||||
const machine = Machine.safeParse(machineConfig ?? {});
|
||||
|
||||
if (!machine.success) {
|
||||
logger.error("Failed to parse machine config", {
|
||||
attemptId: checkpoint.attemptId,
|
||||
machineConfig: checkpoint.attempt.backgroundWorkerTask.machineConfig,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const eventService = new CreateCheckpointRestoreEventService(this._prisma);
|
||||
await eventService.restore({ checkpointId: checkpoint.id });
|
||||
|
||||
socketIo.providerNamespace.emit("RESTORE", {
|
||||
version: "v1",
|
||||
checkpointId: checkpoint.id,
|
||||
runId: checkpoint.runId,
|
||||
type: checkpoint.type,
|
||||
location: checkpoint.location,
|
||||
reason: checkpoint.reason ?? undefined,
|
||||
imageRef: checkpoint.imageRef,
|
||||
machine: machine.data,
|
||||
// identifiers
|
||||
checkpointId: checkpoint.id,
|
||||
envId: checkpoint.runtimeEnvironment.id,
|
||||
envType: checkpoint.runtimeEnvironment.type,
|
||||
orgId: checkpoint.runtimeEnvironment.organizationId,
|
||||
projectId: checkpoint.runtimeEnvironment.projectId,
|
||||
runId: checkpoint.runId,
|
||||
});
|
||||
|
||||
return checkpoint;
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
trace,
|
||||
} from "@opentelemetry/api";
|
||||
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
||||
import { registerInstrumentations } from "@opentelemetry/instrumentation";
|
||||
import { InstrumentationOption, registerInstrumentations } from "@opentelemetry/instrumentation";
|
||||
import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";
|
||||
import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";
|
||||
import { Resource } from "@opentelemetry/resources";
|
||||
@@ -23,12 +23,13 @@ import {
|
||||
TraceIdRatioBasedSampler,
|
||||
} from "@opentelemetry/sdk-trace-base";
|
||||
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
|
||||
import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions";
|
||||
import { SEMRESATTRS_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
|
||||
import { PrismaInstrumentation } from "@prisma/instrumentation";
|
||||
import { env } from "~/env.server";
|
||||
import { AuthenticatedEnvironment } from "~/services/apiAuth.server";
|
||||
import { singleton } from "~/utils/singleton";
|
||||
import { LoggerSpanExporter } from "./telemetry/loggerExporter.server";
|
||||
|
||||
class CustomWebappSampler implements Sampler {
|
||||
constructor(private readonly _baseSampler: Sampler) {}
|
||||
|
||||
@@ -44,10 +45,7 @@ class CustomWebappSampler implements Sampler {
|
||||
const parentContext = trace.getSpanContext(context);
|
||||
|
||||
// Exclude Prisma spans (adjust this logic as needed for your use case)
|
||||
if (
|
||||
!parentContext &&
|
||||
((attributes && attributes["model"] && attributes["method"]) || name.includes("prisma"))
|
||||
) {
|
||||
if (!parentContext && name.includes("prisma")) {
|
||||
return { decision: SamplingDecision.NOT_RECORD };
|
||||
}
|
||||
|
||||
@@ -65,29 +63,46 @@ export const tracer = singleton("tracer", getTracer);
|
||||
function getTracer() {
|
||||
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.ERROR);
|
||||
|
||||
const samplingRate = 1.0 / Math.max(parseInt(env.INTERNAL_OTEL_TRACE_SAMPING_RATE, 10), 1);
|
||||
|
||||
const provider = new NodeTracerProvider({
|
||||
forceFlushTimeoutMillis: 500,
|
||||
resource: new Resource({
|
||||
[SemanticResourceAttributes.SERVICE_NAME]: "trigger.dev",
|
||||
[SEMRESATTRS_SERVICE_NAME]: "trigger.dev",
|
||||
}),
|
||||
sampler: new ParentBasedSampler({
|
||||
root: new CustomWebappSampler(
|
||||
new TraceIdRatioBasedSampler(env.APP_ENV === "development" ? 1.0 : 0.05)
|
||||
), // 5% sampling
|
||||
root: new CustomWebappSampler(new TraceIdRatioBasedSampler(samplingRate)), // 5% sampling
|
||||
}), // 5% sampling
|
||||
});
|
||||
|
||||
if (env.OTLP_EXPORTER_TRACES_URL) {
|
||||
if (env.INTERNAL_OTEL_TRACE_EXPORTER_URL) {
|
||||
const exporter = new OTLPTraceExporter({
|
||||
url: env.OTLP_EXPORTER_TRACES_URL,
|
||||
url: env.INTERNAL_OTEL_TRACE_EXPORTER_URL,
|
||||
timeoutMillis: 1000,
|
||||
headers:
|
||||
env.INTERNAL_OTEL_TRACE_EXPORTER_AUTH_HEADER_NAME &&
|
||||
env.INTERNAL_OTEL_TRACE_EXPORTER_AUTH_HEADER_VALUE
|
||||
? {
|
||||
[env.INTERNAL_OTEL_TRACE_EXPORTER_AUTH_HEADER_NAME]:
|
||||
env.INTERNAL_OTEL_TRACE_EXPORTER_AUTH_HEADER_VALUE,
|
||||
}
|
||||
: undefined,
|
||||
});
|
||||
|
||||
provider.addSpanProcessor(new BatchSpanProcessor(exporter));
|
||||
provider.addSpanProcessor(
|
||||
new BatchSpanProcessor(exporter, {
|
||||
maxExportBatchSize: 512,
|
||||
scheduledDelayMillis: 200,
|
||||
exportTimeoutMillis: 30000,
|
||||
maxQueueSize: 2048,
|
||||
})
|
||||
);
|
||||
|
||||
console.log(`⚡ Tracer: OTLP exporter enabled to ${env.OTLP_EXPORTER_TRACES_URL}`);
|
||||
console.log(`🔦 Tracer: OTLP exporter enabled to ${env.INTERNAL_OTEL_TRACE_EXPORTER_URL}`);
|
||||
} else {
|
||||
if (env.LOG_TELEMETRY === "true") {
|
||||
if (env.INTERNAL_OTEL_TRACE_LOGGING_ENABLED === "1") {
|
||||
console.log(`🔦 Tracer: Logger exporter enabled`);
|
||||
|
||||
const loggerExporter = new LoggerSpanExporter();
|
||||
|
||||
provider.addSpanProcessor(new SimpleSpanProcessor(loggerExporter));
|
||||
@@ -96,13 +111,18 @@ function getTracer() {
|
||||
|
||||
provider.register();
|
||||
|
||||
let instrumentations: InstrumentationOption[] = [
|
||||
new HttpInstrumentation(),
|
||||
new ExpressInstrumentation(),
|
||||
];
|
||||
|
||||
if (env.INTERNAL_OTEL_TRACE_INSTRUMENT_PRISMA_ENABLED === "1") {
|
||||
instrumentations.push(new PrismaInstrumentation());
|
||||
}
|
||||
|
||||
registerInstrumentations({
|
||||
tracerProvider: provider,
|
||||
instrumentations: [
|
||||
new HttpInstrumentation(),
|
||||
new ExpressInstrumentation(),
|
||||
new PrismaInstrumentation(),
|
||||
],
|
||||
instrumentations,
|
||||
});
|
||||
|
||||
return provider.getTracer("trigger.dev", "3.0.0.dp.1");
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 102 KiB |
@@ -63,7 +63,9 @@ You can use Personal Access Tokens to authenticate with Shopify and get started
|
||||
|
||||
To create the tokens on Shopify, login and [follow the instructions](https://help.shopify.com/en/manual/apps/app-types/custom-apps#create-and-install-a-custom-app).
|
||||
|
||||
The [required scopes](https://shopify.dev/docs/api/usage/access-scopes#authenticated-access-scopes) depend on the tasks you wish to perform and which webhooks you intend to receive. Webhooks will generally need read access to the respective Shopify resource.
|
||||
The [required scopes](https://shopify.dev/docs/api/usage/access-scopes#authenticated-access-scopes) depend on the tasks you wish to perform and which webhooks you intend to receive.
|
||||
|
||||
Webhooks will generally need read access to the respective Shopify resource at the very least. If the topic you subscribe to is triggered by an action that requires write access, e.g. `orders/create`, then write access is also required, e.g. `write_orders`.
|
||||
|
||||
Additionally, you will also have to provide your shop domain.
|
||||
|
||||
|
||||
@@ -452,6 +452,7 @@
|
||||
"v3/trigger-folder",
|
||||
"v3/tasks-overview",
|
||||
"v3/triggering",
|
||||
"v3/apikeys",
|
||||
{
|
||||
"group": "Task types",
|
||||
"pages": ["v3/tasks-regular", "v3/tasks-scheduled", "v3/tasks-zod", "v3/tasks-webhooks"]
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
title: "API keys"
|
||||
description: "How to authenticate with Trigger.dev so you can trigger tasks."
|
||||
---
|
||||
|
||||
### Authentication and your secret keys
|
||||
|
||||
When you [trigger a task](/v3/triggering) from your backend code, you need to set the `TRIGGER_SECRET_KEY` environment variable.
|
||||
|
||||
Each environment has its own secret key. You can find the value on the API keys page in the Trigger.dev dashboard:
|
||||
|
||||

|
||||
@@ -18,7 +18,7 @@ We deploy your tasks and scale them up and down when they are triggered. So any
|
||||
|
||||
<Step title="Add your environment variables">
|
||||
You can add values for your local dev environment, staging and prod. {" "}
|
||||
page](/images/v3/environment-variables-panel.jpg)
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
@@ -23,6 +23,10 @@ You can trigger any task from your backend code, using either `trigger()` or `ba
|
||||
Trigger.dev API key to the world.
|
||||
</Note>
|
||||
|
||||
### Authentication
|
||||
|
||||
When you trigger a task from your backend code, you need to set the `TRIGGER_SECRET_KEY` environment variable. You can find the value on the API keys page in the Trigger.dev dashboard. [More info on API keys](/v3/apikeys).
|
||||
|
||||
### trigger()
|
||||
|
||||
Triggers a single run of a task with the payload you pass in, and any options you specify. It does NOT wait for the result, you cannot do that from outside a task.
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @trigger.dev/airtable
|
||||
|
||||
## 3.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.2
|
||||
- @trigger.dev/sdk@3.0.0-beta.2
|
||||
|
||||
## 3.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b66d5525e]
|
||||
- Updated dependencies [719c0a0b9]
|
||||
- Updated dependencies [f93eae300]
|
||||
- @trigger.dev/sdk@3.0.0-beta.1
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.1
|
||||
|
||||
## 3.0.0-beta.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@trigger.dev/airtable",
|
||||
"version": "3.0.0-beta.0",
|
||||
"version": "3.0.0-beta.2",
|
||||
"description": "Trigger.dev integration for airtable",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -25,8 +25,8 @@
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.2",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.2",
|
||||
"airtable": "^0.12.1",
|
||||
"zod": "3.22.3"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @trigger.dev/github
|
||||
|
||||
## 3.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.2
|
||||
- @trigger.dev/sdk@3.0.0-beta.2
|
||||
|
||||
## 3.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b66d5525e]
|
||||
- Updated dependencies [719c0a0b9]
|
||||
- Updated dependencies [f93eae300]
|
||||
- @trigger.dev/sdk@3.0.0-beta.1
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.1
|
||||
|
||||
## 3.0.0-beta.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@trigger.dev/github",
|
||||
"version": "3.0.0-beta.0",
|
||||
"version": "3.0.0-beta.2",
|
||||
"description": "The official GitHub integration for Trigger.dev",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -30,8 +30,8 @@
|
||||
"@octokit/request-error": "^5.0.1",
|
||||
"@octokit/webhooks": "^12.0.10",
|
||||
"octokit": "^3.1.2",
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.2",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.2",
|
||||
"zod": "3.22.3"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @trigger.dev/linear
|
||||
|
||||
## 3.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.2
|
||||
- @trigger.dev/sdk@3.0.0-beta.2
|
||||
|
||||
## 3.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b66d5525e]
|
||||
- Updated dependencies [719c0a0b9]
|
||||
- Updated dependencies [f93eae300]
|
||||
- @trigger.dev/sdk@3.0.0-beta.1
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.1
|
||||
|
||||
## 3.0.0-beta.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@trigger.dev/linear",
|
||||
"version": "3.0.0-beta.0",
|
||||
"version": "3.0.0-beta.2",
|
||||
"description": "Trigger.dev integration for @linear/sdk",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -26,8 +26,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@linear/sdk": "^8.0.0",
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.2",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.2",
|
||||
"zod": "3.22.3"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @trigger.dev/slack
|
||||
|
||||
## 3.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.2
|
||||
- @trigger.dev/sdk@3.0.0-beta.2
|
||||
|
||||
## 3.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b66d5525e]
|
||||
- Updated dependencies [719c0a0b9]
|
||||
- Updated dependencies [f93eae300]
|
||||
- @trigger.dev/sdk@3.0.0-beta.1
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.1
|
||||
|
||||
## 3.0.0-beta.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@trigger.dev/openai",
|
||||
"version": "3.0.0-beta.0",
|
||||
"version": "3.0.0-beta.2",
|
||||
"description": "The official OpenAI integration for Trigger.dev",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -42,8 +42,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"openai": "^4.16.1",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.0"
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.2",
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @trigger.dev/plain
|
||||
|
||||
## 3.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.2
|
||||
- @trigger.dev/sdk@3.0.0-beta.2
|
||||
|
||||
## 3.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b66d5525e]
|
||||
- Updated dependencies [719c0a0b9]
|
||||
- Updated dependencies [f93eae300]
|
||||
- @trigger.dev/sdk@3.0.0-beta.1
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.1
|
||||
|
||||
## 3.0.0-beta.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@trigger.dev/plain",
|
||||
"version": "3.0.0-beta.0",
|
||||
"version": "3.0.0-beta.2",
|
||||
"description": "The official Plain.com integration for Trigger.dev",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -24,8 +24,8 @@
|
||||
"build:tsup": "tsup"
|
||||
},
|
||||
"dependencies": {
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.2",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.2",
|
||||
"@team-plain/typescript-sdk": "^2.7.0"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @trigger.dev/replicate
|
||||
|
||||
## 3.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.2
|
||||
- @trigger.dev/sdk@3.0.0-beta.2
|
||||
|
||||
## 3.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b66d5525e]
|
||||
- Updated dependencies [719c0a0b9]
|
||||
- Updated dependencies [f93eae300]
|
||||
- @trigger.dev/sdk@3.0.0-beta.1
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.1
|
||||
|
||||
## 3.0.0-beta.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@trigger.dev/replicate",
|
||||
"version": "3.0.0-beta.0",
|
||||
"version": "3.0.0-beta.2",
|
||||
"description": "Trigger.dev integration for replicate",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -25,8 +25,8 @@
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.2",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.2",
|
||||
"replicate": "^0.18.1",
|
||||
"zod": "3.22.3"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @trigger.dev/resend
|
||||
|
||||
## 3.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.2
|
||||
- @trigger.dev/sdk@3.0.0-beta.2
|
||||
|
||||
## 3.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b66d5525e]
|
||||
- Updated dependencies [719c0a0b9]
|
||||
- Updated dependencies [f93eae300]
|
||||
- @trigger.dev/sdk@3.0.0-beta.1
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.1
|
||||
|
||||
## 3.0.0-beta.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@trigger.dev/resend",
|
||||
"version": "3.0.0-beta.0",
|
||||
"version": "3.0.0-beta.2",
|
||||
"description": "The official Resend.com integration for Trigger.dev",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -24,8 +24,8 @@
|
||||
"build:tsup": "tsup"
|
||||
},
|
||||
"dependencies": {
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.2",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.2",
|
||||
"resend": "^2.1.0"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @trigger.dev/sendgrid
|
||||
|
||||
## 3.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.2
|
||||
- @trigger.dev/sdk@3.0.0-beta.2
|
||||
|
||||
## 3.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b66d5525e]
|
||||
- Updated dependencies [719c0a0b9]
|
||||
- Updated dependencies [f93eae300]
|
||||
- @trigger.dev/sdk@3.0.0-beta.1
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.1
|
||||
|
||||
## 3.0.0-beta.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@trigger.dev/sendgrid",
|
||||
"version": "3.0.0-beta.0",
|
||||
"version": "3.0.0-beta.2",
|
||||
"description": "Trigger.dev integration for @sendgrid/mail",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -26,8 +26,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@sendgrid/mail": "^7.7.0",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.0"
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.2",
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.8.0"
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @trigger.dev/shopify
|
||||
|
||||
## 3.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.2
|
||||
- @trigger.dev/sdk@3.0.0-beta.2
|
||||
|
||||
## 3.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b66d5525e]
|
||||
- Updated dependencies [719c0a0b9]
|
||||
- Updated dependencies [f93eae300]
|
||||
- @trigger.dev/sdk@3.0.0-beta.1
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.1
|
||||
|
||||
## 3.0.0-beta.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@trigger.dev/shopify",
|
||||
"version": "3.0.0-beta.0",
|
||||
"version": "3.0.0-beta.2",
|
||||
"description": "Trigger.dev integration for @shopify/shopify-api",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -26,8 +26,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@shopify/shopify-api": "^8.0.2",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.2",
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.2",
|
||||
"zod": "3.22.3"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# @trigger.dev/slack
|
||||
|
||||
## 3.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @trigger.dev/sdk@3.0.0-beta.2
|
||||
|
||||
## 3.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b66d5525e]
|
||||
- Updated dependencies [719c0a0b9]
|
||||
- Updated dependencies [f93eae300]
|
||||
- @trigger.dev/sdk@3.0.0-beta.1
|
||||
|
||||
## 3.0.0-beta.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@trigger.dev/slack",
|
||||
"version": "3.0.0-beta.0",
|
||||
"version": "3.0.0-beta.2",
|
||||
"description": "The official Slack integration for Trigger.dev",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -25,7 +25,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@slack/web-api": "^6.8.1",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.2",
|
||||
"zod": "3.22.3"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @trigger.dev/stripe
|
||||
|
||||
## 3.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.2
|
||||
- @trigger.dev/sdk@3.0.0-beta.2
|
||||
|
||||
## 3.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b66d5525e]
|
||||
- Updated dependencies [719c0a0b9]
|
||||
- Updated dependencies [f93eae300]
|
||||
- @trigger.dev/sdk@3.0.0-beta.1
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.1
|
||||
|
||||
## 3.0.0-beta.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@trigger.dev/stripe",
|
||||
"version": "3.0.0-beta.0",
|
||||
"version": "3.0.0-beta.2",
|
||||
"description": "Trigger.dev integration for stripe",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -25,8 +25,8 @@
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.2",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.2",
|
||||
"stripe": "^12.14.0",
|
||||
"zod": "3.22.3"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @trigger.dev/supabase
|
||||
|
||||
## 3.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.2
|
||||
- @trigger.dev/sdk@3.0.0-beta.2
|
||||
|
||||
## 3.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b66d5525e]
|
||||
- Updated dependencies [719c0a0b9]
|
||||
- Updated dependencies [f93eae300]
|
||||
- @trigger.dev/sdk@3.0.0-beta.1
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.1
|
||||
|
||||
## 3.0.0-beta.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@trigger.dev/supabase",
|
||||
"version": "3.0.0-beta.0",
|
||||
"version": "3.0.0-beta.2",
|
||||
"description": "Trigger.dev integration for @supabase/supabase-js",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -26,8 +26,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@supabase/supabase-js": "^2.26.0",
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.2",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.2",
|
||||
"supabase-management-js": "^1.0.0",
|
||||
"zod": "3.22.3"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @trigger.dev/typeform
|
||||
|
||||
## 3.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.2
|
||||
- @trigger.dev/sdk@3.0.0-beta.2
|
||||
|
||||
## 3.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b66d5525e]
|
||||
- Updated dependencies [719c0a0b9]
|
||||
- Updated dependencies [f93eae300]
|
||||
- @trigger.dev/sdk@3.0.0-beta.1
|
||||
- @trigger.dev/integration-kit@3.0.0-beta.1
|
||||
|
||||
## 3.0.0-beta.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@trigger.dev/typeform",
|
||||
"version": "3.0.0-beta.0",
|
||||
"version": "3.0.0-beta.2",
|
||||
"description": "The official Typeform integration for Trigger.dev",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -24,8 +24,8 @@
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.2",
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.2",
|
||||
"@typeform/api-client": "^1.8.0",
|
||||
"zod": "3.22.3"
|
||||
},
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@
|
||||
"env:pull": "turbo run env:pull",
|
||||
"changeset:add": "changeset",
|
||||
"changeset:version": "changeset version",
|
||||
"changeset:release": "pnpm run build --filter \"@trigger.dev/*\" && changeset publish",
|
||||
"changeset:release": "pnpm run build --filter \"@trigger.dev/*\" --filter \"trigger.dev\" && changeset publish",
|
||||
"changeset:beta": "changeset pre enter beta",
|
||||
"changeset:normal": "changeset pre exit",
|
||||
"clean:sourcemaps": "turbo run clean:sourcemaps",
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# @trigger.dev/astro
|
||||
|
||||
## 3.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @trigger.dev/sdk@3.0.0-beta.2
|
||||
|
||||
## 3.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b66d5525e]
|
||||
- Updated dependencies [719c0a0b9]
|
||||
- Updated dependencies [f93eae300]
|
||||
- @trigger.dev/sdk@3.0.0-beta.1
|
||||
|
||||
## 3.0.0-beta.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@trigger.dev/astro",
|
||||
"description": "An Astro-native integration for Trigger.dev background jobs platform",
|
||||
"version": "3.0.0-beta.0",
|
||||
"version": "3.0.0-beta.2",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"files": [
|
||||
@@ -20,7 +20,7 @@
|
||||
"build:tsup": "tsup"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.0"
|
||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"astro": "^3.0.12",
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
# trigger.dev
|
||||
|
||||
## 3.0.0-beta.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- e3cf456c6: Handle string and non-stringifiable outputs like functions
|
||||
- Updated dependencies [e3cf456c6]
|
||||
- @trigger.dev/core@3.0.0-beta.2
|
||||
|
||||
## 3.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b66d5525e: add machine config and secure zod connection
|
||||
- d9c9e80bc: Changed "Worker" to "Version" in the dev command key
|
||||
- 719c0a0b9: Fixed incorrect span timings around checkpoints by implementing a precise wall clock that resets after restores
|
||||
- 9bcb8cb42: Added DEBUG to the ignored env vars
|
||||
- f93eae300: Dynamically import superjson and fix some bundling issues
|
||||
- Updated dependencies [b66d5525e]
|
||||
- Updated dependencies [719c0a0b9]
|
||||
- Updated dependencies [f93eae300]
|
||||
- @trigger.dev/core@3.0.0-beta.1
|
||||
|
||||
## 3.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f1571cbfa: Fixed an issue where the trigger.dev package was not being built before publishing to npm
|
||||
|
||||
## 3.0.0-beta.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "trigger.dev",
|
||||
"version": "3.0.0-beta.0",
|
||||
"version": "3.0.0-beta.3",
|
||||
"description": "A Command-Line Interface for Trigger.dev (v3) projects",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -89,7 +89,7 @@
|
||||
"@opentelemetry/sdk-trace-base": "^1.22.0",
|
||||
"@opentelemetry/sdk-trace-node": "^1.22.0",
|
||||
"@opentelemetry/semantic-conventions": "^1.22.0",
|
||||
"@trigger.dev/core": "workspace:^3.0.0-beta.0",
|
||||
"@trigger.dev/core": "workspace:^3.0.0-beta.2",
|
||||
"@types/degit": "^2.8.3",
|
||||
"chalk": "^5.2.0",
|
||||
"chokidar": "^3.5.3",
|
||||
|
||||
@@ -889,7 +889,14 @@ async function compileProject(
|
||||
TRIGGER_API_URL: `"${config.triggerUrl}"`,
|
||||
__PROJECT_CONFIG__: JSON.stringify(config),
|
||||
},
|
||||
plugins: [bundleDependenciesPlugin(config), workerSetupImportConfigPlugin(configPath)],
|
||||
plugins: [
|
||||
bundleDependenciesPlugin(
|
||||
"workerFacade",
|
||||
config.dependenciesToBundle,
|
||||
config.tsconfigPath
|
||||
),
|
||||
workerSetupImportConfigPlugin(configPath),
|
||||
],
|
||||
});
|
||||
|
||||
if (result.errors.length > 0) {
|
||||
@@ -927,15 +934,22 @@ async function compileProject(
|
||||
write: false,
|
||||
minify: false,
|
||||
sourcemap: false,
|
||||
packages: "external", // https://esbuild.github.io/api/#packages
|
||||
logLevel: "error",
|
||||
platform: "node",
|
||||
packages: "external",
|
||||
format: "cjs", // This is needed to support opentelemetry instrumentation that uses module patching
|
||||
target: ["node18", "es2020"],
|
||||
outdir: "out",
|
||||
define: {
|
||||
__PROJECT_CONFIG__: JSON.stringify(config),
|
||||
},
|
||||
plugins: [
|
||||
bundleDependenciesPlugin(
|
||||
"entryPoint.ts",
|
||||
config.dependenciesToBundle,
|
||||
config.tsconfigPath
|
||||
),
|
||||
],
|
||||
});
|
||||
|
||||
if (entryPointResult.errors.length > 0) {
|
||||
@@ -1003,6 +1017,11 @@ async function compileProject(
|
||||
// Save the entryPoint outputFile to /tmp/dir/index.js
|
||||
await writeFile(join(tempDir, "index.js"), entryPointOutputFile.text);
|
||||
|
||||
logger.debug("Getting the imports for the worker and entryPoint builds", {
|
||||
workerImports: metaOutput.imports,
|
||||
entryPointImports: entryPointMetaOutput.imports,
|
||||
});
|
||||
|
||||
// Get all the required dependencies from the metaOutputs and save them to /tmp/dir/package.json
|
||||
const allImports = [...metaOutput.imports, ...entryPointMetaOutput.imports];
|
||||
|
||||
@@ -1246,7 +1265,7 @@ async function gatherRequiredDependencies(
|
||||
const dependencies: Record<string, string> = {};
|
||||
|
||||
for (const file of imports) {
|
||||
if (file.kind !== "require-call" || !file.external) {
|
||||
if ((file.kind !== "require-call" && file.kind !== "dynamic-import") || !file.external) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1382,7 +1401,7 @@ async function findAllEnvironmentVariableReferencesInFile(filePath: string) {
|
||||
return findAllEnvironmentVariableReferences(fileContents);
|
||||
}
|
||||
|
||||
const IGNORED_ENV_VARS = ["NODE_ENV", "SHELL", "HOME", "PWD", "LOGNAME", "USER", "PATH"];
|
||||
const IGNORED_ENV_VARS = ["NODE_ENV", "SHELL", "HOME", "PWD", "LOGNAME", "USER", "PATH", "DEBUG"];
|
||||
|
||||
function findAllEnvironmentVariableReferences(code: string): string[] {
|
||||
const regex = /\bprocess\.env\.([a-zA-Z_][a-zA-Z0-9_]*)\b/g;
|
||||
|
||||
@@ -26,7 +26,7 @@ import * as packageJson from "../../package.json";
|
||||
import { CliApiClient } from "../apiClient";
|
||||
import { CommonCommandOptions, commonOptions, wrapCommandAction } from "../cli/common.js";
|
||||
import { bundleDependenciesPlugin, workerSetupImportConfigPlugin } from "../utilities/build";
|
||||
import { chalkGrey, chalkPurple, chalkWorker } from "../utilities/cliOutput";
|
||||
import { chalkError, chalkGrey, chalkPurple, chalkTask, chalkWorker } from "../utilities/cliOutput";
|
||||
import { readConfig } from "../utilities/configFiles";
|
||||
import { readJSONFile } from "../utilities/fileSystem";
|
||||
import { printDevBanner, printStandloneInitialBanner } from "../utilities/initialBanner.js";
|
||||
@@ -77,9 +77,13 @@ export async function devCommand(dir: string, options: DevCommandOptions) {
|
||||
|
||||
if (!authorization.ok) {
|
||||
if (authorization.error === "fetch failed") {
|
||||
logger.error("Fetch failed. Platform down?");
|
||||
logger.log(
|
||||
`${chalkError(
|
||||
"X Error:"
|
||||
)} Connecting to the server failed. Please check your internet connection or contact eric@trigger.dev for help.`
|
||||
);
|
||||
} else {
|
||||
logger.error("You must login first. Use `trigger.dev login` to login.");
|
||||
logger.log(`${chalkError("X Error:")} You must login first. Use the \`login\` CLI command.`);
|
||||
}
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
@@ -362,7 +366,11 @@ function useDev({
|
||||
__PROJECT_CONFIG__: JSON.stringify(config),
|
||||
},
|
||||
plugins: [
|
||||
bundleDependenciesPlugin(config),
|
||||
bundleDependenciesPlugin(
|
||||
"workerFacade",
|
||||
(config.dependenciesToBundle ?? []).concat([/^@trigger.dev/]),
|
||||
config.tsconfigPath
|
||||
),
|
||||
workerSetupImportConfigPlugin(configPath),
|
||||
{
|
||||
name: "trigger.dev v3",
|
||||
@@ -631,8 +639,12 @@ async function gatherRequiredDependencies(
|
||||
) {
|
||||
const dependencies: Record<string, string> = {};
|
||||
|
||||
logger.debug("Gathering required dependencies from imports", {
|
||||
imports: outputMeta.imports,
|
||||
});
|
||||
|
||||
for (const file of outputMeta.imports) {
|
||||
if (file.kind !== "require-call" || !file.external) {
|
||||
if ((file.kind !== "require-call" && file.kind !== "dynamic-import") || !file.external) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -693,13 +705,13 @@ function createDuplicateTaskIdOutputErrorMessage(
|
||||
.map((id) => {
|
||||
const tasks = taskResources.filter((task) => task.id === id);
|
||||
|
||||
return `id "${chalkPurple(id)}" was found in:\n${tasks
|
||||
.map((task) => `${task.filePath} -> ${task.exportName}`)
|
||||
.join("\n")}`;
|
||||
return `\n\n${chalkTask(id)} was found in:${tasks
|
||||
.map((task) => `\n${task.filePath} -> ${task.exportName}`)
|
||||
.join("")}`;
|
||||
})
|
||||
.join("\n\n");
|
||||
.join("");
|
||||
|
||||
return `Duplicate task ids detected:\n\n${duplicateTable}\n\n`;
|
||||
return `Duplicate ${chalkTask("task id")} detected:${duplicateTable}`;
|
||||
}
|
||||
|
||||
function gatherProcessEnv() {
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { ResolvedConfig } from "@trigger.dev/core/v3";
|
||||
import type * as esbuild from "esbuild";
|
||||
import type { Plugin } from "esbuild";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { extname, isAbsolute } from "node:path";
|
||||
import tsConfigPaths from "tsconfig-paths";
|
||||
import { logger } from "./logger";
|
||||
import { readFileSync } from "node:fs";
|
||||
|
||||
export function workerSetupImportConfigPlugin(configPath?: string): Plugin {
|
||||
return {
|
||||
@@ -37,8 +36,12 @@ export function workerSetupImportConfigPlugin(configPath?: string): Plugin {
|
||||
};
|
||||
}
|
||||
|
||||
export function bundleDependenciesPlugin(config: ResolvedConfig): Plugin {
|
||||
const matchPath = config.tsconfigPath ? createMatchPath(config.tsconfigPath) : undefined;
|
||||
export function bundleDependenciesPlugin(
|
||||
buildIdentifier: string,
|
||||
dependenciesToBundle?: Array<string | RegExp>,
|
||||
tsconfigPath?: string
|
||||
): Plugin {
|
||||
const matchPath = tsconfigPath ? createMatchPath(tsconfigPath) : undefined;
|
||||
|
||||
function resolvePath(id: string) {
|
||||
if (!matchPath) {
|
||||
@@ -53,33 +56,8 @@ export function bundleDependenciesPlugin(config: ResolvedConfig): Plugin {
|
||||
build.onResolve({ filter: /.*/ }, (args) => {
|
||||
const resolvedPath = resolvePath(args.path);
|
||||
|
||||
logger.ignore(`Checking if ${args.path} should be bundled or external`, {
|
||||
...args,
|
||||
resolvedPath,
|
||||
});
|
||||
|
||||
if (!isBareModuleId(resolvedPath)) {
|
||||
logger.ignore(`Bundling ${args.path} because its not a bareModuleId`, {
|
||||
...args,
|
||||
});
|
||||
|
||||
return undefined; // let esbuild bundle it
|
||||
}
|
||||
|
||||
if (args.path.startsWith("@trigger.dev/")) {
|
||||
logger.ignore(`Bundling ${args.path} because its a trigger.dev package`, {
|
||||
...args,
|
||||
});
|
||||
|
||||
return undefined; // let esbuild bundle it
|
||||
}
|
||||
|
||||
if (args.path === "superjson" || args.path === "copy-anything" || args.path === "is-what") {
|
||||
logger.debug(`Bundling ${args.path} because its superjson/copy-anything/is-what`, {
|
||||
...args,
|
||||
});
|
||||
|
||||
return undefined; // let esbuild bundle it
|
||||
return undefined; // let esbuild handle it
|
||||
}
|
||||
|
||||
// Skip assets that are treated as files (.css, .svg, .png, etc.).
|
||||
@@ -97,13 +75,13 @@ export function bundleDependenciesPlugin(config: ResolvedConfig): Plugin {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
for (let pattern of config.dependenciesToBundle ?? []) {
|
||||
for (let pattern of dependenciesToBundle ?? []) {
|
||||
if (typeof pattern === "string" ? args.path === pattern : pattern.test(args.path)) {
|
||||
return undefined; // let esbuild bundle it
|
||||
}
|
||||
}
|
||||
|
||||
logger.ignore(`Externalizing ${args.path}`, {
|
||||
logger.ignore(`[${buildIdentifier}] Externalizing ${args.path}`, {
|
||||
...args,
|
||||
});
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ export async function printStandloneInitialBanner(performUpdateCheck = true) {
|
||||
|
||||
export function printDevBanner() {
|
||||
logger.log(
|
||||
`${chalkGrey("Key:")} ${chalkWorker("Worker")} ${chalkGrey("|")} ${chalkTask(
|
||||
`${chalkGrey("Key:")} ${chalkWorker("Version")} ${chalkGrey("|")} ${chalkTask(
|
||||
"Task"
|
||||
)} ${chalkGrey("|")} ${chalkRun("Run")}`
|
||||
);
|
||||
|
||||
@@ -18,16 +18,11 @@ import {
|
||||
formatDurationMilliseconds,
|
||||
workerToChildMessages,
|
||||
} from "@trigger.dev/core/v3";
|
||||
import chalk from "chalk";
|
||||
import dotenv from "dotenv";
|
||||
import { Evt } from "evt";
|
||||
import { ChildProcess, fork } from "node:child_process";
|
||||
import { dirname, resolve } from "node:path";
|
||||
import terminalLink from "terminal-link";
|
||||
import { safeDeleteFileSync } from "../../utilities/fileSystem.js";
|
||||
import { installPackages } from "../../utilities/installPackages.js";
|
||||
import { logger } from "../../utilities/logger.js";
|
||||
import { UncaughtExceptionError } from "../common/errors.js";
|
||||
import {
|
||||
chalkError,
|
||||
chalkGrey,
|
||||
@@ -39,6 +34,10 @@ import {
|
||||
chalkWorker,
|
||||
prettyPrintDate,
|
||||
} from "../../utilities/cliOutput.js";
|
||||
import { safeDeleteFileSync } from "../../utilities/fileSystem.js";
|
||||
import { installPackages } from "../../utilities/installPackages.js";
|
||||
import { logger } from "../../utilities/logger.js";
|
||||
import { UncaughtExceptionError } from "../common/errors.js";
|
||||
|
||||
export type CurrentWorkers = BackgroundWorkerCoordinator["currentWorkers"];
|
||||
export class BackgroundWorkerCoordinator {
|
||||
|
||||
@@ -2,9 +2,10 @@ import {
|
||||
Config,
|
||||
ProjectConfig,
|
||||
TaskExecutor,
|
||||
preciseDateOriginNow,
|
||||
type TracingSDK,
|
||||
type HandleErrorFunction,
|
||||
DurableClock,
|
||||
clock,
|
||||
} from "@trigger.dev/core/v3";
|
||||
|
||||
__WORKER_SETUP__;
|
||||
@@ -42,10 +43,11 @@ import { TaskMetadataWithFunctions } from "../../types.js";
|
||||
|
||||
declare const sender: ZodMessageSender<typeof childToWorkerMessages>;
|
||||
|
||||
const preciseDateOrigin = preciseDateOriginNow();
|
||||
const durableClock = new DurableClock();
|
||||
clock.setGlobalClock(durableClock);
|
||||
|
||||
const tracer = new TriggerTracer({ tracer: otelTracer, logger: otelLogger });
|
||||
const consoleInterceptor = new ConsoleInterceptor(otelLogger, preciseDateOrigin);
|
||||
const consoleInterceptor = new ConsoleInterceptor(otelLogger);
|
||||
|
||||
const devRuntimeManager = new DevRuntimeManager();
|
||||
|
||||
@@ -55,7 +57,6 @@ const otelTaskLogger = new OtelTaskLogger({
|
||||
logger: otelLogger,
|
||||
tracer: tracer,
|
||||
level: "info",
|
||||
preciseDateOrigin,
|
||||
});
|
||||
|
||||
logger.setGlobalTaskLogger(otelTaskLogger);
|
||||
@@ -83,6 +84,7 @@ function getTasks(): Array<TaskMetadataWithFunctions> {
|
||||
filePath: (taskFile as any).filePath,
|
||||
queue: (task as any).__trigger.queue,
|
||||
retry: (task as any).__trigger.retry,
|
||||
machine: (task as any).__trigger.machine,
|
||||
fns: (task as any).__trigger.fns,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import {
|
||||
Config,
|
||||
CoordinatorToProdWorkerMessages,
|
||||
PostStartCauses,
|
||||
PreStopCauses,
|
||||
ProdWorkerToCoordinatorMessages,
|
||||
TaskResource,
|
||||
WaitReason,
|
||||
@@ -567,23 +569,15 @@ class ProdWorker {
|
||||
}
|
||||
|
||||
case "/preStop": {
|
||||
const schema = z.enum(["index", "create", "restore"]);
|
||||
|
||||
const cause = schema.safeParse(url.searchParams.get("cause"));
|
||||
const cause = PreStopCauses.safeParse(url.searchParams.get("cause"));
|
||||
|
||||
if (!cause.success) {
|
||||
logger.error("Failed to parse cause", { cause });
|
||||
return;
|
||||
return reply.text("Failed to parse cause", 400);
|
||||
}
|
||||
|
||||
switch (cause.data) {
|
||||
case "index": {
|
||||
break;
|
||||
}
|
||||
case "create": {
|
||||
break;
|
||||
}
|
||||
case "restore": {
|
||||
case "terminate": {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -597,13 +591,11 @@ class ProdWorker {
|
||||
}
|
||||
|
||||
case "/postStart": {
|
||||
const schema = z.enum(["index", "create", "restore"]);
|
||||
|
||||
const cause = schema.safeParse(url.searchParams.get("cause"));
|
||||
const cause = PostStartCauses.safeParse(url.searchParams.get("cause"));
|
||||
|
||||
if (!cause.success) {
|
||||
logger.error("Failed to parse cause", { cause });
|
||||
return;
|
||||
return reply.text("Failed to parse cause", 400);
|
||||
}
|
||||
|
||||
switch (cause.data) {
|
||||
@@ -678,11 +670,7 @@ class ProdWorker {
|
||||
}
|
||||
|
||||
for (const task of this.#backgroundWorker.tasks) {
|
||||
taskResources.push({
|
||||
id: task.id,
|
||||
filePath: task.filePath,
|
||||
exportName: task.exportName,
|
||||
});
|
||||
taskResources.push(task);
|
||||
|
||||
packageVersion = task.packageVersion;
|
||||
}
|
||||
|
||||
@@ -6,8 +6,9 @@ import {
|
||||
TaskExecutor,
|
||||
ZodIpcConnection,
|
||||
type TracingSDK,
|
||||
preciseDateOriginNow,
|
||||
HandleErrorFunction,
|
||||
DurableClock,
|
||||
clock,
|
||||
} from "@trigger.dev/core/v3";
|
||||
import "source-map-support/register.js";
|
||||
|
||||
@@ -40,16 +41,16 @@ import * as packageJson from "../../../package.json";
|
||||
|
||||
import { TaskMetadataWithFunctions } from "../../types";
|
||||
|
||||
const preciseDateOrigin = preciseDateOriginNow();
|
||||
const durableClock = new DurableClock();
|
||||
clock.setGlobalClock(durableClock);
|
||||
|
||||
const tracer = new TriggerTracer({ tracer: otelTracer, logger: otelLogger });
|
||||
const consoleInterceptor = new ConsoleInterceptor(otelLogger, preciseDateOrigin);
|
||||
const consoleInterceptor = new ConsoleInterceptor(otelLogger);
|
||||
|
||||
const otelTaskLogger = new OtelTaskLogger({
|
||||
logger: otelLogger,
|
||||
tracer: tracer,
|
||||
level: "info",
|
||||
preciseDateOrigin,
|
||||
});
|
||||
|
||||
logger.setGlobalTaskLogger(otelTaskLogger);
|
||||
@@ -77,6 +78,7 @@ function getTasks(): Array<TaskMetadataWithFunctions> {
|
||||
filePath: (taskFile as any).filePath,
|
||||
queue: (task as any).__trigger.queue,
|
||||
retry: (task as any).__trigger.retry,
|
||||
machine: (task as any).__trigger.machine,
|
||||
fns: (task as any).__trigger.fns,
|
||||
});
|
||||
}
|
||||
@@ -200,7 +202,9 @@ const zodIpc = new ZodIpcConnection({
|
||||
},
|
||||
});
|
||||
|
||||
const prodRuntimeManager = new ProdRuntimeManager(zodIpc);
|
||||
const prodRuntimeManager = new ProdRuntimeManager(zodIpc, {
|
||||
waitThresholdInMs: parseInt(process.env.TRIGGER_RUNTIME_WAIT_THRESHOLD_IN_MS ?? "30000", 10),
|
||||
});
|
||||
|
||||
runtime.setGlobalRuntimeManager(prodRuntimeManager);
|
||||
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# create-trigger
|
||||
|
||||
## 3.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [e3cf456c6]
|
||||
- @trigger.dev/core@3.0.0-beta.2
|
||||
- @trigger.dev/yalt@3.0.0-beta.2
|
||||
|
||||
## 3.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b66d5525e]
|
||||
- Updated dependencies [719c0a0b9]
|
||||
- Updated dependencies [f93eae300]
|
||||
- @trigger.dev/core@3.0.0-beta.1
|
||||
- @trigger.dev/yalt@3.0.0-beta.1
|
||||
|
||||
## 3.0.0-beta.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@trigger.dev/cli",
|
||||
"version": "3.0.0-beta.0",
|
||||
"version": "3.0.0-beta.2",
|
||||
"description": "The Trigger.dev CLI",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
# @trigger.dev/core-apps
|
||||
|
||||
## 3.0.0-beta.2
|
||||
|
||||
## 3.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b66d5525e: add machine config and secure zod connection
|
||||
|
||||
## 3.0.0-beta.0
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@trigger.dev/core-apps",
|
||||
"description": "Backend core code used across apps",
|
||||
"version": "3.0.0-beta.0",
|
||||
"version": "3.0.0-beta.2",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
|
||||
@@ -2,6 +2,7 @@ import { createServer } from "node:http";
|
||||
import {
|
||||
ClientToSharedQueueMessages,
|
||||
clientWebsocketMessages,
|
||||
EnvironmentType,
|
||||
Machine,
|
||||
PlatformToProviderMessages,
|
||||
ProviderToPlatformMessages,
|
||||
@@ -18,30 +19,46 @@ const MACHINE_NAME = process.env.MACHINE_NAME || "local";
|
||||
const PLATFORM_HOST = process.env.PLATFORM_HOST || "127.0.0.1";
|
||||
const PLATFORM_WS_PORT = process.env.PLATFORM_WS_PORT || 3030;
|
||||
const PLATFORM_SECRET = process.env.PLATFORM_SECRET || "provider-secret";
|
||||
const SECURE_CONNECTION = ["1", "true"].includes(process.env.SECURE_CONNECTION ?? "false");
|
||||
|
||||
const logger = new SimpleLogger(`[${MACHINE_NAME}]`);
|
||||
|
||||
export interface TaskOperationsIndexOptions {
|
||||
shortCode: string;
|
||||
imageRef: string;
|
||||
envId: string;
|
||||
apiKey: string;
|
||||
apiUrl: string;
|
||||
// identifiers
|
||||
envId: string;
|
||||
envType: EnvironmentType;
|
||||
orgId: string;
|
||||
projectId: string;
|
||||
}
|
||||
|
||||
export interface TaskOperationsCreateOptions {
|
||||
runId: string;
|
||||
image: string;
|
||||
machine: Machine;
|
||||
envId: string;
|
||||
version: string;
|
||||
// identifiers
|
||||
envId: string;
|
||||
envType: EnvironmentType;
|
||||
orgId: string;
|
||||
projectId: string;
|
||||
runId: string;
|
||||
attemptId: string;
|
||||
}
|
||||
|
||||
export interface TaskOperationsRestoreOptions {
|
||||
runId: string;
|
||||
imageRef: string;
|
||||
checkpointRef: string;
|
||||
machine: Machine;
|
||||
// identifiers
|
||||
envId: string;
|
||||
envType: EnvironmentType;
|
||||
orgId: string;
|
||||
projectId: string;
|
||||
runId: string;
|
||||
checkpointId: string;
|
||||
}
|
||||
|
||||
export interface TaskOperations {
|
||||
@@ -87,6 +104,7 @@ export class ProviderShell implements Provider {
|
||||
namespace: "shared-queue",
|
||||
host: PLATFORM_HOST,
|
||||
port: Number(PLATFORM_WS_PORT),
|
||||
secure: SECURE_CONNECTION,
|
||||
clientMessages: ClientToSharedQueueMessages,
|
||||
serverMessages: SharedQueueToClientMessages,
|
||||
authToken: PLATFORM_SECRET,
|
||||
@@ -101,11 +119,16 @@ export class ProviderShell implements Provider {
|
||||
if (message.data.type === "SCHEDULE_ATTEMPT") {
|
||||
try {
|
||||
this.tasks.create({
|
||||
envId: message.data.envId,
|
||||
runId: message.data.runId,
|
||||
image: message.data.image,
|
||||
machine: {},
|
||||
version: message.version,
|
||||
machine: message.data.machine,
|
||||
version: message.data.version,
|
||||
// identifiers
|
||||
envId: message.data.envId,
|
||||
envType: message.data.envType,
|
||||
orgId: message.data.orgId,
|
||||
projectId: message.data.projectId,
|
||||
runId: message.data.runId,
|
||||
attemptId: message.data.id,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error("create failed", error);
|
||||
@@ -138,6 +161,7 @@ export class ProviderShell implements Provider {
|
||||
namespace: "provider",
|
||||
host: PLATFORM_HOST,
|
||||
port: Number(PLATFORM_WS_PORT),
|
||||
secure: SECURE_CONNECTION,
|
||||
clientMessages: ProviderToPlatformMessages,
|
||||
serverMessages: PlatformToProviderMessages,
|
||||
authToken: PLATFORM_SECRET,
|
||||
@@ -165,9 +189,13 @@ export class ProviderShell implements Provider {
|
||||
await this.tasks.index({
|
||||
shortCode: message.shortCode,
|
||||
imageRef: message.imageTag,
|
||||
envId: message.envId,
|
||||
apiKey: message.apiKey,
|
||||
apiUrl: message.apiUrl,
|
||||
// identifiers
|
||||
envId: message.envId,
|
||||
envType: message.envType,
|
||||
orgId: message.orgId,
|
||||
projectId: message.projectId,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error("index failed", error);
|
||||
@@ -206,13 +234,16 @@ export class ProviderShell implements Provider {
|
||||
|
||||
try {
|
||||
await this.tasks.restore({
|
||||
runId: message.runId,
|
||||
checkpointRef: message.location,
|
||||
machine: {
|
||||
cpu: "1",
|
||||
memory: "100Mi",
|
||||
},
|
||||
machine: message.machine,
|
||||
imageRef: message.imageRef,
|
||||
// identifiers
|
||||
envId: message.envId,
|
||||
envType: message.envType,
|
||||
orgId: message.orgId,
|
||||
projectId: message.projectId,
|
||||
runId: message.runId,
|
||||
checkpointId: message.checkpointId,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error("restore failed", error);
|
||||
@@ -230,54 +261,34 @@ export class ProviderShell implements Provider {
|
||||
|
||||
const reply = new HttpReply(res);
|
||||
|
||||
switch (req.url) {
|
||||
case "/health": {
|
||||
return reply.text("ok");
|
||||
}
|
||||
case "/whoami": {
|
||||
return reply.text(`${MACHINE_NAME}`);
|
||||
}
|
||||
case "/close": {
|
||||
this.#platformSocket.close();
|
||||
return reply.text("platform socket closed");
|
||||
}
|
||||
case "/delete": {
|
||||
const body = await getTextBody(req);
|
||||
try {
|
||||
const url = new URL(req.url ?? "", `http://${req.headers.host}`);
|
||||
|
||||
await this.tasks.delete({ runId: body });
|
||||
switch (url.pathname) {
|
||||
case "/health": {
|
||||
return reply.text("ok");
|
||||
}
|
||||
case "/whoami": {
|
||||
return reply.text(`${MACHINE_NAME}`);
|
||||
}
|
||||
case "/close": {
|
||||
this.#platformSocket.close();
|
||||
return reply.text("platform socket closed");
|
||||
}
|
||||
case "/delete": {
|
||||
const body = await getTextBody(req);
|
||||
|
||||
return reply.text(`sent delete request: ${body}`);
|
||||
}
|
||||
case "/invoke": {
|
||||
const body = await getTextBody(req);
|
||||
|
||||
await this.tasks.create({
|
||||
envId: "placeholder",
|
||||
image: body,
|
||||
machine: {
|
||||
cpu: "1",
|
||||
memory: "100Mi",
|
||||
},
|
||||
runId: "<missing>",
|
||||
version: "<missing>",
|
||||
});
|
||||
|
||||
return reply.text(`sent restore request: ${body}`);
|
||||
}
|
||||
case "/restore": {
|
||||
const body = await getTextBody(req);
|
||||
|
||||
const items = body.split("&");
|
||||
const image = items[0];
|
||||
const baseImageTag = items[1] ?? image;
|
||||
|
||||
// await this.tasks.restore({});
|
||||
|
||||
return reply.text(`sent restore request: ${body}`);
|
||||
}
|
||||
default: {
|
||||
return reply.empty(404);
|
||||
await this.tasks.delete({ runId: body });
|
||||
|
||||
return reply.text(`sent delete request: ${body}`);
|
||||
}
|
||||
default: {
|
||||
return reply.empty(404);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error("HTTP server error", { error });
|
||||
reply.empty(500);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# @trigger.dev/core-backend
|
||||
|
||||
## 3.0.0-beta.2
|
||||
|
||||
## 3.0.0-beta.1
|
||||
|
||||
## 3.0.0-beta.0
|
||||
|
||||
## 2.3.18
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@trigger.dev/core-backend",
|
||||
"version": "3.0.0-beta.0",
|
||||
"version": "3.0.0-beta.2",
|
||||
"description": "Core code used across `@trigger.dev/sdk` and Trigger.dev server",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
|
||||
@@ -94,20 +94,22 @@ export class Logger {
|
||||
...args: Array<Record<string, unknown> | undefined>
|
||||
) {
|
||||
// Get the current context from trace if it exists
|
||||
const currentContext = trace.getSpan(context.active());
|
||||
const currentSpan = trace.getSpan(context.active());
|
||||
|
||||
const structuredLog = {
|
||||
...structureArgs(safeJsonClone(args) as Record<string, unknown>[], this.#filteredKeys),
|
||||
...this.#additionalFields(),
|
||||
timestamp: new Date(),
|
||||
name: this.#name,
|
||||
message,
|
||||
level,
|
||||
traceId: currentContext?.spanContext().traceId,
|
||||
parentSpanId: currentContext?.spanContext().spanId,
|
||||
};
|
||||
if (!currentSpan || currentSpan.isRecording()) {
|
||||
const structuredLog = {
|
||||
...structureArgs(safeJsonClone(args) as Record<string, unknown>[], this.#filteredKeys),
|
||||
...this.#additionalFields(),
|
||||
timestamp: new Date(),
|
||||
name: this.#name,
|
||||
message,
|
||||
level,
|
||||
traceId: currentSpan?.spanContext().traceId,
|
||||
parentSpanId: currentSpan?.spanContext().spanId,
|
||||
};
|
||||
|
||||
loggerFunction(JSON.stringify(structuredLog, this.#jsonReplacer));
|
||||
loggerFunction(JSON.stringify(structuredLog, this.#jsonReplacer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# internal-platform
|
||||
|
||||
## 3.0.0-beta.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- e3cf456c6: Handle string and non-stringifiable outputs like functions
|
||||
|
||||
## 3.0.0-beta.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b66d5525e: add machine config and secure zod connection
|
||||
- 719c0a0b9: Fixed incorrect span timings around checkpoints by implementing a precise wall clock that resets after restores
|
||||
- f93eae300: Dynamically import superjson and fix some bundling issues
|
||||
|
||||
## 3.0.0-beta.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@trigger.dev/core",
|
||||
"version": "3.0.0-beta.0",
|
||||
"version": "3.0.0-beta.2",
|
||||
"description": "Core code used across the Trigger.dev SDK and platform",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// Split module-level variable definition into separate files to allow
|
||||
// tree-shaking on each api instance.
|
||||
import { ClockAPI } from "./clock";
|
||||
/** Entrypoint for clock API */
|
||||
export const clock = ClockAPI.getInstance();
|
||||
@@ -0,0 +1,6 @@
|
||||
export type ClockTime = [number, number];
|
||||
|
||||
export interface Clock {
|
||||
preciseNow(): ClockTime;
|
||||
reset(): void;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
const API_NAME = "clock";
|
||||
|
||||
import { getGlobal, registerGlobal } from "../utils/globals";
|
||||
import type { Clock, ClockTime } from "./clock";
|
||||
import { SimpleClock } from "./simpleClock";
|
||||
|
||||
const SIMPLE_CLOCK = new SimpleClock();
|
||||
|
||||
export class ClockAPI {
|
||||
private static _instance?: ClockAPI;
|
||||
|
||||
private constructor() {}
|
||||
|
||||
public static getInstance(): ClockAPI {
|
||||
if (!this._instance) {
|
||||
this._instance = new ClockAPI();
|
||||
}
|
||||
|
||||
return this._instance;
|
||||
}
|
||||
|
||||
public setGlobalClock(clock: Clock): boolean {
|
||||
return registerGlobal(API_NAME, clock);
|
||||
}
|
||||
|
||||
public preciseNow(): ClockTime {
|
||||
return this.#getClock().preciseNow();
|
||||
}
|
||||
|
||||
public reset(): void {
|
||||
this.#getClock().reset();
|
||||
}
|
||||
|
||||
#getClock(): Clock {
|
||||
return getGlobal(API_NAME) ?? SIMPLE_CLOCK;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import { PreciseDate } from "@google-cloud/precise-date";
|
||||
import { Clock, ClockTime } from "./clock";
|
||||
|
||||
export type PreciseWallClockOptions = {
|
||||
origin?: ClockTime;
|
||||
now?: PreciseDate;
|
||||
};
|
||||
|
||||
export class PreciseWallClock implements Clock {
|
||||
private _origin: {
|
||||
clockTime: ClockTime;
|
||||
preciseDate: PreciseDate;
|
||||
};
|
||||
|
||||
get #originClockTime() {
|
||||
return this._origin.clockTime;
|
||||
}
|
||||
|
||||
get #originPreciseDate() {
|
||||
return this._origin.preciseDate;
|
||||
}
|
||||
|
||||
constructor(options: PreciseWallClockOptions = {}) {
|
||||
this._origin = {
|
||||
clockTime: options.origin ?? process.hrtime(),
|
||||
preciseDate: options.now ?? new PreciseDate(),
|
||||
};
|
||||
}
|
||||
|
||||
preciseNow(): [number, number] {
|
||||
const elapsedHrTime = process.hrtime(this.#originClockTime);
|
||||
const elapsedNanoseconds = BigInt(elapsedHrTime[0]) * BigInt(1e9) + BigInt(elapsedHrTime[1]);
|
||||
|
||||
const preciseDate = new PreciseDate(this.#originPreciseDate.getFullTime() + elapsedNanoseconds);
|
||||
const dateStruct = preciseDate.toStruct();
|
||||
|
||||
return [dateStruct.seconds, dateStruct.nanos];
|
||||
}
|
||||
|
||||
reset() {
|
||||
this._origin = {
|
||||
clockTime: process.hrtime(),
|
||||
preciseDate: new PreciseDate(),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { PreciseDate } from "@google-cloud/precise-date";
|
||||
import { Clock } from "./clock";
|
||||
|
||||
export class SimpleClock implements Clock {
|
||||
preciseNow(): [number, number] {
|
||||
const now = new PreciseDate();
|
||||
const nowStruct = now.toStruct();
|
||||
|
||||
return [nowStruct.seconds, nowStruct.nanos];
|
||||
}
|
||||
|
||||
reset() {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
@@ -4,11 +4,11 @@ import util from "node:util";
|
||||
import { iconStringForSeverity } from "./icons";
|
||||
import { SemanticInternalAttributes } from "./semanticInternalAttributes";
|
||||
import { flattenAttributes } from "./utils/flattenAttributes";
|
||||
import { type PreciseDateOrigin, calculatePreciseDateHrTime } from "./utils/preciseDate";
|
||||
|
||||
import { ClockTime } from "./clock/clock";
|
||||
import { clock } from "./clock-api";
|
||||
|
||||
export class ConsoleInterceptor {
|
||||
constructor(private readonly logger: logsAPI.Logger, private readonly preciseDateOrigin: PreciseDateOrigin) { }
|
||||
constructor(private readonly logger: logsAPI.Logger) {}
|
||||
|
||||
// Intercept the console and send logs to the OpenTelemetry logger
|
||||
// during the execution of the callback
|
||||
@@ -39,24 +39,28 @@ export class ConsoleInterceptor {
|
||||
}
|
||||
|
||||
log(...args: unknown[]): void {
|
||||
this.#handleLog(SeverityNumber.INFO, "Log", ...args);
|
||||
this.#handleLog(SeverityNumber.INFO, this.#getTimestampInHrTime(), "Log", ...args);
|
||||
}
|
||||
|
||||
info(...args: unknown[]): void {
|
||||
this.#handleLog(SeverityNumber.INFO, "Info", ...args);
|
||||
this.#handleLog(SeverityNumber.INFO, this.#getTimestampInHrTime(), "Info", ...args);
|
||||
}
|
||||
|
||||
warn(...args: unknown[]): void {
|
||||
this.#handleLog(SeverityNumber.WARN, "Warn", ...args);
|
||||
this.#handleLog(SeverityNumber.WARN, this.#getTimestampInHrTime(), "Warn", ...args);
|
||||
}
|
||||
|
||||
error(...args: unknown[]): void {
|
||||
this.#handleLog(SeverityNumber.ERROR, "Error", ...args);
|
||||
this.#handleLog(SeverityNumber.ERROR, this.#getTimestampInHrTime(), "Error", ...args);
|
||||
}
|
||||
|
||||
#handleLog(severityNumber: SeverityNumber, severityText: string, ...args: unknown[]): void {
|
||||
#handleLog(
|
||||
severityNumber: SeverityNumber,
|
||||
timestamp: ClockTime,
|
||||
severityText: string,
|
||||
...args: unknown[]
|
||||
): void {
|
||||
const body = util.format(...args);
|
||||
const timestamp = this.#getTimestampInHrTime();
|
||||
|
||||
const parsed = tryParseJSON(body);
|
||||
|
||||
@@ -81,8 +85,8 @@ export class ConsoleInterceptor {
|
||||
});
|
||||
}
|
||||
|
||||
#getTimestampInHrTime(): [number, number] {
|
||||
return calculatePreciseDateHrTime(this.preciseDateOrigin);
|
||||
#getTimestampInHrTime(): ClockTime {
|
||||
return clock.preciseNow();
|
||||
}
|
||||
|
||||
#getAttributes(severityNumber: SeverityNumber): logsAPI.LogAttributes {
|
||||
|
||||
@@ -9,6 +9,7 @@ export * from "./zodIpc";
|
||||
export * from "./errors";
|
||||
export * from "./runtime-api";
|
||||
export * from "./logger-api";
|
||||
export * from "./clock-api";
|
||||
export * from "./types";
|
||||
export * from "./limits";
|
||||
export { SemanticInternalAttributes } from "./semanticInternalAttributes";
|
||||
@@ -35,6 +36,7 @@ export { taskContextManager, TaskContextSpanProcessor } from "./tasks/taskContex
|
||||
export type { RuntimeManager } from "./runtime/manager";
|
||||
export { DevRuntimeManager } from "./runtime/devRuntimeManager";
|
||||
export { ProdRuntimeManager } from "./runtime/prodRuntimeManager";
|
||||
export { PreciseWallClock as DurableClock } from "./clock/preciseWallClock";
|
||||
export { TriggerTracer } from "./tracer";
|
||||
|
||||
export type { TaskLogger } from "./logger/taskLogger";
|
||||
@@ -57,17 +59,12 @@ export { omit } from "./utils/omit";
|
||||
export { TracingSDK, type TracingDiagnosticLogLevel, recordSpanException } from "./otel";
|
||||
export { TaskExecutor, type TaskExecutorOptions } from "./workers/taskExecutor";
|
||||
export { detectDependencyVersion } from "./utils/detectDependencyVersion";
|
||||
export {
|
||||
type PreciseDateOrigin,
|
||||
calculatePreciseDateHrTime,
|
||||
preciseDateOriginNow,
|
||||
} from "./utils/preciseDate";
|
||||
export {
|
||||
parsePacket,
|
||||
stringifyIO,
|
||||
prettyPrintPacket,
|
||||
createPacketAttributes,
|
||||
createPackageAttributesAsJson,
|
||||
createPacketAttributesAsJson,
|
||||
conditionallyExportPacket,
|
||||
conditionallyImportPacket,
|
||||
packetRequiresOffloading,
|
||||
|
||||
@@ -4,7 +4,8 @@ import { iconStringForSeverity } from "../icons";
|
||||
import { SemanticInternalAttributes } from "../semanticInternalAttributes";
|
||||
import { TriggerTracer } from "../tracer";
|
||||
import { flattenAttributes } from "../utils/flattenAttributes";
|
||||
import { PreciseDateOrigin, calculatePreciseDateHrTime } from "../utils/preciseDate";
|
||||
import { ClockTime } from "../clock/clock";
|
||||
import { clock } from "../clock-api";
|
||||
|
||||
export type LogLevel = "log" | "error" | "warn" | "info" | "debug";
|
||||
|
||||
@@ -14,7 +15,6 @@ export type TaskLoggerConfig = {
|
||||
logger: Logger;
|
||||
tracer: TriggerTracer;
|
||||
level: LogLevel;
|
||||
preciseDateOrigin: PreciseDateOrigin;
|
||||
};
|
||||
|
||||
export interface TaskLogger {
|
||||
@@ -36,41 +36,40 @@ export class OtelTaskLogger implements TaskLogger {
|
||||
debug(message: string, properties?: Record<string, unknown>) {
|
||||
if (this._level < 4) return;
|
||||
|
||||
this.#emitLog(message, "debug", SeverityNumber.DEBUG, properties);
|
||||
this.#emitLog(message, this.#getTimestampInHrTime(), "debug", SeverityNumber.DEBUG, properties);
|
||||
}
|
||||
|
||||
log(message: string, properties?: Record<string, unknown>) {
|
||||
if (this._level < 2) return;
|
||||
|
||||
this.#emitLog(message, "log", SeverityNumber.INFO, properties);
|
||||
this.#emitLog(message, this.#getTimestampInHrTime(), "log", SeverityNumber.INFO, properties);
|
||||
}
|
||||
|
||||
info(message: string, properties?: Record<string, unknown>) {
|
||||
if (this._level < 3) return;
|
||||
|
||||
this.#emitLog(message, "info", SeverityNumber.INFO, properties);
|
||||
this.#emitLog(message, this.#getTimestampInHrTime(), "info", SeverityNumber.INFO, properties);
|
||||
}
|
||||
|
||||
warn(message: string, properties?: Record<string, unknown>) {
|
||||
if (this._level < 1) return;
|
||||
|
||||
this.#emitLog(message, "warn", SeverityNumber.WARN, properties);
|
||||
this.#emitLog(message, this.#getTimestampInHrTime(), "warn", SeverityNumber.WARN, properties);
|
||||
}
|
||||
|
||||
error(message: string, properties?: Record<string, unknown>) {
|
||||
if (this._level < 0) return;
|
||||
|
||||
this.#emitLog(message, "error", SeverityNumber.ERROR, properties);
|
||||
this.#emitLog(message, this.#getTimestampInHrTime(), "error", SeverityNumber.ERROR, properties);
|
||||
}
|
||||
|
||||
#emitLog(
|
||||
message: string,
|
||||
timestamp: ClockTime,
|
||||
severityText: string,
|
||||
severityNumber: SeverityNumber,
|
||||
properties?: Record<string, unknown>
|
||||
) {
|
||||
const timestamp = this.#getTimestampInHrTime();
|
||||
|
||||
let attributes: Attributes = { ...flattenAttributes(properties) };
|
||||
|
||||
const icon = iconStringForSeverity(severityNumber);
|
||||
@@ -83,7 +82,7 @@ export class OtelTaskLogger implements TaskLogger {
|
||||
severityText,
|
||||
body: message,
|
||||
attributes,
|
||||
timestamp
|
||||
timestamp,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -91,17 +90,17 @@ export class OtelTaskLogger implements TaskLogger {
|
||||
return this._config.tracer.startActiveSpan(name, fn, options);
|
||||
}
|
||||
|
||||
#getTimestampInHrTime(): [number, number] {
|
||||
return calculatePreciseDateHrTime(this._config.preciseDateOrigin);
|
||||
#getTimestampInHrTime(): ClockTime {
|
||||
return clock.preciseNow();
|
||||
}
|
||||
}
|
||||
|
||||
export class NoopTaskLogger implements TaskLogger {
|
||||
debug() { }
|
||||
log() { }
|
||||
info() { }
|
||||
warn() { }
|
||||
error() { }
|
||||
debug() {}
|
||||
log() {}
|
||||
info() {}
|
||||
warn() {}
|
||||
error() {}
|
||||
trace<T>(name: string, fn: (span: Span) => Promise<T>): Promise<T> {
|
||||
return fn({} as Span);
|
||||
}
|
||||
|
||||
@@ -15,16 +15,18 @@ import {
|
||||
detectResourcesSync,
|
||||
processDetectorSync,
|
||||
} from "@opentelemetry/resources";
|
||||
import { LoggerProvider, SimpleLogRecordProcessor } from "@opentelemetry/sdk-logs";
|
||||
import {
|
||||
BatchLogRecordProcessor,
|
||||
LoggerProvider,
|
||||
SimpleLogRecordProcessor,
|
||||
} from "@opentelemetry/sdk-logs";
|
||||
import {
|
||||
BatchSpanProcessor,
|
||||
NodeTracerProvider,
|
||||
SimpleSpanProcessor,
|
||||
SpanExporter,
|
||||
} from "@opentelemetry/sdk-trace-node";
|
||||
import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions";
|
||||
import { SemanticInternalAttributes } from "../semanticInternalAttributes";
|
||||
import { TaskContextLogProcessor, TaskContextSpanProcessor } from "../tasks/taskContextManager";
|
||||
import { getEnvVar } from "../utils/getEnv";
|
||||
import {
|
||||
OTEL_ATTRIBUTE_PER_EVENT_COUNT_LIMIT,
|
||||
OTEL_ATTRIBUTE_PER_LINK_COUNT_LIMIT,
|
||||
@@ -35,6 +37,9 @@ import {
|
||||
OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT,
|
||||
OTEL_SPAN_EVENT_COUNT_LIMIT,
|
||||
} from "../limits";
|
||||
import { SemanticInternalAttributes } from "../semanticInternalAttributes";
|
||||
import { TaskContextLogProcessor, TaskContextSpanProcessor } from "../tasks/taskContextManager";
|
||||
import { getEnvVar } from "../utils/getEnv";
|
||||
|
||||
class AsyncResourceDetector implements DetectorSync {
|
||||
private _promise: Promise<ResourceAttributes>;
|
||||
@@ -130,8 +135,22 @@ export class TracingSDK {
|
||||
});
|
||||
|
||||
traceProvider.addSpanProcessor(
|
||||
new TaskContextSpanProcessor(new SimpleSpanProcessor(spanExporter))
|
||||
new TaskContextSpanProcessor(
|
||||
getEnvVar("OTEL_BATCH_PROCESSING_ENABLED") === "1"
|
||||
? new BatchSpanProcessor(spanExporter, {
|
||||
maxExportBatchSize: parseInt(getEnvVar("OTEL_SPAN_MAX_EXPORT_BATCH_SIZE") ?? "64"),
|
||||
scheduledDelayMillis: parseInt(
|
||||
getEnvVar("OTEL_SPAN_SCHEDULED_DELAY_MILLIS") ?? "200"
|
||||
),
|
||||
exportTimeoutMillis: parseInt(
|
||||
getEnvVar("OTEL_SPAN_EXPORT_TIMEOUT_MILLIS") ?? "30000"
|
||||
),
|
||||
maxQueueSize: parseInt(getEnvVar("OTEL_SPAN_MAX_QUEUE_SIZE") ?? "512"),
|
||||
})
|
||||
: new SimpleSpanProcessor(spanExporter)
|
||||
)
|
||||
);
|
||||
|
||||
traceProvider.register();
|
||||
|
||||
registerInstrumentations({
|
||||
@@ -153,7 +172,16 @@ export class TracingSDK {
|
||||
});
|
||||
|
||||
loggerProvider.addLogRecordProcessor(
|
||||
new TaskContextLogProcessor(new SimpleLogRecordProcessor(logExporter))
|
||||
new TaskContextLogProcessor(
|
||||
getEnvVar("OTEL_BATCH_PROCESSING_ENABLED") === "1"
|
||||
? new BatchLogRecordProcessor(logExporter, {
|
||||
maxExportBatchSize: parseInt(getEnvVar("OTEL_LOG_MAX_EXPORT_BATCH_SIZE") ?? "64"),
|
||||
scheduledDelayMillis: parseInt(getEnvVar("OTEL_LOG_SCHEDULED_DELAY_MILLIS") ?? "200"),
|
||||
exportTimeoutMillis: parseInt(getEnvVar("OTEL_LOG_EXPORT_TIMEOUT_MILLIS") ?? "30000"),
|
||||
maxQueueSize: parseInt(getEnvVar("OTEL_LOG_MAX_QUEUE_SIZE") ?? "512"),
|
||||
})
|
||||
: new SimpleLogRecordProcessor(logExporter)
|
||||
)
|
||||
);
|
||||
|
||||
this._logProvider = loggerProvider;
|
||||
|
||||
@@ -5,7 +5,6 @@ import {
|
||||
TaskRunExecution,
|
||||
TaskRunExecutionResult,
|
||||
} from "../schemas";
|
||||
import { conditionallyImportPacket } from "../utils/ioSerialization";
|
||||
import { RuntimeManager } from "./manager";
|
||||
|
||||
export class DevRuntimeManager implements RuntimeManager {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { clock } from "../clock-api";
|
||||
import {
|
||||
BatchTaskRunExecutionResult,
|
||||
ProdChildToWorkerMessages,
|
||||
@@ -9,6 +10,11 @@ import {
|
||||
} from "../schemas";
|
||||
import { ZodIpcConnection } from "../zodIpc";
|
||||
import { RuntimeManager } from "./manager";
|
||||
import { setTimeout } from "node:timers/promises";
|
||||
|
||||
export type ProdRuntimeManagerOptions = {
|
||||
waitThresholdInMs?: number;
|
||||
};
|
||||
|
||||
export class ProdRuntimeManager implements RuntimeManager {
|
||||
_taskWaits: Map<
|
||||
@@ -21,7 +27,7 @@ export class ProdRuntimeManager implements RuntimeManager {
|
||||
{ resolve: (value: BatchTaskRunExecutionResult) => void; reject: (err?: any) => void }
|
||||
> = new Map();
|
||||
|
||||
_waitForRestore: { resolve: (value?: any) => void; reject: (err?: any) => void } | undefined;
|
||||
_waitForRestore: { resolve: (value: "restore") => void; reject: (err?: any) => void } | undefined;
|
||||
|
||||
_tasks: Map<string, TaskMetadataWithFilePath> = new Map();
|
||||
|
||||
@@ -29,7 +35,8 @@ export class ProdRuntimeManager implements RuntimeManager {
|
||||
private ipc: ZodIpcConnection<
|
||||
typeof ProdWorkerToChildMessages,
|
||||
typeof ProdChildToWorkerMessages
|
||||
>
|
||||
>,
|
||||
private options: ProdRuntimeManagerOptions = {}
|
||||
) {}
|
||||
|
||||
disable(): void {
|
||||
@@ -47,20 +54,16 @@ export class ProdRuntimeManager implements RuntimeManager {
|
||||
}
|
||||
|
||||
async waitForDuration(ms: number): Promise<void> {
|
||||
let timeout: NodeJS.Timeout | undefined;
|
||||
|
||||
const now = Date.now();
|
||||
|
||||
const resolveAfterDuration = new Promise((resolve) => {
|
||||
timeout = setTimeout(resolve, ms);
|
||||
});
|
||||
const resolveAfterDuration = setTimeout(ms, "duration" as const);
|
||||
|
||||
if (ms < 10_000) {
|
||||
if (ms <= this.waitThresholdInMs) {
|
||||
await resolveAfterDuration;
|
||||
return;
|
||||
}
|
||||
|
||||
const waitForRestore = new Promise((resolve, reject) => {
|
||||
const waitForRestore = new Promise<"restore">((resolve, reject) => {
|
||||
this._waitForRestore = { resolve, reject };
|
||||
});
|
||||
|
||||
@@ -81,8 +84,6 @@ export class ProdRuntimeManager implements RuntimeManager {
|
||||
|
||||
// The coordinator can then cancel any in-progress checkpoints
|
||||
this.ipc.send("CANCEL_CHECKPOINT", {});
|
||||
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
|
||||
resumeAfterRestore(): void {
|
||||
@@ -90,7 +91,10 @@ export class ProdRuntimeManager implements RuntimeManager {
|
||||
return;
|
||||
}
|
||||
|
||||
this._waitForRestore.resolve();
|
||||
// Resets the clock to the current time
|
||||
clock.reset();
|
||||
|
||||
this._waitForRestore.resolve("restore");
|
||||
this._waitForRestore = undefined;
|
||||
}
|
||||
|
||||
@@ -155,4 +159,8 @@ export class ProdRuntimeManager implements RuntimeManager {
|
||||
|
||||
this._taskWaits.delete(execution.run.id);
|
||||
}
|
||||
|
||||
private get waitThresholdInMs(): number {
|
||||
return this.options.waitThresholdInMs ?? 30_000;
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user