Skip to content

Commit e988339

Browse files
committed
Found root cause: doesn't get successful observations in winter, so never does any clean-up
1 parent 0606cb0 commit e988339

2 files changed

Lines changed: 54 additions & 77 deletions

File tree

website/workers/app.ts

Lines changed: 54 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ declare module "react-router" {
2222

2323
const requestHandler = createRequestHandler(
2424
() => import("virtual:react-router/server-build"),
25-
import.meta.env.MODE
25+
import.meta.env.MODE,
2626
);
2727

2828
export default {
@@ -49,7 +49,7 @@ export default {
4949
0,
5050
0,
5151
0,
52-
0
52+
0,
5353
);
5454
// Get all dates which have observations where uploaded to R2 is false
5555
const allDates = await db
@@ -60,8 +60,8 @@ export default {
6060
.where(
6161
and(
6262
lt(schema.Observations.timestamp, todayAtMidnight),
63-
eq(schema.Observations.exportedToR2, false)
64-
)
63+
eq(schema.Observations.exportedToR2, false),
64+
),
6565
)
6666
.orderBy(asc(sql`date(timestamp)`))
6767
.limit(99) // Limit to 99 days which is the limit of the number of workflow instances you can create in a batch
@@ -74,22 +74,26 @@ export default {
7474
days.map((day) => ({
7575
id: `overnight-save-${day.toISOString().split("T")[0]}`,
7676
params: { dayToProcess: day },
77-
}))
77+
})),
7878
);
7979
console.log(`Created ${days.length} workflow instances`);
80-
const tenDaysAgo = new Date(
80+
const thirtyDaysAgo = new Date(
8181
date.getFullYear(),
8282
date.getMonth(),
83-
date.getDate() - 10,
83+
date.getDate() - 30,
84+
0,
8485
0,
8586
0,
8687
0,
87-
0
8888
);
89+
await db
90+
.delete(schema.DisregardedObservations)
91+
.where(lt(schema.DisregardedObservations.timestamp, thirtyDaysAgo));
92+
console.log(`Deleted disregarded observations older than 30 days`);
8993
await db
9094
.delete(schema.Heartbeats)
91-
.where(lt(schema.Heartbeats.hourStartTimestamp, tenDaysAgo));
92-
console.log(`Deleted heartbeats older than 10 days`);
95+
.where(lt(schema.Heartbeats.hourStartTimestamp, thirtyDaysAgo));
96+
console.log(`Deleted heartbeats older than 30 days`);
9397
},
9498
} satisfies ExportedHandler<Env>;
9599

@@ -99,7 +103,7 @@ export class UploadToWindGuru extends WorkflowEntrypoint<
99103
> {
100104
async run(
101105
event: WorkflowEvent<schema.ObservationInsert>,
102-
step: WorkflowStep
106+
step: WorkflowStep,
103107
) {
104108
await step.do(
105109
"Upload to WindGuru",
@@ -117,7 +121,7 @@ export class UploadToWindGuru extends WorkflowEntrypoint<
117121
if (!WINDGURU_UID || !WINDGURU_PASSWORD)
118122
throw new NonRetryableError("Missing Windguru credentials");
119123
const payloadData = await schema.observationInsertSchema.safeParseAsync(
120-
event.payload
124+
event.payload,
121125
);
122126
if (!payloadData.success)
123127
throw new NonRetryableError("Issue with incoming data");
@@ -128,7 +132,9 @@ export class UploadToWindGuru extends WorkflowEntrypoint<
128132
{
129133
name: "MD5",
130134
},
131-
new TextEncoder().encode(`${salt}${WINDGURU_UID}${WINDGURU_PASSWORD}`)
135+
new TextEncoder().encode(
136+
`${salt}${WINDGURU_UID}${WINDGURU_PASSWORD}`,
137+
),
132138
);
133139
const params = new URLSearchParams({
134140
uid: WINDGURU_UID,
@@ -146,7 +152,7 @@ export class UploadToWindGuru extends WorkflowEntrypoint<
146152
`https://www.windguru.cz/upload/api.php?${params.toString()}`,
147153
{
148154
method: "GET",
149-
}
155+
},
150156
).then((response) => {
151157
if (!response.ok)
152158
throw new Error("Windguru failed, status: " + response.status);
@@ -155,7 +161,7 @@ export class UploadToWindGuru extends WorkflowEntrypoint<
155161
if (response !== "OK") {
156162
throw new Error(`Windguru upload failed: ${response}`);
157163
}
158-
}
164+
},
159165
);
160166
}
161167
}
@@ -166,7 +172,7 @@ export class UploadToMetOffice extends WorkflowEntrypoint<
166172
> {
167173
async run(
168174
event: WorkflowEvent<schema.ObservationInsert>,
169-
step: WorkflowStep
175+
step: WorkflowStep,
170176
) {
171177
await step.do(
172178
"Upload to Met Office",
@@ -184,7 +190,7 @@ export class UploadToMetOffice extends WorkflowEntrypoint<
184190
if (!METOFFICE_SITE_ID || !METOFFICE_AUTH_KEY)
185191
throw new NonRetryableError("Missing Met Office credentials");
186192
const payloadData = await schema.observationInsertSchema.safeParseAsync(
187-
event.payload
193+
event.payload,
188194
);
189195
if (!payloadData.success)
190196
throw new NonRetryableError("Issue with incoming data");
@@ -211,15 +217,15 @@ export class UploadToMetOffice extends WorkflowEntrypoint<
211217
`http://wow.metoffice.gov.uk/automaticreading?${params.toString()}`,
212218
{
213219
method: "GET",
214-
}
220+
},
215221
).then((response) => {
216222
if (response.status === 429)
217223
throw new NonRetryableError(
218-
"Met office asked for a backoff, skip this observation"
224+
"Met office asked for a backoff, skip this observation",
219225
);
220226
if (!response.ok)
221227
throw new Error(
222-
"Met Office upload failed, status: " + response.status
228+
"Met Office upload failed, status: " + response.status,
223229
);
224230
return response.json();
225231
});
@@ -229,9 +235,9 @@ export class UploadToMetOffice extends WorkflowEntrypoint<
229235
Object.keys(response).length !== 0
230236
)
231237
throw new Error(
232-
`Met Office upload failed: ${JSON.stringify(response)}`
238+
`Met Office upload failed: ${JSON.stringify(response)}`,
233239
);
234-
}
240+
},
235241
);
236242
}
237243
}
@@ -242,7 +248,7 @@ export class UploadToWindy extends WorkflowEntrypoint<
242248
> {
243249
async run(
244250
event: WorkflowEvent<schema.ObservationInsert>,
245-
step: WorkflowStep
251+
step: WorkflowStep,
246252
) {
247253
await step.do(
248254
"Upload to Windy",
@@ -260,7 +266,7 @@ export class UploadToWindy extends WorkflowEntrypoint<
260266
if (!WINDY_API_KEY || !WINDY_STATION_ID)
261267
throw new NonRetryableError("Missing Windy credentials");
262268
const payloadData = await schema.observationInsertSchema.safeParseAsync(
263-
event.payload
269+
event.payload,
264270
);
265271
if (!payloadData.success)
266272
throw new NonRetryableError("Issue with incoming data");
@@ -280,25 +286,25 @@ export class UploadToWindy extends WorkflowEntrypoint<
280286
`https://stations.windy.com/pws/update/${WINDY_API_KEY}?${params.toString()}`,
281287
{
282288
method: "GET",
283-
}
289+
},
284290
);
285291
const responseText = await response.text();
286292
if (
287293
responseText.length > 0 &&
288294
responseText.includes(
289-
"Measurement sent too soon, update interval is 5 minutes"
295+
"Measurement sent too soon, update interval is 5 minutes",
290296
)
291297
) {
292298
throw new NonRetryableError(
293-
"Windy asked for a backoff, skip this observation"
299+
"Windy asked for a backoff, skip this observation",
294300
);
295301
} else if (!response.ok)
296302
throw new Error("Windy upload failed, status: " + response.status);
297303
const responseJson = JSON.parse(responseText);
298304
if (!responseJson || typeof responseJson !== "object")
299305
throw new Error(`Windy upload failed: ${JSON.stringify(response)}`);
300306
return responseText;
301-
}
307+
},
302308
);
303309
}
304310
}
@@ -337,7 +343,7 @@ export class OvernightSaveToR2 extends WorkflowEntrypoint<
337343
0,
338344
0,
339345
0,
340-
0
346+
0,
341347
);
342348
const endOfPeriod = new Date(
343349
dayToProcess.getFullYear(),
@@ -346,7 +352,7 @@ export class OvernightSaveToR2 extends WorkflowEntrypoint<
346352
0,
347353
0,
348354
0,
349-
0
355+
0,
350356
);
351357

352358
const allObservations = await db
@@ -355,8 +361,8 @@ export class OvernightSaveToR2 extends WorkflowEntrypoint<
355361
.where(
356362
and(
357363
gte(schema.Observations.timestamp, startOfPeriod),
358-
lt(schema.Observations.timestamp, endOfPeriod)
359-
)
364+
lt(schema.Observations.timestamp, endOfPeriod),
365+
),
360366
)
361367
.orderBy(asc(schema.Observations.timestamp))
362368
.catch((error) => {
@@ -377,66 +383,43 @@ export class OvernightSaveToR2 extends WorkflowEntrypoint<
377383
Object.values(observation.data)
378384
.map((value) => `"${value}"`)
379385
.join(","),
380-
].join(",")
386+
].join(","),
381387
),
382388
].join("\n");
383389
console.log(`Uploading ${csv.length} bytes to R2`);
384390
const upload = await this.env.R2_BUCKET.put(
385391
`daily-observations/${startOfPeriod.getFullYear()}-${String(
386-
startOfPeriod.getMonth() + 1
392+
startOfPeriod.getMonth() + 1,
387393
).padStart(2, "0")}-${String(startOfPeriod.getDate()).padStart(
388394
2,
389-
"0"
395+
"0",
390396
)}.csv`,
391-
csv
397+
csv,
392398
).catch((error) => {
393399
throw new Error("Failed to upload to R2", { cause: error });
394400
});
395401
if (!upload || !upload.uploaded)
396402
throw new Error("Failed to upload to R2");
397403
console.log(
398-
`Uploaded to R2 ${upload.size} bytes, proceeding to update observations`
404+
`Uploaded to R2 ${upload.size} bytes, proceeding to update observations`,
399405
);
400-
const [updateObservations, deleteDisregardedObservations] =
401-
await db.batch([
402-
db
403-
.update(schema.Observations)
404-
.set({ exportedToR2: true })
405-
.where(
406-
and(
407-
gte(schema.Observations.timestamp, startOfPeriod),
408-
lt(schema.Observations.timestamp, endOfPeriod)
409-
)
410-
), // Record observations which were uploaded to R2 as being exported
411-
db
412-
.delete(schema.DisregardedObservations)
413-
.where(
414-
lt(
415-
schema.DisregardedObservations.timestamp,
416-
new Date(
417-
startOfPeriod.getFullYear(),
418-
startOfPeriod.getMonth(),
419-
startOfPeriod.getDate() - 30,
420-
0,
421-
0,
422-
0,
423-
0
424-
)
425-
)
426-
), // Delete all disregarded observations older than 30 days, as we don't need to keep that data indefinitely
427-
]);
406+
const updateObservations = await db
407+
.update(schema.Observations)
408+
.set({ exportedToR2: true })
409+
.where(
410+
and(
411+
gte(schema.Observations.timestamp, startOfPeriod),
412+
lt(schema.Observations.timestamp, endOfPeriod),
413+
),
414+
);
428415
if (updateObservations.error)
429416
throw new Error("Failed to update observations", {
430417
cause: updateObservations.error,
431418
});
432-
if (deleteDisregardedObservations.error)
433-
throw new Error("Failed to delete disregarded observations", {
434-
cause: deleteDisregardedObservations.error,
435-
});
436419
console.log(
437-
`Successfully uploaded to R2 and updated observations. Script complete`
420+
`Successfully uploaded to R2 and updated observations. Script complete`,
438421
);
439-
}
422+
},
440423
);
441424
}
442425
}

website/wrangler.jsonc

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
"database_id": "ccfaf6e2-70d5-4d1f-b44e-c2c182e346ea",
99
"migrations_table": "migrations",
1010
"migrations_dir": "database/migrations",
11-
"experimental_remote": false,
1211
},
1312
],
1413
"kv_namespaces": [
@@ -61,11 +60,6 @@
6160
"persist": true,
6261
"invocation_logs": true,
6362
},
64-
"traces": {
65-
"enabled": true,
66-
"head_sampling_rate": 1,
67-
"persist": true,
68-
},
6963
},
7064
"preview_urls": false,
7165
"triggers": {

0 commit comments

Comments
 (0)