Skip to content

Commit 6051ee9

Browse files
committed
new monitor logic
1 parent c35fe24 commit 6051ee9

File tree

2 files changed

+34
-59
lines changed

2 files changed

+34
-59
lines changed

apps/uptime/src/index.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ const app = new Elysia()
8989

9090
const headerSchema = z.object({
9191
"upstash-signature": z.string(),
92-
"x-schedule-id": z.string(),
93-
"x-max-retries": z.string().optional(),
92+
"upstash-schedule-id": z.string(),
93+
"upstash-retried": z.string().optional(),
9494
});
9595

9696
const parsed = headerSchema.safeParse(headers);
@@ -108,7 +108,7 @@ const app = new Elysia()
108108
);
109109
}
110110

111-
const { "upstash-signature": signature, "x-schedule-id": scheduleId } =
111+
const { "upstash-signature": signature, "upstash-schedule-id": scheduleId } =
112112
parsed.data;
113113

114114
const isValid = await receiver.verify({
@@ -143,8 +143,8 @@ const app = new Elysia()
143143

144144
const monitorId = schedule.data.websiteId || scheduleId;
145145

146-
const maxRetries = parsed.data["x-max-retries"]
147-
? Number.parseInt(parsed.data["x-max-retries"], 10)
146+
const maxRetries = parsed.data["upstash-retried"]
147+
? Number.parseInt(parsed.data["upstash-retried"], 10) + 3
148148
: 3;
149149

150150
const result = await checkUptime(monitorId, schedule.data.url, 1, maxRetries);

packages/rpc/src/routers/uptime.ts

Lines changed: 29 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
import { db, eq, and, uptimeSchedules } from "@databuddy/db";
1+
import { and, db, eq, uptimeSchedules } from "@databuddy/db";
22
import { logger } from "@databuddy/shared/logger";
33
import { ORPCError } from "@orpc/server";
44
import { Client } from "@upstash/qstash";
55
import { z } from "zod";
66
import { recordORPCError } from "../lib/otel";
77
import { protectedProcedure } from "../orpc";
8-
import { authorizeWebsiteAccess, authorizeUptimeScheduleAccess } from "../utils/auth";
9-
import { nanoid } from "nanoid";
8+
import {
9+
authorizeUptimeScheduleAccess,
10+
authorizeWebsiteAccess,
11+
} from "../utils/auth";
12+
1013
if (!process.env.UPSTASH_QSTASH_TOKEN) {
1114
logger.error("UPSTASH_QSTASH_TOKEN environment variable is required");
1215
}
@@ -52,17 +55,12 @@ async function findScheduleByWebsiteId(websiteId: string) {
5255
return schedule;
5356
}
5457

55-
async function createQStashSchedule(
56-
scheduleId: string,
57-
granularity: z.infer<typeof granularityEnum>
58-
) {
58+
async function createQStashSchedule(granularity: z.infer<typeof granularityEnum>) {
5959
const result = await client.schedules.create({
60-
scheduleId,
6160
destination: UPTIME_URL_GROUP,
6261
cron: CRON_GRANULARITIES[granularity],
6362
headers: {
6463
"Content-Type": "application/json",
65-
"X-Schedule-Id": scheduleId,
6664
},
6765
});
6866

@@ -195,8 +193,7 @@ export const uptimeRouter = {
195193
input.websiteId ?? null
196194
);
197195

198-
const scheduleId = input.websiteId ? input.websiteId : nanoid(10);
199-
await createQStashSchedule(scheduleId, input.granularity);
196+
const scheduleId = await createQStashSchedule(input.granularity);
200197

201198
await db.insert(uptimeSchedules).values({
202199
id: scheduleId,
@@ -209,19 +206,6 @@ export const uptimeRouter = {
209206
isPaused: false,
210207
});
211208

212-
try {
213-
await client.publish({
214-
urlGroup: UPTIME_URL_GROUP,
215-
headers: {
216-
"Content-Type": "application/json",
217-
"X-Schedule-Id": scheduleId,
218-
},
219-
});
220-
logger.info({ scheduleId }, "Triggered uptime check after creation");
221-
} catch (error) {
222-
logger.error({ scheduleId, error }, "Failed to trigger initial check");
223-
}
224-
225209
logger.info(
226210
{
227211
scheduleId,
@@ -245,6 +229,8 @@ export const uptimeRouter = {
245229
.input(
246230
z.object({
247231
scheduleId: z.string().min(1, "Schedule ID is required"),
232+
url: z.string().url("Valid URL is required"),
233+
name: z.string().optional(),
248234
granularity: granularityEnum,
249235
})
250236
)
@@ -266,47 +252,36 @@ export const uptimeRouter = {
266252
userId: schedule.userId,
267253
});
268254

269-
try {
270-
await client.schedules.delete(input.scheduleId);
271-
} catch (error) {
272-
logger.error(
273-
{ scheduleId: input.scheduleId, error },
274-
"Failed to delete old QStash schedule during update"
275-
);
276-
recordORPCError({
277-
code: "INTERNAL_SERVER_ERROR",
278-
message: "Failed to delete old QStash schedule",
279-
});
280-
throw new ORPCError("INTERNAL_SERVER_ERROR", {
281-
message: "Failed to delete old QStash schedule. Please try again.",
282-
});
283-
}
255+
await client.schedules.delete(input.scheduleId);
256+
const newScheduleId = await createQStashSchedule(input.granularity);
284257

285-
await db
286-
.update(uptimeSchedules)
287-
.set({
288-
granularity: input.granularity,
289-
cron: CRON_GRANULARITIES[input.granularity],
290-
updatedAt: new Date(),
291-
})
292-
.where(eq(uptimeSchedules.id, input.scheduleId));
258+
await db.delete(uptimeSchedules).where(eq(uptimeSchedules.id, input.scheduleId));
293259

294-
const newScheduleId = await createQStashSchedule(
295-
input.scheduleId,
296-
input.granularity
297-
);
260+
await db.insert(uptimeSchedules).values({
261+
id: newScheduleId,
262+
websiteId: schedule.websiteId,
263+
userId: schedule.userId,
264+
url: input.url,
265+
name: input.name ?? null,
266+
granularity: input.granularity,
267+
cron: CRON_GRANULARITIES[input.granularity],
268+
isPaused: false,
269+
});
298270

299271
logger.info(
300272
{
301-
scheduleId: input.scheduleId,
273+
oldScheduleId: input.scheduleId,
274+
newScheduleId,
275+
url: input.url,
302276
granularity: input.granularity,
303-
userId: context.user.id,
304277
},
305278
"Uptime schedule updated"
306279
);
307280

308281
return {
309-
scheduleId: input.scheduleId,
282+
scheduleId: newScheduleId,
283+
url: input.url,
284+
name: input.name,
310285
granularity: input.granularity,
311286
cron: CRON_GRANULARITIES[input.granularity],
312287
};

0 commit comments

Comments
 (0)