Skip to content
Source
Sign inSign up

Summary.ts

64 lines2.3 KB

1import * as Effect from "effect/Effect";
2import * as Schema from "effect/Schema";
3​
4const Label = Schema.String.check(Schema.isMaxLength(256));
5const Count = Schema.Number.check(
6 Schema.isInt(),
7 Schema.isBetween({ minimum: 0, maximum: Number.MAX_SAFE_INTEGER }),
8);
9export const Summary = Schema.Struct({
10 id: Schema.String.check(Schema.isPattern(/^[a-f0-9]{64}$/)),
11 recordedAt: Count,
12 host: Label,
13 platform: Label,
14 arch: Label,
15 ci: Schema.Boolean,
16 runId: Label,
17 tasks: Schema.Array(
18 Schema.Struct({
19 package: Label,
20 task: Label,
21 source: Schema.Literals(["local", "remote", "unspecified", "executed", "failed"]),
22 savedMs: Count,
23 }),
24 ).check(Schema.isMaxLength(1000)),
25});
26​
27export const recordSummary = Effect.fn("TaskCache.summary")(function* (
28 summary: typeof Summary.Type,
29 developer: string,
30) {
31 const local = summary.tasks.filter((task) => task.source === "local");
32 const unspecified = summary.tasks.filter((task) => task.source === "unspecified");
33 const remote = summary.tasks.filter((task) => task.source === "remote");
34 yield* Effect.annotateCurrentSpan({
35 "cache.event_id": summary.id,
36 "cache.recorded_at": summary.recordedAt,
37 "developer.id": developer,
38 "host.name": summary.host,
39 "host.os": summary.platform,
40 "host.arch": summary.arch,
41 ci: summary.ci,
42 "ci.run_id": summary.runId,
43 "cache.local_hits": local.length,
44 "cache.unspecified_hits": unspecified.length,
45 "cache.unspecified_saved_ms": unspecified.reduce((sum, task) => sum + task.savedMs, 0),
46 "cache.remote_hits": remote.length,
47 "cache.executed": summary.tasks.filter((task) => task.source === "executed").length,
48 "cache.restore_failures": summary.tasks.filter((task) => task.source === "failed").length,
49 "cache.local_saved_ms": local.reduce((sum, task) => sum + task.savedMs, 0),
50 "cache.remote_saved_ms": remote.reduce((sum, task) => sum + task.savedMs, 0),
51 });
52 yield* Effect.forEach(summary.tasks, (task, index) =>
53 Effect.annotateCurrentSpan({
54 "cache.event_id": summary.id,
55 "cache.task_index": index,
56 "developer.id": developer,
57 "host.name": summary.host,
58 "task.package": task.package,
59 "task.name": task.task,
60 "cache.source": task.source,
61 "cache.saved_ms": task.savedMs,
62 }).pipe(Effect.withSpan("TaskCache.task")),
63 );
64});