Skip to content

Commit 395abe1

Browse files
authored
v3: Various fixes to support papermark use-case (#970)
* Adding a changeset for v3 * Add a version field to @trigger.dev/core-apps package.json * Build trigger.dev when doing a prerelease * bundle @trigger.dev/core-apps with trigger.dev cli * Fix the init command config template * Don’t use * for the @trigger.dev/core dep version specifier * strip workspace: from the package version before installing it * Added dependenciesToBundle config option to bundle ESM only packages * Added logging around resolving dependency paths * Try again * Resolve dependencies based on the project dir first * flip the bundled default * Adding some logs around dev task completion notifications * Adding some additional logs * Add more logs * Write out the log using process.stdout * Store pending completion notifications and resume them when awaited (fixes race condition) * Cleanup some of the logs * Copy over the postinstall step from the projects package.json * Add support for including additional files when deploying (e.g. prisma schema) * Don’t run scripts when resolving deps * copy all the files just in case anything is needed in postinstall * Remove duplicate option * Use the tag when outputting the dev command * Remove the postinstall script * add the trigger dir to the config if the default is not chosen * Remove the “hud” display in the dev command * trigger file names with dashes now work * Better file watching in dev * Much better duplicate ID experience now * Much better “Project not found” error * Export the handleError function types from sdk * Add support for configuring instrumentation * Upgrade and unify @opentelemetry/* packages (and remove storybook from the webapp) * Fix typescript error in react package * Upgrade react types in webapp * Allow span icons to be determined based on the span name (e.g. prisma:) * Ignore built-in env vars when checking for env vars, and allow continuing the deployment even if missing env vars were detected * Improve the retry.fetch default behavior and option structure * Fixed typescript errors with packages/email react types * Update the retry.fetch docs
1 parent b35eebb commit 395abe1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+3922
-10494
lines changed

.changeset/config.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616
"emails",
1717
"proxy",
1818
"yalt",
19-
"@trigger.dev/database"
19+
"@trigger.dev/database",
20+
"coordinator",
21+
"docker-provider",
22+
"kubernetes-provider"
2023
],
2124
"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
2225
"onlyUpdatePeerDependentsWhenOutOfRange": true

.changeset/sweet-lizards-press.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"trigger.dev": major
3+
"@trigger.dev/core": major
4+
"@trigger.dev/otlp-importer": major
5+
"@trigger.dev/sdk": major
6+
---
7+
8+
Updates to support Trigger.dev v3

CHANGESETS.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pnpm exec changeset version --snapshot prerelease
4747
3. Build the packages:
4848

4949
```sh
50-
pnpm run build --filter "@trigger.dev/*"
50+
pnpm run build --filter "@trigger.dev/*" --filter "trigger.dev"
5151
```
5252

5353
4. Publish the snapshot (replace "dev" with your tag)

apps/webapp/.storybook/main.ts

-48
This file was deleted.

apps/webapp/.storybook/preview.tsx

-50
This file was deleted.

apps/webapp/app/components/runs/v3/RunIcon.tsx

+21-1
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,30 @@ import { cn } from "~/utils/cn";
1212

1313
type TaskIconProps = {
1414
name: string | undefined;
15+
spanName: string;
1516
className?: string;
1617
};
1718

18-
export function RunIcon({ name, className }: TaskIconProps) {
19+
type SpanNameIcons = {
20+
matcher: RegExp;
21+
iconName: string;
22+
};
23+
24+
const spanNameIcons: SpanNameIcons[] = [{ matcher: /^prisma:/, iconName: "brand-prisma" }];
25+
26+
export function RunIcon({ name, className, spanName }: TaskIconProps) {
27+
const spanNameIcon = spanNameIcons.find(({ matcher }) => matcher.test(spanName));
28+
29+
if (spanNameIcon) {
30+
return (
31+
<NamedIcon
32+
name={spanNameIcon.iconName}
33+
className={cn(className)}
34+
fallback={<InformationCircleIcon className={cn(className, "text-text-dimmed")} />}
35+
/>
36+
);
37+
}
38+
1939
if (!name) return <Squares2X2Icon className={cn(className, "text-text-dimmed")} />;
2040

2141
switch (name) {

apps/webapp/app/entry.server.tsx

-17
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { H } from "@highlight-run/node";
21
import {
32
createReadableStreamFromReadable,
43
type DataFunctionArgs,
@@ -165,10 +164,6 @@ function handleBrowserRequest(
165164
});
166165
}
167166

168-
if (env.HIGHLIGHT_PROJECT_ID) {
169-
H.init({ projectID: env.HIGHLIGHT_PROJECT_ID });
170-
}
171-
172167
export function handleError(error: unknown, { request, params, context }: DataFunctionArgs) {
173168
logError(error, request);
174169
}
@@ -178,18 +173,6 @@ Worker.init().catch((error) => {
178173
});
179174

180175
function logError(error: unknown, request?: Request) {
181-
if (env.HIGHLIGHT_PROJECT_ID) {
182-
const parsed = request ? H.parseHeaders(Object.fromEntries(request.headers)) : undefined;
183-
if (error instanceof Error) {
184-
H.consumeError(error, parsed?.secureSessionId, parsed?.requestId);
185-
} else {
186-
H.consumeError(
187-
new Error(`Unknown error: ${JSON.stringify(error)}`),
188-
parsed?.secureSessionId,
189-
parsed?.requestId
190-
);
191-
}
192-
}
193176
console.error(error);
194177
}
195178

apps/webapp/app/root.tsx

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { ErrorBoundary as HighlightErrorBoundary } from "@highlight-run/react";
21
import type { LinksFunction, LoaderFunctionArgs, MetaFunction } from "@remix-run/node";
32
import type { ShouldRevalidateFunction } from "@remix-run/react";
43
import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from "@remix-run/react";
@@ -111,9 +110,7 @@ function App() {
111110
<Links />
112111
</head>
113112
<body className="bg-darkBackground h-full overflow-hidden">
114-
<HighlightErrorBoundary>
115-
<Outlet />
116-
</HighlightErrorBoundary>
113+
<Outlet />
117114
<Toast />
118115
<ScrollRestoration />
119116
<ExternalScripts />

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam.spans.$spanParam/route.tsx

+5-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,11 @@ export default function Page() {
6060
>
6161
<div className="mx-3 flex items-center justify-between gap-2 border-b border-grid-dimmed">
6262
<div className="flex items-center gap-1 overflow-x-hidden">
63-
<RunIcon name={event.style?.icon} className="h-4 min-h-4 w-4 min-w-4" />
63+
<RunIcon
64+
name={event.style?.icon}
65+
spanName={event.message}
66+
className="h-4 min-h-4 w-4 min-w-4"
67+
/>
6468
<Header2 className={cn("whitespace-nowrap")}>
6569
<SpanTitle {...event} size="large" />
6670
</Header2>

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx

+5-1
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,11 @@ function TasksTreeView({
362362

363363
<div className="flex w-full items-center justify-between gap-2 pl-1">
364364
<div className="flex items-center gap-2 overflow-x-hidden">
365-
<RunIcon name={node.data.style?.icon} className="h-4 min-h-4 w-4 min-w-4" />
365+
<RunIcon
366+
name={node.data.style?.icon}
367+
spanName={node.data.message}
368+
className="h-4 min-h-4 w-4 min-w-4"
369+
/>
366370
<NodeText node={node} />
367371
{node.data.isRoot && <Badge variant="outline-rounded">Root</Badge>}
368372
</div>

apps/webapp/app/v3/services/createBackgroundWorker.server.ts

+73-36
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { CreateBackgroundWorkerRequestBody, TaskResource } from "@trigger.dev/core/v3";
22
import type { BackgroundWorker } from "@trigger.dev/database";
3-
import { PrismaClientOrTransaction } from "~/db.server";
3+
import { Prisma, PrismaClientOrTransaction } from "~/db.server";
44
import { AuthenticatedEnvironment } from "~/services/apiAuth.server";
55
import { logger } from "~/services/logger.server";
66
import { generateFriendlyId } from "../friendlyIdentifiers";
@@ -89,46 +89,83 @@ export async function createBackgroundTasks(
8989
prisma: PrismaClientOrTransaction
9090
) {
9191
for (const task of tasks) {
92-
await prisma.backgroundWorkerTask.create({
93-
data: {
94-
friendlyId: generateFriendlyId("task"),
95-
projectId: worker.projectId,
96-
runtimeEnvironmentId: worker.runtimeEnvironmentId,
97-
workerId: worker.id,
98-
slug: task.id,
99-
filePath: task.filePath,
100-
exportName: task.exportName,
101-
retryConfig: task.retry,
102-
queueConfig: task.queue,
103-
},
104-
});
92+
try {
93+
await prisma.backgroundWorkerTask.create({
94+
data: {
95+
friendlyId: generateFriendlyId("task"),
96+
projectId: worker.projectId,
97+
runtimeEnvironmentId: worker.runtimeEnvironmentId,
98+
workerId: worker.id,
99+
slug: task.id,
100+
filePath: task.filePath,
101+
exportName: task.exportName,
102+
retryConfig: task.retry,
103+
queueConfig: task.queue,
104+
},
105+
});
105106

106-
const queueName = task.queue?.name ?? `task/${task.id}`;
107+
const queueName = task.queue?.name ?? `task/${task.id}`;
107108

108-
const taskQueue = await prisma.taskQueue.upsert({
109-
where: {
110-
runtimeEnvironmentId_name: {
111-
runtimeEnvironmentId: worker.runtimeEnvironmentId,
109+
const taskQueue = await prisma.taskQueue.upsert({
110+
where: {
111+
runtimeEnvironmentId_name: {
112+
runtimeEnvironmentId: worker.runtimeEnvironmentId,
113+
name: queueName,
114+
},
115+
},
116+
update: {
117+
concurrencyLimit: task.queue?.concurrencyLimit,
118+
rateLimit: task.queue?.rateLimit,
119+
},
120+
create: {
121+
friendlyId: generateFriendlyId("queue"),
112122
name: queueName,
123+
concurrencyLimit: task.queue?.concurrencyLimit,
124+
runtimeEnvironmentId: worker.runtimeEnvironmentId,
125+
projectId: worker.projectId,
126+
rateLimit: task.queue?.rateLimit,
127+
type: task.queue?.name ? "NAMED" : "VIRTUAL",
113128
},
114-
},
115-
update: {
116-
concurrencyLimit: task.queue?.concurrencyLimit,
117-
rateLimit: task.queue?.rateLimit,
118-
},
119-
create: {
120-
friendlyId: generateFriendlyId("queue"),
121-
name: queueName,
122-
concurrencyLimit: task.queue?.concurrencyLimit,
123-
runtimeEnvironmentId: worker.runtimeEnvironmentId,
124-
projectId: worker.projectId,
125-
rateLimit: task.queue?.rateLimit,
126-
type: task.queue?.name ? "NAMED" : "VIRTUAL",
127-
},
128-
});
129+
});
129130

130-
if (taskQueue.concurrencyLimit) {
131-
await marqs?.updateQueueConcurrency(env, taskQueue.name, taskQueue.concurrencyLimit);
131+
if (taskQueue.concurrencyLimit) {
132+
await marqs?.updateQueueConcurrency(env, taskQueue.name, taskQueue.concurrencyLimit);
133+
}
134+
} catch (error) {
135+
if (error instanceof Prisma.PrismaClientKnownRequestError) {
136+
// The error code for unique constraint violation in Prisma is P2002
137+
if (error.code === "P2002") {
138+
logger.warn("Task already exists", {
139+
task,
140+
worker,
141+
});
142+
} else {
143+
logger.error("Prisma Error creating background worker task", {
144+
error: {
145+
code: error.code,
146+
message: error.message,
147+
},
148+
task,
149+
worker,
150+
});
151+
}
152+
} else if (error instanceof Error) {
153+
logger.error("Error creating background worker task", {
154+
error: {
155+
name: error.name,
156+
message: error.message,
157+
stack: error.stack,
158+
},
159+
task,
160+
worker,
161+
});
162+
} else {
163+
logger.error("Unknown error creating background worker task", {
164+
error,
165+
task,
166+
worker,
167+
});
168+
}
132169
}
133170
}
134171
}

0 commit comments

Comments
 (0)