@usine/orchestrator 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +151 -52
- package/dist/board/items.d.ts +9 -1
- package/dist/board/items.d.ts.map +1 -1
- package/dist/board/items.js +16 -4
- package/dist/board/items.js.map +1 -1
- package/dist/board/projection.d.ts +7 -1
- package/dist/board/projection.d.ts.map +1 -1
- package/dist/board/projection.js +53 -14
- package/dist/board/projection.js.map +1 -1
- package/dist/board/tasks.d.ts +14 -2
- package/dist/board/tasks.d.ts.map +1 -1
- package/dist/board/tasks.js +23 -8
- package/dist/board/tasks.js.map +1 -1
- package/dist/credentials.d.ts +5 -6
- package/dist/credentials.d.ts.map +1 -1
- package/dist/credentials.js +22 -15
- package/dist/credentials.js.map +1 -1
- package/dist/current-instance/changes.d.ts +87 -0
- package/dist/current-instance/changes.d.ts.map +1 -0
- package/dist/current-instance/changes.js +138 -0
- package/dist/current-instance/changes.js.map +1 -0
- package/dist/current-instance/current-instance.d.ts +89 -0
- package/dist/current-instance/current-instance.d.ts.map +1 -0
- package/dist/current-instance/current-instance.js +163 -0
- package/dist/current-instance/current-instance.js.map +1 -0
- package/dist/exe-dev.d.ts +6 -2
- package/dist/exe-dev.d.ts.map +1 -1
- package/dist/exe-dev.js +7 -8
- package/dist/exe-dev.js.map +1 -1
- package/dist/idle-triggers.d.ts +1 -1
- package/dist/idle-triggers.d.ts.map +1 -1
- package/dist/idle-triggers.js +1 -1
- package/dist/idle-triggers.js.map +1 -1
- package/dist/label-reconciler.d.ts +5 -2
- package/dist/label-reconciler.d.ts.map +1 -1
- package/dist/label-reconciler.js.map +1 -1
- package/dist/local.d.ts +4 -18
- package/dist/local.d.ts.map +1 -1
- package/dist/local.js +7 -45
- package/dist/local.js.map +1 -1
- package/dist/loop-matches.d.ts +28 -0
- package/dist/loop-matches.d.ts.map +1 -0
- package/dist/loop-matches.js +74 -0
- package/dist/loop-matches.js.map +1 -0
- package/dist/operator/attempt.d.ts +57 -10
- package/dist/operator/attempt.d.ts.map +1 -1
- package/dist/operator/attempt.js +49 -10
- package/dist/operator/attempt.js.map +1 -1
- package/dist/operator/board.d.ts +43 -16
- package/dist/operator/board.d.ts.map +1 -1
- package/dist/operator/board.js +43 -16
- package/dist/operator/board.js.map +1 -1
- package/dist/operator/configuration.d.ts +258 -0
- package/dist/operator/configuration.d.ts.map +1 -0
- package/dist/operator/configuration.js +410 -0
- package/dist/operator/configuration.js.map +1 -0
- package/dist/operator/desk.d.ts +181 -0
- package/dist/operator/desk.d.ts.map +1 -0
- package/dist/operator/desk.js +463 -0
- package/dist/operator/desk.js.map +1 -0
- package/dist/operator/github-changes.d.ts +88 -0
- package/dist/operator/github-changes.d.ts.map +1 -0
- package/dist/operator/github-changes.js +266 -0
- package/dist/operator/github-changes.js.map +1 -0
- package/dist/operator/http.d.ts +152 -57
- package/dist/operator/http.d.ts.map +1 -1
- package/dist/operator/http.js +140 -21
- package/dist/operator/http.js.map +1 -1
- package/dist/operator/need.d.ts +44 -11
- package/dist/operator/need.d.ts.map +1 -1
- package/dist/operator/need.js +46 -9
- package/dist/operator/need.js.map +1 -1
- package/dist/operator/operator.d.ts +109 -29
- package/dist/operator/operator.d.ts.map +1 -1
- package/dist/operator/operator.js +254 -52
- package/dist/operator/operator.js.map +1 -1
- package/dist/operator/overview.d.ts +7 -7
- package/dist/operator/overview.d.ts.map +1 -1
- package/dist/operator/overview.js +5 -5
- package/dist/operator/overview.js.map +1 -1
- package/dist/operator/projection.d.ts +54 -5
- package/dist/operator/projection.d.ts.map +1 -1
- package/dist/operator/projection.js +100 -9
- package/dist/operator/projection.js.map +1 -1
- package/dist/operator/run.d.ts +71 -6
- package/dist/operator/run.d.ts.map +1 -1
- package/dist/operator/run.js +69 -6
- package/dist/operator/run.js.map +1 -1
- package/dist/operator/task.d.ts +93 -0
- package/dist/operator/task.d.ts.map +1 -0
- package/dist/operator/task.js +204 -0
- package/dist/operator/task.js.map +1 -0
- package/dist/operator/transcript.d.ts +12 -12
- package/dist/operator/transcript.d.ts.map +1 -1
- package/dist/operator/transcript.js +11 -9
- package/dist/operator/transcript.js.map +1 -1
- package/dist/operator/usage.d.ts +111 -0
- package/dist/operator/usage.d.ts.map +1 -0
- package/dist/operator/usage.js +219 -0
- package/dist/operator/usage.js.map +1 -0
- package/dist/orchestrator.d.ts +8 -5
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +4 -2
- package/dist/orchestrator.js.map +1 -1
- package/dist/polling/cycle.d.ts +28 -10
- package/dist/polling/cycle.d.ts.map +1 -1
- package/dist/polling/cycle.js +20 -6
- package/dist/polling/cycle.js.map +1 -1
- package/dist/polling/evaluation-failures.d.ts +42 -0
- package/dist/polling/evaluation-failures.d.ts.map +1 -0
- package/dist/polling/evaluation-failures.js +103 -0
- package/dist/polling/evaluation-failures.js.map +1 -0
- package/dist/polling/hints.d.ts +2 -2
- package/dist/polling/hints.d.ts.map +1 -1
- package/dist/polling/hints.js +2 -2
- package/dist/polling/hints.js.map +1 -1
- package/dist/polling/loop-evaluation.d.ts +21 -11
- package/dist/polling/loop-evaluation.d.ts.map +1 -1
- package/dist/polling/loop-evaluation.js +70 -27
- package/dist/polling/loop-evaluation.js.map +1 -1
- package/dist/polling/open-issues.d.ts +23 -0
- package/dist/polling/open-issues.d.ts.map +1 -0
- package/dist/polling/open-issues.js +77 -0
- package/dist/polling/open-issues.js.map +1 -0
- package/dist/polling/polling.d.ts +20 -11
- package/dist/polling/polling.d.ts.map +1 -1
- package/dist/polling/polling.js +201 -51
- package/dist/polling/polling.js.map +1 -1
- package/dist/polling/repository-sync.d.ts +20 -14
- package/dist/polling/repository-sync.d.ts.map +1 -1
- package/dist/polling/repository-sync.js +34 -27
- package/dist/polling/repository-sync.js.map +1 -1
- package/dist/polling-triggers.d.ts +1 -1
- package/dist/polling-triggers.d.ts.map +1 -1
- package/dist/polling-triggers.js +1 -1
- package/dist/polling-triggers.js.map +1 -1
- package/dist/reloads.d.ts +14 -0
- package/dist/reloads.d.ts.map +1 -0
- package/dist/reloads.js +7 -0
- package/dist/reloads.js.map +1 -0
- package/dist/runtime.d.ts +24 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +58 -0
- package/dist/runtime.js.map +1 -0
- package/dist/schedule-triggers.d.ts +14 -10
- package/dist/schedule-triggers.d.ts.map +1 -1
- package/dist/schedule-triggers.js +36 -31
- package/dist/schedule-triggers.js.map +1 -1
- package/dist/scheduler.d.ts +35 -4
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/scheduler.js +327 -41
- package/dist/scheduler.js.map +1 -1
- package/dist/ssh.d.ts +39 -0
- package/dist/ssh.d.ts.map +1 -0
- package/dist/ssh.js +75 -0
- package/dist/ssh.js.map +1 -0
- package/dist/trigger-condition.d.ts +12 -0
- package/dist/trigger-condition.d.ts.map +1 -0
- package/dist/trigger-condition.js +88 -0
- package/dist/trigger-condition.js.map +1 -0
- package/dist/trigger-submission.d.ts +16 -13
- package/dist/trigger-submission.d.ts.map +1 -1
- package/dist/trigger-submission.js +19 -14
- package/dist/trigger-submission.js.map +1 -1
- package/dist/worker-engine.d.ts +10 -0
- package/dist/worker-engine.d.ts.map +1 -0
- package/dist/worker-engine.js +25 -0
- package/dist/worker-engine.js.map +1 -0
- package/dist/worker-status.d.ts +70 -0
- package/dist/worker-status.d.ts.map +1 -0
- package/dist/worker-status.js +55 -0
- package/dist/worker-status.js.map +1 -0
- package/package.json +31 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop-evaluation.js","sourceRoot":"","sources":["../../src/polling/loop-evaluation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAChG,OAAO,EAAE,SAAS,EAAyB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"loop-evaluation.js","sourceRoot":"","sources":["../../src/polling/loop-evaluation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ManagedRepo } from "@usine/config/factory";
|
|
2
|
+
import { ItemProjectionReader } from "@usine/engine/item-projection";
|
|
3
|
+
import { GitHubPolling } from "@usine/github/polling";
|
|
4
|
+
import { DateTime, Duration, Effect, Option } from "effect";
|
|
5
|
+
import type { ResolvedLoop } from "../trigger-submission.ts";
|
|
6
|
+
import { RepositoryPollFailure } from "./cycle.ts";
|
|
7
|
+
/** The minimum time between open issue checks of a repository. */
|
|
8
|
+
export declare const OPEN_ISSUE_CHECK_INTERVAL: Duration.Duration;
|
|
9
|
+
/** The result of one open issue check in a poll cycle. */
|
|
10
|
+
interface OpenIssueCheck {
|
|
11
|
+
readonly revokedRuns: number;
|
|
12
|
+
readonly failures: ReadonlyArray<RepositoryPollFailure>;
|
|
13
|
+
readonly nextPollAt: Option.Option<DateTime.Utc>;
|
|
14
|
+
}
|
|
15
|
+
export declare const NO_OPEN_ISSUE_CHECK: OpenIssueCheck;
|
|
16
|
+
/**
|
|
17
|
+
* Marks each issue stored as open in `repository` that GitHub no longer has as gone, and revokes
|
|
18
|
+
* its unstarted Runs. Reports GitHub request failures without failing the cycle; fails on
|
|
19
|
+
* persistence errors.
|
|
20
|
+
*/
|
|
21
|
+
export declare const checkOpenIssues: (repository: ManagedRepo, loops: readonly ResolvedLoop[]) => Effect.Effect<OpenIssueCheck, import("@usine/engine/engine").AttemptCancellationError | import("@usine/engine/engine").EnginePersistenceError | import("@usine/engine/engine").RunInterventionRejectedError | import("@usine/engine/engine").RunNotFoundError | import("@usine/engine/engine").RunOperationRejectedError | import("@usine/engine/engine").RunRetryBlockedError, GitHubPolling | ItemProjectionReader | import("@usine/engine/item-projection").ItemProjectionWriter | import("@usine/engine/engine").RunEngine>;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=open-issues.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-issues.d.ts","sourceRoot":"","sources":["../../src/polling/open-issues.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAA8B,MAAM,YAAY,CAAC;AAI/E,kEAAkE;AAClE,eAAO,MAAM,yBAAyB,mBAAuB,CAAC;AAE9D,0DAA0D;AAC1D,UAAU,cAAc;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,qBAAqB,CAAC,CAAC;IACxD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;CAClD;AAED,eAAO,MAAM,mBAAmB,EAAE,cAIjC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,8jBA4D1B,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { ItemProjectionReader } from "@usine/engine/item-projection";
|
|
2
|
+
import { GitHubPolling } from "@usine/github/polling";
|
|
3
|
+
import { DateTime, Duration, Effect, Option, Result } from "effect";
|
|
4
|
+
import { RepositoryPollFailure, repositoryFailureLogFields } from "./cycle.js";
|
|
5
|
+
import { revokeMissingItem } from "./loop-evaluation.js";
|
|
6
|
+
import { markItemGone } from "./repository-sync.js";
|
|
7
|
+
/** The minimum time between open issue checks of a repository. */
|
|
8
|
+
export const OPEN_ISSUE_CHECK_INTERVAL = Duration.minutes(10);
|
|
9
|
+
export const NO_OPEN_ISSUE_CHECK = {
|
|
10
|
+
revokedRuns: 0,
|
|
11
|
+
failures: [],
|
|
12
|
+
nextPollAt: Option.none(),
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Marks each issue stored as open in `repository` that GitHub no longer has as gone, and revokes
|
|
16
|
+
* its unstarted Runs. Reports GitHub request failures without failing the cycle; fails on
|
|
17
|
+
* persistence errors.
|
|
18
|
+
*/
|
|
19
|
+
export const checkOpenIssues = Effect.fn("PollingTriggers.checkOpenIssues")(function* (repository, loops) {
|
|
20
|
+
yield* Effect.annotateCurrentSpan({ repository: repository.name });
|
|
21
|
+
const items = yield* ItemProjectionReader;
|
|
22
|
+
const github = yield* GitHubPolling;
|
|
23
|
+
const open = yield* items.openIssues(repository.name);
|
|
24
|
+
if (open.length === 0) {
|
|
25
|
+
yield* Effect.logDebug("No open issues to check against GitHub", {
|
|
26
|
+
repository: repository.name,
|
|
27
|
+
});
|
|
28
|
+
return NO_OPEN_ISSUE_CHECK;
|
|
29
|
+
}
|
|
30
|
+
const result = yield* Effect.result(github.missingIssues(repository.name, open));
|
|
31
|
+
if (Result.isFailure(result)) {
|
|
32
|
+
const error = result.failure;
|
|
33
|
+
if (error._tag === "GitHubRateLimitError") {
|
|
34
|
+
yield* Effect.logWarning("Open-issue check rate-limited; checking again in 10 minutes", {
|
|
35
|
+
repository: repository.name,
|
|
36
|
+
openIssues: open.length,
|
|
37
|
+
operation: error.operation,
|
|
38
|
+
retryAt: DateTime.formatIso(error.retryAt),
|
|
39
|
+
});
|
|
40
|
+
return { ...NO_OPEN_ISSUE_CHECK, nextPollAt: Option.some(error.retryAt) };
|
|
41
|
+
}
|
|
42
|
+
yield* Effect.logError("Open-issue check failed; checking again in 10 minutes", {
|
|
43
|
+
repository: repository.name,
|
|
44
|
+
openIssues: open.length,
|
|
45
|
+
...repositoryFailureLogFields(error),
|
|
46
|
+
});
|
|
47
|
+
return {
|
|
48
|
+
...NO_OPEN_ISSUE_CHECK,
|
|
49
|
+
failures: [
|
|
50
|
+
new RepositoryPollFailure({
|
|
51
|
+
repository: repository.name,
|
|
52
|
+
errorTag: error._tag,
|
|
53
|
+
message: error.message,
|
|
54
|
+
}),
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
let revokedRuns = 0;
|
|
59
|
+
for (const number of result.success) {
|
|
60
|
+
const revoked = yield* revokeMissingItem(repository, loops, "issue", number);
|
|
61
|
+
const projectionMarkedGone = yield* markItemGone(repository.name, number);
|
|
62
|
+
revokedRuns += revoked;
|
|
63
|
+
yield* Effect.logInfo("GitHub no longer has an open issue; it leaves the open lanes", {
|
|
64
|
+
repository: repository.name,
|
|
65
|
+
item: number,
|
|
66
|
+
revokedRuns: revoked,
|
|
67
|
+
projectionMarkedGone,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
yield* Effect.logDebug("Checked open issues against GitHub", {
|
|
71
|
+
repository: repository.name,
|
|
72
|
+
openIssues: open.length,
|
|
73
|
+
missingIssues: result.success.length,
|
|
74
|
+
});
|
|
75
|
+
return { ...NO_OPEN_ISSUE_CHECK, revokedRuns };
|
|
76
|
+
});
|
|
77
|
+
//# sourceMappingURL=open-issues.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-issues.js","sourceRoot":"","sources":["../../src/polling/open-issues.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,33 +4,42 @@ import { type RepositoryName } from "@usine/core/repository";
|
|
|
4
4
|
import { CursorStore } from "@usine/engine/cursor";
|
|
5
5
|
import { CycleBudgets } from "@usine/engine/cycle-budget";
|
|
6
6
|
import { RunEngine, type EnginePersistenceError } from "@usine/engine/engine";
|
|
7
|
-
import { ItemProjectionWriter } from "@usine/engine/item-projection";
|
|
7
|
+
import { ItemProjectionReader, ItemProjectionWriter } from "@usine/engine/item-projection";
|
|
8
8
|
import { LoopControl } from "@usine/engine/loop-control";
|
|
9
9
|
import { RepositoryLabelProjectionReader, RepositoryLabelProjectionWriter } from "@usine/engine/repository-label-projection";
|
|
10
10
|
import { ExpressionEngine } from "@usine/expression/expression-engine";
|
|
11
11
|
import { type ChangedItem, GitHubPolling } from "@usine/github/polling";
|
|
12
12
|
import { Context, DateTime, Effect, Layer, Option } from "effect";
|
|
13
13
|
import { LabelReconciler } from "../label-reconciler.ts";
|
|
14
|
+
import { type WatchedInstance } from "../reloads.ts";
|
|
14
15
|
import { PollCycle } from "./cycle.ts";
|
|
15
16
|
declare const PollingTriggers_base: Context.ServiceClass<PollingTriggers, "@usine/orchestrator/PollingTriggers", {
|
|
16
17
|
/**
|
|
17
|
-
* Polls every managed repository
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* Items finish. Repository failures are reported while siblings continue;
|
|
21
|
-
* failure to read Loop runtime state fails the whole cycle.
|
|
18
|
+
* Polls every managed repository and evaluates its Loops against changed Items. Reports
|
|
19
|
+
* repository failures without stopping the others; fails only if Loop runtime state can't be
|
|
20
|
+
* read.
|
|
22
21
|
*/
|
|
23
22
|
readonly poll: (instance: LoadedInstance) => Effect.Effect<PollCycle, EnginePersistenceError>;
|
|
24
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Requests an Item fetch after a self-write, keeping the writer's request backoff. Duplicate
|
|
25
|
+
* hints coalesce, and polling repairs lost ones.
|
|
26
|
+
*/
|
|
25
27
|
readonly hint: (repository: RepositoryName, item: ChangedItem, backoffUntil?: Option.Option<DateTime.Utc>) => Effect.Effect<void>;
|
|
26
|
-
/**
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Runs cycles at the configured interval and processes self-write hints, respecting GitHub
|
|
30
|
+
* request backoff. An accepted reload starts the next cycle immediately, unless GitHub asked to
|
|
31
|
+
* wait longer.
|
|
32
|
+
*/
|
|
33
|
+
readonly run: (instances: WatchedInstance) => Effect.Effect<never>;
|
|
34
|
+
/**
|
|
35
|
+
* The last completed cycle with its isolated failures, or `None` before the first cycle
|
|
36
|
+
* completes.
|
|
37
|
+
*/
|
|
29
38
|
readonly latest: Effect.Effect<Option.Option<PollCycle>>;
|
|
30
39
|
}>;
|
|
31
40
|
/** Keeps managed repositories' Boards current and evaluates their active Loops against changed Items. */
|
|
32
41
|
export declare class PollingTriggers extends PollingTriggers_base {
|
|
33
|
-
static readonly layer: Layer.Layer<PollingTriggers, never, ConfigParser | CursorStore | CycleBudgets | ExpressionEngine | GitHubPolling | ItemProjectionWriter | LabelReconciler | LoopControl | RepositoryLabelProjectionReader | RepositoryLabelProjectionWriter | RunEngine>;
|
|
42
|
+
static readonly layer: Layer.Layer<PollingTriggers, never, ConfigParser | CursorStore | CycleBudgets | ExpressionEngine | GitHubPolling | ItemProjectionReader | ItemProjectionWriter | LabelReconciler | LoopControl | RepositoryLabelProjectionReader | RepositoryLabelProjectionWriter | RunEngine>;
|
|
34
43
|
}
|
|
35
44
|
export {};
|
|
36
45
|
//# sourceMappingURL=polling.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"polling.d.ts","sourceRoot":"","sources":["../../src/polling/polling.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAA2B,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAa,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EACL,SAAS,EACT,KAAK,sBAAsB,EAE5B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"polling.d.ts","sourceRoot":"","sources":["../../src/polling/polling.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAA2B,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAa,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EACL,SAAS,EACT,KAAK,sBAAsB,EAE5B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAC3F,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EACL,+BAA+B,EAC/B,+BAA+B,EAChC,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAEL,KAAK,WAAW,EAGhB,aAAa,EACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,OAAO,EACP,QAAQ,EAER,MAAM,EACN,KAAK,EACL,MAAM,EAKP,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,eAAe,EAA8B,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAEnE,OAAO,EAGL,SAAS,EAKV,MAAM,YAAY,CAAC;;IA8FhB;;;;OAIG;mBACY,CAAC,QAAQ,EAAE,cAAc,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,sBAAsB,CAAC;IAC7F;;;OAGG;mBACY,CACb,UAAU,EAAE,cAAc,EAC1B,IAAI,EAAE,WAAW,EACjB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,KACvC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;IACxB;;;;OAIG;kBACW,CAAC,SAAS,EAAE,eAAe,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;IAClE;;;OAGG;qBACc,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;;AA7B5D,yGAAyG;AACzG,qBAAa,eAAgB,SAAQ,oBA8BK;IACxC,MAAM,CAAC,QAAQ,CAAC,KAAK,kRAmjBkB;CACxC"}
|
package/dist/polling/polling.js
CHANGED
|
@@ -4,27 +4,35 @@ import { canonicalRepositoryName } from "@usine/core/repository";
|
|
|
4
4
|
import { CursorKey, CursorStore } from "@usine/engine/cursor";
|
|
5
5
|
import { CycleBudgets } from "@usine/engine/cycle-budget";
|
|
6
6
|
import { RunEngine, } from "@usine/engine/engine";
|
|
7
|
-
import { ItemProjectionWriter } from "@usine/engine/item-projection";
|
|
7
|
+
import { ItemProjectionReader, ItemProjectionWriter } from "@usine/engine/item-projection";
|
|
8
8
|
import { LoopControl } from "@usine/engine/loop-control";
|
|
9
9
|
import { RepositoryLabelProjectionReader, RepositoryLabelProjectionWriter, } from "@usine/engine/repository-label-projection";
|
|
10
10
|
import { ExpressionEngine } from "@usine/expression/expression-engine";
|
|
11
|
-
import { EntityTag, PollCursor, GitHubPolling } from "@usine/github/polling";
|
|
11
|
+
import { ChangedPullRequest, EntityTag, PollCursor, GitHubPolling, } from "@usine/github/polling";
|
|
12
12
|
import { Clock, Context, DateTime, Duration, Effect, Layer, Option, Ref, Result, Schema, Semaphore, } from "effect";
|
|
13
13
|
import { LabelReconciler } from "../label-reconciler.js";
|
|
14
|
+
import { reloadedFrom } from "../reloads.js";
|
|
14
15
|
import { resolveTriggerLoops } from "../trigger-submission.js";
|
|
15
|
-
import { latestPollAt, PollCycle, RepositoryPollFailure, repositoryFailureLogFields, } from "./cycle.js";
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
16
|
+
import { latestPollAt, PollCycle, RepositoryPoll, RepositoryPollFailure, repositoryFailureLogFields, } from "./cycle.js";
|
|
17
|
+
import { changedItem, FailingItem, failingItem, failingItemPollFailures, logItemEvaluation, } from "./evaluation-failures.js";
|
|
18
|
+
import { evaluateItem, revokeMissingItem } from "./loop-evaluation.js";
|
|
19
|
+
import { markItemGone, observeItem, synchronizeLabels } from "./repository-sync.js";
|
|
18
20
|
import { ItemHints } from "./hints.js";
|
|
19
|
-
|
|
21
|
+
import { checkOpenIssues, NO_OPEN_ISSUE_CHECK, OPEN_ISSUE_CHECK_INTERVAL } from "./open-issues.js";
|
|
22
|
+
/** The number of repositories polled in parallel, kept low for GitHub's per-token limits. */
|
|
20
23
|
const REPOSITORY_CONCURRENCY = 4;
|
|
21
24
|
const ITEM_CONCURRENCY = 4;
|
|
22
25
|
const WatchKey = Schema.NonEmptyString.pipe(Schema.brand("GitHubPollWatchKey"));
|
|
23
26
|
class StoredPollCursor extends Schema.Class("@usine/orchestrator/StoredPollCursor")({
|
|
24
|
-
boardVersion: Schema.Literal(
|
|
27
|
+
boardVersion: Schema.Literal(5),
|
|
28
|
+
openPullRequests: Schema.Array(Schema.Struct({
|
|
29
|
+
number: ChangedPullRequest.fields.number,
|
|
30
|
+
updatedAt: Schema.DateTimeUtcFromString,
|
|
31
|
+
})),
|
|
25
32
|
cursor: PollCursor,
|
|
26
33
|
labelEntityTag: Schema.OptionFromNullOr(EntityTag),
|
|
27
34
|
watches: Schema.Array(WatchKey).check(Schema.isUnique()),
|
|
35
|
+
failingItems: Schema.Array(FailingItem).pipe(Schema.withDecodingDefaultKey(Effect.succeed([]))),
|
|
28
36
|
}) {
|
|
29
37
|
}
|
|
30
38
|
const cursorKey = (repository) => CursorKey.make(`github-poll:${canonicalRepositoryName(repository.name)}`);
|
|
@@ -47,13 +55,25 @@ export class PollingTriggers extends Context.Service()("@usine/orchestrator/Poll
|
|
|
47
55
|
const github = yield* GitHubPolling;
|
|
48
56
|
const loops = yield* LoopControl;
|
|
49
57
|
const latest = yield* Ref.make(Option.none());
|
|
58
|
+
// Kept across cycles, so a repository whose poll fails keeps its last completion time.
|
|
59
|
+
const completedPolls = yield* Ref.make(new Map());
|
|
50
60
|
const hints = yield* ItemHints;
|
|
51
61
|
const ownership = yield* Semaphore.make(1);
|
|
62
|
+
// A failing Item is fetched again only on its repository's first completed cycle in a process
|
|
63
|
+
// or after a reload.
|
|
64
|
+
const retriedFailingItems = yield* Ref.make({
|
|
65
|
+
instance: Option.none(),
|
|
66
|
+
repositories: new Set(),
|
|
67
|
+
});
|
|
68
|
+
// When each repository's open issues were last checked against GitHub.
|
|
69
|
+
const openIssueChecks = yield* Ref.make(new Map());
|
|
52
70
|
const emptyCursor = (watches) => new StoredPollCursor({
|
|
53
|
-
boardVersion:
|
|
71
|
+
boardVersion: 5,
|
|
72
|
+
openPullRequests: [],
|
|
54
73
|
cursor: PollCursor.empty,
|
|
55
74
|
labelEntityTag: Option.none(),
|
|
56
75
|
watches,
|
|
76
|
+
failingItems: [],
|
|
57
77
|
});
|
|
58
78
|
const readCursor = Effect.fn("PollingTriggers.readCursor")(function* (watched) {
|
|
59
79
|
yield* Effect.annotateCurrentSpan({ repository: watched.repository.name });
|
|
@@ -74,6 +94,23 @@ export class PollingTriggers extends Context.Service()("@usine/orchestrator/Poll
|
|
|
74
94
|
yield* Effect.annotateCurrentSpan({ repository: watched.repository.name });
|
|
75
95
|
yield* cursors.write(cursorKey(watched.repository), StoredPollCursor, cursor);
|
|
76
96
|
});
|
|
97
|
+
/** Checks the repository's open issues unless the last check started less than 10 minutes ago. */
|
|
98
|
+
const checkOpenIssuesWhenDue = Effect.fn("PollingTriggers.checkOpenIssuesWhenDue")(function* (watched) {
|
|
99
|
+
yield* Effect.annotateCurrentSpan({ repository: watched.repository.name });
|
|
100
|
+
const key = cursorKey(watched.repository);
|
|
101
|
+
const now = yield* Clock.currentTimeMillis;
|
|
102
|
+
const lastCheck = (yield* Ref.get(openIssueChecks)).get(key);
|
|
103
|
+
if (lastCheck !== undefined &&
|
|
104
|
+
now - lastCheck < Duration.toMillis(OPEN_ISSUE_CHECK_INTERVAL)) {
|
|
105
|
+
yield* Effect.logDebug("Open issues were checked less than 10 minutes ago; skipped", {
|
|
106
|
+
repository: watched.repository.name,
|
|
107
|
+
lastCheckedAt: DateTime.formatIso(DateTime.makeUnsafe(lastCheck)),
|
|
108
|
+
});
|
|
109
|
+
return NO_OPEN_ISSUE_CHECK;
|
|
110
|
+
}
|
|
111
|
+
yield* Ref.update(openIssueChecks, (checks) => new Map(checks).set(key, now));
|
|
112
|
+
return yield* checkOpenIssues(watched.repository, watched.loops);
|
|
113
|
+
});
|
|
77
114
|
const pollRepository = Effect.fn("PollingTriggers.pollRepository")(function* (watched) {
|
|
78
115
|
yield* Effect.annotateCurrentSpan({ repository: watched.repository.name });
|
|
79
116
|
const resets = (yield* budgets.pendingResets()).filter(({ repository }) => canonicalRepositoryName(repository) ===
|
|
@@ -91,61 +128,137 @@ export class PollingTriggers extends Context.Service()("@usine/orchestrator/Poll
|
|
|
91
128
|
// begin, including on the first cycle after `usine up`.
|
|
92
129
|
const detected = yield* github.changes(watched.repository.name, stored.cursor);
|
|
93
130
|
yield* hints.defer(detected.backoffUntil);
|
|
131
|
+
const retrying = (yield* Ref.get(retriedFailingItems)).repositories.has(cursorKey(watched.repository))
|
|
132
|
+
? []
|
|
133
|
+
: stored.failingItems;
|
|
134
|
+
// Mergeability can change without an updated_at or ETag change, so open PRs stay in the
|
|
135
|
+
// cursor and are refreshed on every poll, even on 304. Cursor version 5 rebuilds this set
|
|
136
|
+
// on upgrade.
|
|
137
|
+
const items = new Map([
|
|
138
|
+
...retrying.map((failing) => [failing.number, changedItem(failing)]),
|
|
139
|
+
...stored.openPullRequests.map((item) => [item.number, new ChangedPullRequest(item)]),
|
|
140
|
+
]);
|
|
141
|
+
if (detected._tag === "RepositoryChanges") {
|
|
142
|
+
for (const item of detected.items)
|
|
143
|
+
items.set(item.number, item);
|
|
144
|
+
yield* Effect.logInfo("Repository changed", {
|
|
145
|
+
repository: watched.repository.name,
|
|
146
|
+
changedItems: detected.items.length,
|
|
147
|
+
backlog: detected.backlog,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
const detectedNumbers = new Set((detected._tag === "RepositoryChanges" ? detected.items : []).map(({ number }) => number));
|
|
151
|
+
// Items fetched only because the cursor kept them: refreshed open pull requests and Items
|
|
152
|
+
// whose Loops failed before this process or instance.
|
|
153
|
+
const cursorOnly = new Set([...stored.openPullRequests, ...retrying]
|
|
154
|
+
.map(({ number }) => number)
|
|
155
|
+
.filter((number) => !detectedNumbers.has(number)));
|
|
156
|
+
if (retrying.length > 0) {
|
|
157
|
+
yield* Effect.logInfo("Evaluating Items whose Loops failed before this process started or the instance was reloaded", {
|
|
158
|
+
repository: watched.repository.name,
|
|
159
|
+
items: retrying.map(({ number }) => number).join(", "),
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
const nextPollAt = latestPollAt([detected.nextPollAt, preflight.nextPollAt]);
|
|
163
|
+
yield* Effect.logDebug("Refreshing detected Items and open pull requests", {
|
|
164
|
+
repository: watched.repository.name,
|
|
165
|
+
detection: detected._tag,
|
|
166
|
+
openPullRequests: stored.openPullRequests.length,
|
|
167
|
+
items: items.size,
|
|
168
|
+
});
|
|
169
|
+
const recorded = new Map(stored.failingItems.map((failing) => [failing.number, failing]));
|
|
170
|
+
const evaluations = yield* Effect.forEach(items.values(), (item) => Effect.gen(function* () {
|
|
171
|
+
const observation = yield* observeItem(watched.repository.name, item);
|
|
172
|
+
const cycle = yield* evaluateItem(watched.repository, watched.loops, observation);
|
|
173
|
+
const failing = failingItem(item, observation.projection.contentHash, cycle.failures);
|
|
174
|
+
yield* logItemEvaluation(watched.repository.name, item.number, Option.fromNullishOr(recorded.get(item.number)), failing);
|
|
175
|
+
return { _tag: "Evaluated", item, observation, cycle, failing };
|
|
176
|
+
}).pipe(
|
|
177
|
+
// An Item kept only by the cursor may have been deleted or transferred, and must
|
|
178
|
+
// not stall the repository. Other failures still interrupt the cycle, which retries
|
|
179
|
+
// next time.
|
|
180
|
+
Effect.catchTag("GitHubItemNotFoundError", (error) => Effect.gen(function* () {
|
|
181
|
+
if (!cursorOnly.has(item.number))
|
|
182
|
+
return yield* error;
|
|
183
|
+
const revokedRuns = yield* revokeMissingItem(watched.repository, watched.loops, item._tag === "ChangedIssue" ? "issue" : "pr", item.number);
|
|
184
|
+
const projectionMarkedGone = yield* markItemGone(watched.repository.name, item.number);
|
|
185
|
+
yield* Effect.logWarning("GitHub no longer has an Item the poll cursor kept; it is dropped from the cursor", {
|
|
186
|
+
repository: watched.repository.name,
|
|
187
|
+
item: item.number,
|
|
188
|
+
openPullRequest: stored.openPullRequests.some(({ number }) => number === item.number),
|
|
189
|
+
revokedRuns,
|
|
190
|
+
projectionMarkedGone,
|
|
191
|
+
errorTag: error._tag,
|
|
192
|
+
message: error.message,
|
|
193
|
+
});
|
|
194
|
+
return { _tag: "Missing", revokedRuns };
|
|
195
|
+
}))), { concurrency: ITEM_CONCURRENCY });
|
|
196
|
+
const observed = evaluations.flatMap((evaluation) => evaluation._tag === "Evaluated" ? [evaluation] : []);
|
|
197
|
+
const missingRevokedRuns = evaluations.reduce((sum, evaluation) => sum + (evaluation._tag === "Missing" ? evaluation.revokedRuns : 0), 0);
|
|
198
|
+
const itemCycles = observed.map(({ cycle }) => cycle);
|
|
199
|
+
const openIssueCheck = yield* checkOpenIssuesWhenDue(watched);
|
|
200
|
+
yield* hints.defer(openIssueCheck.nextPollAt);
|
|
201
|
+
// An Item the cycle did not fetch keeps its recorded failures.
|
|
202
|
+
const failingItems = [
|
|
203
|
+
...stored.failingItems.filter(({ number }) => !items.has(number)),
|
|
204
|
+
...observed.flatMap(({ failing }) => Option.toArray(failing)),
|
|
205
|
+
].sort((left, right) => left.number - right.number);
|
|
94
206
|
const nextCursor = new StoredPollCursor({
|
|
95
|
-
boardVersion:
|
|
207
|
+
boardVersion: 5,
|
|
96
208
|
cursor: detected.cursor,
|
|
97
209
|
labelEntityTag: preflight.labelEntityTag,
|
|
98
210
|
watches: watched.watches,
|
|
211
|
+
openPullRequests: observed.flatMap(({ item, observation }) => item._tag === "ChangedPullRequest" && observation.projection.payload.state === "OPEN"
|
|
212
|
+
? [{ number: item.number, updatedAt: item.updatedAt }]
|
|
213
|
+
: []),
|
|
214
|
+
failingItems,
|
|
99
215
|
});
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
});
|
|
108
|
-
return {
|
|
109
|
-
changedItems: 0,
|
|
110
|
-
submissions: [],
|
|
111
|
-
revokedRuns: 0,
|
|
112
|
-
failures: preflight.failures,
|
|
113
|
-
preflightFindings: preflight.preflightFindings,
|
|
114
|
-
nextPollAt,
|
|
115
|
-
};
|
|
216
|
+
// Advancing the cursor is the commit point: every changed Item was fetched, evaluated,
|
|
217
|
+
// and submitted or revoked. After a failure, the old cursor stays so the next cycle polls
|
|
218
|
+
// again.
|
|
219
|
+
if (detected._tag === "RepositoryChanges" ||
|
|
220
|
+
items.size > 0 ||
|
|
221
|
+
preflight.entityTagChanged) {
|
|
222
|
+
yield* writeCursor(watched, nextCursor);
|
|
116
223
|
}
|
|
117
|
-
yield*
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
});
|
|
122
|
-
const itemCycles = yield* Effect.forEach(detected.items, (item) => observeItem(watched.repository.name, item).pipe(Effect.flatMap((projection) => evaluateItem(watched.repository, watched.loops, projection))), { concurrency: ITEM_CONCURRENCY });
|
|
123
|
-
// Advancing the cursor is the commit point: every changed item was
|
|
124
|
-
// fetched, evaluated, and submitted or revoked. After a failure the
|
|
125
|
-
// old cursor stays so the next cycle re-polls.
|
|
126
|
-
yield* writeCursor(watched, nextCursor);
|
|
224
|
+
yield* Ref.update(retriedFailingItems, (retried) => ({
|
|
225
|
+
...retried,
|
|
226
|
+
repositories: new Set([...retried.repositories, cursorKey(watched.repository)]),
|
|
227
|
+
}));
|
|
127
228
|
yield* Effect.forEach(resets, budgets.acknowledgeReset, { discard: true });
|
|
128
229
|
return {
|
|
129
|
-
|
|
230
|
+
// Refreshed open PRs are observed, not reported as changed by
|
|
231
|
+
// GitHub; counting them would make every idle poll look busy.
|
|
232
|
+
changedItems: detected._tag === "RepositoryChanges" ? detected.items.length : 0,
|
|
130
233
|
submissions: itemCycles.flatMap(({ submissions }) => submissions),
|
|
131
|
-
revokedRuns: itemCycles.reduce((sum, cycle) => sum + cycle.revokedRuns,
|
|
132
|
-
failures: [
|
|
234
|
+
revokedRuns: itemCycles.reduce((sum, cycle) => sum + cycle.revokedRuns, missingRevokedRuns + openIssueCheck.revokedRuns),
|
|
235
|
+
failures: [
|
|
236
|
+
...preflight.failures,
|
|
237
|
+
...openIssueCheck.failures,
|
|
238
|
+
...failingItems.flatMap((failing) => failingItemPollFailures(watched.repository.name, failing)),
|
|
239
|
+
],
|
|
133
240
|
preflightFindings: preflight.preflightFindings,
|
|
134
|
-
nextPollAt,
|
|
241
|
+
nextPollAt: latestPollAt([nextPollAt, openIssueCheck.nextPollAt]),
|
|
135
242
|
};
|
|
136
243
|
}).pipe(Effect.mapError((error) => ({
|
|
137
244
|
_tag: "InterruptedRepositoryCycle",
|
|
138
245
|
error,
|
|
139
|
-
failures:
|
|
246
|
+
failures: [
|
|
247
|
+
...preflight.failures,
|
|
248
|
+
...stored.failingItems.flatMap((failing) => failingItemPollFailures(watched.repository.name, failing)),
|
|
249
|
+
],
|
|
140
250
|
preflightFindings: preflight.preflightFindings,
|
|
141
251
|
nextPollAt: preflight.nextPollAt,
|
|
142
252
|
})));
|
|
143
253
|
});
|
|
144
254
|
// Bind only dependencies, preserving the caller's clock, logging and
|
|
145
255
|
// tracing context on each cycle instead of capturing them at layer build.
|
|
146
|
-
const repositoryServices = (yield* Effect.context()).pipe(Context.pick(ConfigParser, CycleBudgets, ExpressionEngine, GitHubPolling, ItemProjectionWriter, LabelReconciler, RepositoryLabelProjectionReader, RepositoryLabelProjectionWriter, RunEngine));
|
|
256
|
+
const repositoryServices = (yield* Effect.context()).pipe(Context.pick(ConfigParser, CycleBudgets, ExpressionEngine, GitHubPolling, ItemProjectionReader, ItemProjectionWriter, LabelReconciler, RepositoryLabelProjectionReader, RepositoryLabelProjectionWriter, RunEngine));
|
|
147
257
|
const poll = Effect.fn("PollingTriggers.poll")(function* (instance) {
|
|
148
258
|
yield* hints.awaitBackoff;
|
|
259
|
+
yield* Ref.update(retriedFailingItems, (retried) => Option.contains(retried.instance, instance)
|
|
260
|
+
? retried
|
|
261
|
+
: { instance: Option.some(instance), repositories: new Set() });
|
|
149
262
|
const paused = new Set((yield* loops.states).filter((state) => state.paused).map((state) => state.loop));
|
|
150
263
|
for (const loop of instance.loops) {
|
|
151
264
|
if (loop.trigger.on !== "schedule" && paused.has(loop.name)) {
|
|
@@ -161,10 +274,12 @@ export class PollingTriggers extends Context.Service()("@usine/orchestrator/Poll
|
|
|
161
274
|
const failures = [];
|
|
162
275
|
const backoffs = [];
|
|
163
276
|
const preflightFindings = [];
|
|
277
|
+
const completedAt = yield* DateTime.now;
|
|
164
278
|
for (const { repository, result } of settled) {
|
|
165
279
|
if (Result.isSuccess(result)) {
|
|
166
280
|
cycles.push(result.success);
|
|
167
281
|
preflightFindings.push(...result.success.preflightFindings);
|
|
282
|
+
yield* Ref.update(completedPolls, (current) => new Map(current).set(canonicalRepositoryName(repository.repository.name), new RepositoryPoll({ repository: repository.repository.name, completedAt })));
|
|
168
283
|
continue;
|
|
169
284
|
}
|
|
170
285
|
const interrupted = result.failure._tag === "InterruptedRepositoryCycle";
|
|
@@ -196,7 +311,9 @@ export class PollingTriggers extends Context.Service()("@usine/orchestrator/Poll
|
|
|
196
311
|
message: error.message,
|
|
197
312
|
}));
|
|
198
313
|
}
|
|
314
|
+
const polls = yield* Ref.get(completedPolls);
|
|
199
315
|
const cycle = new PollCycle({
|
|
316
|
+
repositoryPolls: watched.flatMap(({ repository }) => Option.toArray(Option.fromNullishOr(polls.get(canonicalRepositoryName(repository.name))))),
|
|
200
317
|
repositories: watched.length,
|
|
201
318
|
changedItems: cycles.reduce((sum, cycle) => sum + cycle.changedItems, 0),
|
|
202
319
|
submissions: cycles.flatMap(({ submissions }) => submissions),
|
|
@@ -228,6 +345,18 @@ export class PollingTriggers extends Context.Service()("@usine/orchestrator/Poll
|
|
|
228
345
|
// advance a REST cursor or replace the latest complete cycle's findings.
|
|
229
346
|
const observed = yield* observeItem(watched.repository.name, hint.item);
|
|
230
347
|
const result = yield* evaluateItem(watched.repository, watched.loops, observed);
|
|
348
|
+
// The self-write changed the Item, so the next poll fetches it again
|
|
349
|
+
// and records these failures for Needs you.
|
|
350
|
+
for (const failure of result.failures) {
|
|
351
|
+
yield* Effect.logWarning("Self-write Hint could not evaluate a Loop on the Item", {
|
|
352
|
+
repository: hint.repository,
|
|
353
|
+
item: hint.item.number,
|
|
354
|
+
loop: failure.loop,
|
|
355
|
+
stage: failure.stage,
|
|
356
|
+
errorTag: failure.errorTag,
|
|
357
|
+
message: failure.message,
|
|
358
|
+
});
|
|
359
|
+
}
|
|
231
360
|
yield* Effect.logInfo("Self-write Hint refreshed the Item", {
|
|
232
361
|
repository: hint.repository,
|
|
233
362
|
item: hint.item.number,
|
|
@@ -244,20 +373,41 @@ export class PollingTriggers extends Context.Service()("@usine/orchestrator/Poll
|
|
|
244
373
|
...repositoryFailureLogFields(error),
|
|
245
374
|
});
|
|
246
375
|
})), ownership.withPermits(1)));
|
|
247
|
-
|
|
376
|
+
// An accepted reload ends the wait for `intervalAt`, never the wait for
|
|
377
|
+
// `requestedAt`, the time GitHub asked for.
|
|
378
|
+
const waitForNextPoll = (instances, polled, intervalAt, requestedAt) => Effect.gen(function* () {
|
|
379
|
+
let target = Math.max(intervalAt, requestedAt);
|
|
380
|
+
let seen = polled;
|
|
248
381
|
while (true) {
|
|
249
382
|
const remaining = target - (yield* Clock.currentTimeMillis);
|
|
250
383
|
if (remaining <= 0)
|
|
251
384
|
return;
|
|
252
|
-
const
|
|
253
|
-
|
|
385
|
+
const wake = yield* Effect.raceAllFirst([
|
|
386
|
+
Effect.sleep(Duration.millis(remaining)).pipe(Effect.map(() => ({ _tag: "Due" }))),
|
|
387
|
+
hints.take.pipe(Effect.map((hint) => ({ _tag: "Hint", hint }))),
|
|
388
|
+
reloadedFrom(instances, seen).pipe(Effect.map((instance) => ({ _tag: "Reloaded", instance }))),
|
|
389
|
+
]);
|
|
390
|
+
if (wake._tag === "Due")
|
|
254
391
|
return;
|
|
255
|
-
|
|
392
|
+
if (wake._tag === "Hint") {
|
|
393
|
+
yield* refreshHint(yield* instances.get, wake.hint);
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
396
|
+
seen = wake.instance;
|
|
397
|
+
target = requestedAt;
|
|
398
|
+
const sleepMs = requestedAt - (yield* Clock.currentTimeMillis);
|
|
399
|
+
if (sleepMs > 0) {
|
|
400
|
+
yield* Effect.logInfo("Instance reloaded; the next poll waits for the time GitHub asked for", { sleepMs });
|
|
401
|
+
}
|
|
402
|
+
else {
|
|
403
|
+
yield* Effect.logInfo("Instance reloaded; polling now instead of after poll_interval");
|
|
404
|
+
}
|
|
256
405
|
}
|
|
257
406
|
});
|
|
258
407
|
// `run` never returns, so wrapping it in Effect.fn would open a span that
|
|
259
408
|
// never closes; `poll` opens the span for each cycle.
|
|
260
|
-
const run = (
|
|
409
|
+
const run = (instances) => Effect.gen(function* () {
|
|
410
|
+
const instance = yield* instances.get;
|
|
261
411
|
const startedAt = yield* Clock.currentTimeMillis;
|
|
262
412
|
const result = yield* Effect.result(poll(instance));
|
|
263
413
|
if (Result.isFailure(result)) {
|
|
@@ -273,12 +423,12 @@ export class PollingTriggers extends Context.Service()("@usine/orchestrator/Poll
|
|
|
273
423
|
}
|
|
274
424
|
const cycle = result.success;
|
|
275
425
|
const intervalAt = startedAt + instance.config.settings.pollInterval * 1_000;
|
|
276
|
-
const
|
|
277
|
-
onNone: () =>
|
|
278
|
-
onSome:
|
|
426
|
+
const requestedAt = Option.match(cycle.nextPollAt, {
|
|
427
|
+
onNone: () => 0,
|
|
428
|
+
onSome: DateTime.toEpochMillis,
|
|
279
429
|
});
|
|
280
430
|
const now = yield* Clock.currentTimeMillis;
|
|
281
|
-
const sleepMs = Math.max(0,
|
|
431
|
+
const sleepMs = Math.max(0, Math.max(intervalAt, requestedAt) - now);
|
|
282
432
|
yield* Effect.logInfo("Poll cycle complete", {
|
|
283
433
|
repositories: cycle.repositories,
|
|
284
434
|
changedItems: cycle.changedItems,
|
|
@@ -288,7 +438,7 @@ export class PollingTriggers extends Context.Service()("@usine/orchestrator/Poll
|
|
|
288
438
|
preflightFindings: cycle.preflightFindings.length,
|
|
289
439
|
sleepMs,
|
|
290
440
|
});
|
|
291
|
-
yield* waitForNextPoll(instance,
|
|
441
|
+
yield* waitForNextPoll(instances, instance, intervalAt, requestedAt);
|
|
292
442
|
}).pipe(Effect.forever);
|
|
293
443
|
return { latest: Ref.get(latest), poll, run, hint: hints.offer };
|
|
294
444
|
})).pipe(Layer.provide(ItemHints.layer));
|