@substrat-run/kernel 0.148.0 → 0.149.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/dist/attachment-sweep.d.ts +208 -0
- package/dist/attachment-sweep.d.ts.map +1 -0
- package/dist/attachment-sweep.js +318 -0
- package/dist/attachment-sweep.js.map +1 -0
- package/dist/index.d.ts +15 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -7
- package/dist/index.js.map +1 -1
- package/dist/invocation-line.d.ts +85 -0
- package/dist/invocation-line.d.ts.map +1 -1
- package/dist/invocation-line.js +43 -0
- package/dist/invocation-line.js.map +1 -1
- package/dist/migration-digest.d.ts +56 -0
- package/dist/migration-digest.d.ts.map +1 -1
- package/dist/migration-digest.js +92 -0
- package/dist/migration-digest.js.map +1 -1
- package/dist/migration-fence.d.ts +14 -0
- package/dist/migration-fence.d.ts.map +1 -0
- package/dist/migration-fence.js +515 -0
- package/dist/migration-fence.js.map +1 -0
- package/dist/migration-replay.d.ts +52 -0
- package/dist/migration-replay.d.ts.map +1 -0
- package/dist/migration-replay.js +140 -0
- package/dist/migration-replay.js.map +1 -0
- package/dist/module-migrations.d.ts +3 -3
- package/dist/module-migrations.js +3 -3
- package/dist/peer.d.ts +32 -2
- package/dist/peer.d.ts.map +1 -1
- package/dist/peer.js +99 -3
- package/dist/peer.js.map +1 -1
- package/dist/permission-eval.d.ts +8 -0
- package/dist/permission-eval.d.ts.map +1 -1
- package/dist/permission-eval.js +14 -0
- package/dist/permission-eval.js.map +1 -1
- package/dist/platform-sweep.d.ts +94 -1
- package/dist/platform-sweep.d.ts.map +1 -1
- package/dist/platform-sweep.js +130 -0
- package/dist/platform-sweep.js.map +1 -1
- package/dist/promote-review.d.ts +125 -0
- package/dist/promote-review.d.ts.map +1 -0
- package/dist/promote-review.js +181 -0
- package/dist/promote-review.js.map +1 -0
- package/dist/scope-host.d.ts +204 -42
- package/dist/scope-host.d.ts.map +1 -1
- package/dist/scope-host.js.map +1 -1
- package/dist/scope-store.d.ts +5 -5
- package/dist/scope-store.d.ts.map +1 -1
- package/dist/spine-restore.d.ts +2 -0
- package/dist/spine-restore.d.ts.map +1 -1
- package/dist/spine-restore.js +5 -0
- package/dist/spine-restore.js.map +1 -1
- package/dist/store-driver-releases.d.ts +306 -0
- package/dist/store-driver-releases.d.ts.map +1 -0
- package/dist/store-driver-releases.js +581 -0
- package/dist/store-driver-releases.js.map +1 -0
- package/dist/table-ownership.d.ts +5 -2
- package/dist/table-ownership.d.ts.map +1 -1
- package/dist/table-ownership.js +19 -10
- package/dist/table-ownership.js.map +1 -1
- package/dist/testing.d.ts +2 -0
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +2 -0
- package/dist/testing.js.map +1 -1
- package/dist/upload-link.d.ts +60 -7
- package/dist/upload-link.d.ts.map +1 -1
- package/dist/upload-link.js +189 -25
- package/dist/upload-link.js.map +1 -1
- package/dist/version-migrations.d.ts +63 -1
- package/dist/version-migrations.d.ts.map +1 -1
- package/dist/version-migrations.js +174 -8
- package/dist/version-migrations.js.map +1 -1
- package/dist/vertical-scope-stores.d.ts +9 -9
- package/dist/vertical-scope-stores.d.ts.map +1 -1
- package/dist/vertical-scope-stores.js +29 -29
- package/dist/vertical-scope-stores.js.map +1 -1
- package/package.json +2 -2
- package/dist/store-kind-releases.d.ts +0 -137
- package/dist/store-kind-releases.d.ts.map +0 -1
- package/dist/store-kind-releases.js +0 -252
- package/dist/store-kind-releases.js.map +0 -1
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import type { SwitchSql } from './system-switch.js';
|
|
2
|
-
/** Interpolated into both adapters' directory DDL, so `lint:spine-ddl` sees one spelling on each side. */
|
|
3
|
-
export declare const STORE_KIND_RELEASES_DDL = "\n CREATE TABLE IF NOT EXISTS store_kind_releases (\n kind TEXT NOT NULL,\n sha256 TEXT NOT NULL,\n source_commit TEXT NOT NULL,\n uploaded_by TEXT NOT NULL,\n uploaded_at TEXT NOT NULL,\n PRIMARY KEY (kind, sha256)\n );\n CREATE TABLE IF NOT EXISTS store_kind_rollouts (\n kind TEXT NOT NULL,\n seq INTEGER NOT NULL,\n sha256 TEXT NOT NULL,\n action TEXT NOT NULL,\n from_sha256 TEXT,\n previous_good_sha256 TEXT,\n state TEXT NOT NULL,\n actor TEXT NOT NULL,\n -- The hold the rollout runs under: a rolling row whose holder holds nothing has stopped.\n holder TEXT NOT NULL,\n started_at TEXT NOT NULL,\n ended_at TEXT,\n detail TEXT,\n PRIMARY KEY (kind, seq)\n );\n CREATE TABLE IF NOT EXISTS store_kind_current (\n kind TEXT PRIMARY KEY,\n sha256 TEXT NOT NULL,\n seq INTEGER NOT NULL\n );\n CREATE TABLE IF NOT EXISTS store_kind_holds (\n kind TEXT NOT NULL,\n holder TEXT NOT NULL,\n mode TEXT NOT NULL,\n expires_at INTEGER NOT NULL,\n PRIMARY KEY (kind, holder)\n );\n";
|
|
4
|
-
/** A stored release: its bytes are kept elsewhere under `<kind>/<sha256>`. */
|
|
5
|
-
export interface StoreKindReleaseRecord {
|
|
6
|
-
readonly kind: string;
|
|
7
|
-
readonly sha256: string;
|
|
8
|
-
readonly sourceCommit: string;
|
|
9
|
-
readonly uploadedBy: string;
|
|
10
|
-
readonly uploadedAt: string;
|
|
11
|
-
}
|
|
12
|
-
export type StoreKindRolloutAction = 'rollout' | 'rollback';
|
|
13
|
-
/**
|
|
14
|
-
* `paused`: the request's batch ran out with verticals left to walk. Nothing failed; the fleet is
|
|
15
|
-
* part way, and posting the same rollout (or the same rollback) again continues it.
|
|
16
|
-
*/
|
|
17
|
-
export type StoreKindRolloutState = 'rolling' | 'good' | 'failed' | 'diverged' | 'paused';
|
|
18
|
-
export interface StoreKindRolloutRecord {
|
|
19
|
-
readonly kind: string;
|
|
20
|
-
readonly seq: number;
|
|
21
|
-
readonly sha256: string;
|
|
22
|
-
readonly action: StoreKindRolloutAction;
|
|
23
|
-
/** The current good release when the rollout began; null for a kind's first. */
|
|
24
|
-
readonly fromSha256: string | null;
|
|
25
|
-
/** Where a rollback from this release, once it is good, returns to; null when nowhere. */
|
|
26
|
-
readonly previousGoodSha256: string | null;
|
|
27
|
-
readonly state: StoreKindRolloutState;
|
|
28
|
-
readonly actor: string;
|
|
29
|
-
readonly startedAt: string;
|
|
30
|
-
readonly endedAt: string | null;
|
|
31
|
-
readonly detail: string | null;
|
|
32
|
-
}
|
|
33
|
-
export interface StoreKindState {
|
|
34
|
-
/** The release the last good rollout reached, and that rollout. Null before any. */
|
|
35
|
-
readonly current: {
|
|
36
|
-
readonly sha256: string;
|
|
37
|
-
readonly seq: number;
|
|
38
|
-
readonly previousGoodSha256: string | null;
|
|
39
|
-
} | null;
|
|
40
|
-
/** Every rollout, oldest first. */
|
|
41
|
-
readonly rollouts: StoreKindRolloutRecord[];
|
|
42
|
-
/** Where a rollback goes now (see `storeKindStateIn`); null when nowhere. */
|
|
43
|
-
readonly rollbackTarget: string | null;
|
|
44
|
-
/** The target of a rollback that paused or diverged part way, until it ends good. Unless it is the current release, it blocks rollouts. */
|
|
45
|
-
readonly unfinishedRollback: string | null;
|
|
46
|
-
}
|
|
47
|
-
export type StoreKindHoldMode = 'shared' | 'exclusive';
|
|
48
|
-
/** A stored release, or undefined. */
|
|
49
|
-
export declare function storeKindReleaseIn(db: SwitchSql, kind: string, sha256: string): StoreKindReleaseRecord | undefined;
|
|
50
|
-
/**
|
|
51
|
-
* Record that a release's bytes are stored. The same sha256 again is the same release, and the
|
|
52
|
-
* row already written is returned as it stands (`created: false`). The same sha256 from another
|
|
53
|
-
* commit is refused (`conflict`): one bundle has one source the reviewer reads.
|
|
54
|
-
*/
|
|
55
|
-
export declare function recordStoreKindReleaseIn(db: SwitchSql, input: {
|
|
56
|
-
kind: string;
|
|
57
|
-
sha256: string;
|
|
58
|
-
sourceCommit: string;
|
|
59
|
-
actor: string;
|
|
60
|
-
at: string;
|
|
61
|
-
}): {
|
|
62
|
-
record: StoreKindReleaseRecord;
|
|
63
|
-
created: boolean;
|
|
64
|
-
};
|
|
65
|
-
/**
|
|
66
|
-
* The kind's current release, every rollout, and where a rollback goes now.
|
|
67
|
-
*
|
|
68
|
-
* With `nowMs`, a `rolling` row whose holder no longer holds the kind exclusively is reported as
|
|
69
|
-
* `diverged` (read-time only, nothing is written): its holder stopped, and its scripts may be on
|
|
70
|
-
* either release. The next rollout's begin writes that state.
|
|
71
|
-
*
|
|
72
|
-
* `rollbackTarget` is, in order:
|
|
73
|
-
* - the target of a rollback that is the newest attempt since the current release, a `failed` one
|
|
74
|
-
* aside, and ended `paused` or `diverged` (`unfinishedRollback`): posting the rollback again
|
|
75
|
-
* continues it, and never turns it around onto the release it is leaving. A failed attempt moved
|
|
76
|
-
* nothing, or returned what it moved, so it changes nothing here. No rollout may begin while a
|
|
77
|
-
* rollback to an earlier release is unfinished, `paused` or `diverged` (`beginStoreKindRolloutIn`):
|
|
78
|
-
* it is finished first, by posting it again. A rollback onto the current release (undoing a
|
|
79
|
-
* diverged rollout) does not block a rollout. A rollback to an earlier release cannot meet the
|
|
80
|
-
* schema rule (the route refuses one below the current schema), but one onto the current release
|
|
81
|
-
* can, and then it never finishes, so going forward must stay open;
|
|
82
|
-
* - the current release itself, when a rollout since it ended `diverged` or `paused`: the fleet may
|
|
83
|
-
* be mixed, and undoing that rollout means converging every script back on the release it was
|
|
84
|
-
* healthy on, never going past it;
|
|
85
|
-
* - otherwise the immediately previous good release.
|
|
86
|
-
* An unfinished attempt never changes what "previous good" means.
|
|
87
|
-
*/
|
|
88
|
-
export declare function storeKindStateIn(db: SwitchSql, kind: string, nowMs?: number): StoreKindState;
|
|
89
|
-
/**
|
|
90
|
-
* Take, or renew, a hold on a kind. Answers false when another holder's live hold excludes it: an
|
|
91
|
-
* exclusive one for any request, or any one for an exclusive request. A lapsed hold is dropped
|
|
92
|
-
* first. Asking in the other mode than the one held is refused.
|
|
93
|
-
*
|
|
94
|
-
* `renew` only extends a hold the holder still holds: a holder whose lease lapsed gets false, even
|
|
95
|
-
* when nobody took the kind since, because a lapsed holder cannot know what happened meanwhile.
|
|
96
|
-
* With `rolloutSeq` it also answers false unless that rollout is still `rolling`, so a rollout
|
|
97
|
-
* whose row another holder ended stops instead of moving scripts the state no longer describes.
|
|
98
|
-
*/
|
|
99
|
-
export declare function holdStoreKindIn(db: SwitchSql, input: {
|
|
100
|
-
kind: string;
|
|
101
|
-
holder: string;
|
|
102
|
-
mode: StoreKindHoldMode;
|
|
103
|
-
nowMs: number;
|
|
104
|
-
ttlMs: number;
|
|
105
|
-
renew?: boolean;
|
|
106
|
-
rolloutSeq?: number;
|
|
107
|
-
}): boolean;
|
|
108
|
-
/** Drop a hold. Dropping one already gone is not an error. */
|
|
109
|
-
export declare function releaseStoreKindHoldIn(db: SwitchSql, input: {
|
|
110
|
-
kind: string;
|
|
111
|
-
holder: string;
|
|
112
|
-
}): void;
|
|
113
|
-
/**
|
|
114
|
-
* Begin a rollout or a rollback of a stored release, as the exclusive holder. A rollout left
|
|
115
|
-
* `rolling` by an earlier holder ends `diverged` here: its scripts may be on either release, and
|
|
116
|
-
* this rollout reaches all of them. A rollback must name the current release's previous good one.
|
|
117
|
-
*/
|
|
118
|
-
export declare function beginStoreKindRolloutIn(db: SwitchSql, input: {
|
|
119
|
-
kind: string;
|
|
120
|
-
sha256: string;
|
|
121
|
-
action: StoreKindRolloutAction;
|
|
122
|
-
holder: string;
|
|
123
|
-
actor: string;
|
|
124
|
-
at: string;
|
|
125
|
-
nowMs: number;
|
|
126
|
-
}): StoreKindRolloutRecord;
|
|
127
|
-
/** End a rollout the caller began, as the exclusive holder. A good one makes its release current. */
|
|
128
|
-
export declare function finishStoreKindRolloutIn(db: SwitchSql, input: {
|
|
129
|
-
kind: string;
|
|
130
|
-
seq: number;
|
|
131
|
-
holder: string;
|
|
132
|
-
state: Exclude<StoreKindRolloutState, 'rolling'>;
|
|
133
|
-
detail: string | null;
|
|
134
|
-
at: string;
|
|
135
|
-
nowMs: number;
|
|
136
|
-
}): StoreKindRolloutRecord;
|
|
137
|
-
//# sourceMappingURL=store-kind-releases.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"store-kind-releases.d.ts","sourceRoot":"","sources":["../src/store-kind-releases.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A store kind's releases, its rollouts and the holds that serialize them (D-63, #2300), shared by
|
|
3
|
-
* both adapters' directories.
|
|
4
|
-
*
|
|
5
|
-
* - `store_kind_releases`: a release's bytes were stored (the bytes themselves live outside the
|
|
6
|
-
* directory, keyed by kind and sha256). Insert-only: who uploaded a release, and from which
|
|
7
|
-
* commit, is never rewritten.
|
|
8
|
-
* - `store_kind_rollouts`: one row per attempt to move every script of the kind to a release, in
|
|
9
|
-
* `seq` order. A row is `rolling` until its holder ends it `good`, `failed` or `diverged`.
|
|
10
|
-
* - `store_kind_current`: the release the last `good` rollout moved every script to.
|
|
11
|
-
*
|
|
12
|
-
* "The immediately previous good release" (D-63) is recorded, never derived from an ordering:
|
|
13
|
-
* each rollout row names `previous_good_sha256`, the release a rollback from it returns to. A
|
|
14
|
-
* rollout of T from current F records F; a rollback goes to the current row's previous good X, and
|
|
15
|
-
* records X's own previous good, so after r1 → r2 → r3 one rollback reaches r2 and the next r1.
|
|
16
|
-
*
|
|
17
|
-
* A hold is a lease: `exclusive` for a rollout or a rollback, `shared` for a push or serve that
|
|
18
|
-
* rebuilds a script at the release it runs, which a rollout must not interleave with (a rebuild
|
|
19
|
-
* that read the old release and uploaded after the rollout moved the script would revert it).
|
|
20
|
-
* A begin or finish is refused unless the caller still holds the kind exclusively, so a holder
|
|
21
|
-
* whose lease lapsed cannot write over the next one; its `rolling` row reads as `diverged` to the
|
|
22
|
-
* next rollout, which converges every script again.
|
|
23
|
-
*/
|
|
24
|
-
import { substratError } from '@substrat-run/contracts';
|
|
25
|
-
/** Interpolated into both adapters' directory DDL, so `lint:spine-ddl` sees one spelling on each side. */
|
|
26
|
-
export const STORE_KIND_RELEASES_DDL = `
|
|
27
|
-
CREATE TABLE IF NOT EXISTS store_kind_releases (
|
|
28
|
-
kind TEXT NOT NULL,
|
|
29
|
-
sha256 TEXT NOT NULL,
|
|
30
|
-
source_commit TEXT NOT NULL,
|
|
31
|
-
uploaded_by TEXT NOT NULL,
|
|
32
|
-
uploaded_at TEXT NOT NULL,
|
|
33
|
-
PRIMARY KEY (kind, sha256)
|
|
34
|
-
);
|
|
35
|
-
CREATE TABLE IF NOT EXISTS store_kind_rollouts (
|
|
36
|
-
kind TEXT NOT NULL,
|
|
37
|
-
seq INTEGER NOT NULL,
|
|
38
|
-
sha256 TEXT NOT NULL,
|
|
39
|
-
action TEXT NOT NULL,
|
|
40
|
-
from_sha256 TEXT,
|
|
41
|
-
previous_good_sha256 TEXT,
|
|
42
|
-
state TEXT NOT NULL,
|
|
43
|
-
actor TEXT NOT NULL,
|
|
44
|
-
-- The hold the rollout runs under: a rolling row whose holder holds nothing has stopped.
|
|
45
|
-
holder TEXT NOT NULL,
|
|
46
|
-
started_at TEXT NOT NULL,
|
|
47
|
-
ended_at TEXT,
|
|
48
|
-
detail TEXT,
|
|
49
|
-
PRIMARY KEY (kind, seq)
|
|
50
|
-
);
|
|
51
|
-
CREATE TABLE IF NOT EXISTS store_kind_current (
|
|
52
|
-
kind TEXT PRIMARY KEY,
|
|
53
|
-
sha256 TEXT NOT NULL,
|
|
54
|
-
seq INTEGER NOT NULL
|
|
55
|
-
);
|
|
56
|
-
CREATE TABLE IF NOT EXISTS store_kind_holds (
|
|
57
|
-
kind TEXT NOT NULL,
|
|
58
|
-
holder TEXT NOT NULL,
|
|
59
|
-
mode TEXT NOT NULL,
|
|
60
|
-
expires_at INTEGER NOT NULL,
|
|
61
|
-
PRIMARY KEY (kind, holder)
|
|
62
|
-
);
|
|
63
|
-
`;
|
|
64
|
-
const rolloutOf = (r) => ({
|
|
65
|
-
kind: r.kind,
|
|
66
|
-
seq: Number(r.seq),
|
|
67
|
-
sha256: r.sha256,
|
|
68
|
-
action: r.action,
|
|
69
|
-
fromSha256: r.from_sha256,
|
|
70
|
-
previousGoodSha256: r.previous_good_sha256,
|
|
71
|
-
state: r.state,
|
|
72
|
-
actor: r.actor,
|
|
73
|
-
startedAt: r.started_at,
|
|
74
|
-
endedAt: r.ended_at,
|
|
75
|
-
detail: r.detail,
|
|
76
|
-
});
|
|
77
|
-
const ROLLOUT_COLUMNS = 'kind, seq, sha256, action, from_sha256, previous_good_sha256, state, actor, started_at, ended_at, detail';
|
|
78
|
-
function rolloutAt(db, kind, seq) {
|
|
79
|
-
const [row] = db.all(`SELECT ${ROLLOUT_COLUMNS} FROM store_kind_rollouts WHERE kind = ? AND seq = ?`, kind, seq);
|
|
80
|
-
return row ? rolloutOf(row) : undefined;
|
|
81
|
-
}
|
|
82
|
-
/** A stored release, or undefined. */
|
|
83
|
-
export function storeKindReleaseIn(db, kind, sha256) {
|
|
84
|
-
const [row] = db.all('SELECT kind, sha256, source_commit, uploaded_by, uploaded_at FROM store_kind_releases WHERE kind = ? AND sha256 = ?', kind, sha256);
|
|
85
|
-
return row
|
|
86
|
-
? { kind: row.kind, sha256: row.sha256, sourceCommit: row.source_commit, uploadedBy: row.uploaded_by, uploadedAt: row.uploaded_at }
|
|
87
|
-
: undefined;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Record that a release's bytes are stored. The same sha256 again is the same release, and the
|
|
91
|
-
* row already written is returned as it stands (`created: false`). The same sha256 from another
|
|
92
|
-
* commit is refused (`conflict`): one bundle has one source the reviewer reads.
|
|
93
|
-
*/
|
|
94
|
-
export function recordStoreKindReleaseIn(db, input) {
|
|
95
|
-
const held = storeKindReleaseIn(db, input.kind, input.sha256);
|
|
96
|
-
if (held) {
|
|
97
|
-
if (held.sourceCommit !== input.sourceCommit) {
|
|
98
|
-
throw substratError('conflict', `release ${input.sha256} of '${input.kind}' is stored as built from ${held.sourceCommit}, not ${input.sourceCommit}`);
|
|
99
|
-
}
|
|
100
|
-
return { record: held, created: false };
|
|
101
|
-
}
|
|
102
|
-
db.run('INSERT INTO store_kind_releases (kind, sha256, source_commit, uploaded_by, uploaded_at) VALUES (?, ?, ?, ?, ?)', input.kind, input.sha256, input.sourceCommit, input.actor, input.at);
|
|
103
|
-
return { record: storeKindReleaseIn(db, input.kind, input.sha256), created: true };
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* The kind's current release, every rollout, and where a rollback goes now.
|
|
107
|
-
*
|
|
108
|
-
* With `nowMs`, a `rolling` row whose holder no longer holds the kind exclusively is reported as
|
|
109
|
-
* `diverged` (read-time only, nothing is written): its holder stopped, and its scripts may be on
|
|
110
|
-
* either release. The next rollout's begin writes that state.
|
|
111
|
-
*
|
|
112
|
-
* `rollbackTarget` is, in order:
|
|
113
|
-
* - the target of a rollback that is the newest attempt since the current release, a `failed` one
|
|
114
|
-
* aside, and ended `paused` or `diverged` (`unfinishedRollback`): posting the rollback again
|
|
115
|
-
* continues it, and never turns it around onto the release it is leaving. A failed attempt moved
|
|
116
|
-
* nothing, or returned what it moved, so it changes nothing here. No rollout may begin while a
|
|
117
|
-
* rollback to an earlier release is unfinished, `paused` or `diverged` (`beginStoreKindRolloutIn`):
|
|
118
|
-
* it is finished first, by posting it again. A rollback onto the current release (undoing a
|
|
119
|
-
* diverged rollout) does not block a rollout. A rollback to an earlier release cannot meet the
|
|
120
|
-
* schema rule (the route refuses one below the current schema), but one onto the current release
|
|
121
|
-
* can, and then it never finishes, so going forward must stay open;
|
|
122
|
-
* - the current release itself, when a rollout since it ended `diverged` or `paused`: the fleet may
|
|
123
|
-
* be mixed, and undoing that rollout means converging every script back on the release it was
|
|
124
|
-
* healthy on, never going past it;
|
|
125
|
-
* - otherwise the immediately previous good release.
|
|
126
|
-
* An unfinished attempt never changes what "previous good" means.
|
|
127
|
-
*/
|
|
128
|
-
export function storeKindStateIn(db, kind, nowMs) {
|
|
129
|
-
const live = nowMs === undefined
|
|
130
|
-
? undefined
|
|
131
|
-
: new Set(db.all("SELECT holder FROM store_kind_holds WHERE kind = ? AND mode = 'exclusive' AND expires_at > ?", kind, nowMs).map((h) => h.holder));
|
|
132
|
-
const rows = db.all(`SELECT ${ROLLOUT_COLUMNS}, holder FROM store_kind_rollouts WHERE kind = ? ORDER BY seq`, kind);
|
|
133
|
-
const rollouts = rows.map((r) => live && r.state === 'rolling' && !(r.holder && live.has(r.holder))
|
|
134
|
-
? rolloutOf({ ...r, state: 'diverged', detail: 'its holder no longer holds the kind; the rollout stopped before it ended' })
|
|
135
|
-
: rolloutOf(r));
|
|
136
|
-
const [current] = db.all('SELECT sha256, seq FROM store_kind_current WHERE kind = ?', kind);
|
|
137
|
-
if (!current)
|
|
138
|
-
return { current: null, rollouts, rollbackTarget: null, unfinishedRollback: null };
|
|
139
|
-
const seq = Number(current.seq);
|
|
140
|
-
const row = rollouts.find((r) => r.seq === seq);
|
|
141
|
-
const previousGoodSha256 = row?.previousGoodSha256 ?? null;
|
|
142
|
-
const since = rollouts.filter((r) => r.seq > seq);
|
|
143
|
-
// A failed attempt moved nothing, or returned what it moved, so it never decides what comes next.
|
|
144
|
-
const newest = since.filter((r) => r.state !== 'failed').at(-1);
|
|
145
|
-
const unfinishedRollback = newest?.action === 'rollback' && (newest.state === 'paused' || newest.state === 'diverged') ? newest.sha256 : null;
|
|
146
|
-
const mixed = since.some((r) => r.state === 'diverged' || r.state === 'paused');
|
|
147
|
-
return {
|
|
148
|
-
current: { sha256: current.sha256, seq, previousGoodSha256 },
|
|
149
|
-
rollouts,
|
|
150
|
-
rollbackTarget: unfinishedRollback ?? (mixed ? current.sha256 : previousGoodSha256),
|
|
151
|
-
unfinishedRollback,
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Take, or renew, a hold on a kind. Answers false when another holder's live hold excludes it: an
|
|
156
|
-
* exclusive one for any request, or any one for an exclusive request. A lapsed hold is dropped
|
|
157
|
-
* first. Asking in the other mode than the one held is refused.
|
|
158
|
-
*
|
|
159
|
-
* `renew` only extends a hold the holder still holds: a holder whose lease lapsed gets false, even
|
|
160
|
-
* when nobody took the kind since, because a lapsed holder cannot know what happened meanwhile.
|
|
161
|
-
* With `rolloutSeq` it also answers false unless that rollout is still `rolling`, so a rollout
|
|
162
|
-
* whose row another holder ended stops instead of moving scripts the state no longer describes.
|
|
163
|
-
*/
|
|
164
|
-
export function holdStoreKindIn(db, input) {
|
|
165
|
-
if (!(input.ttlMs > 0))
|
|
166
|
-
throw substratError('validation_failed', 'a store-kind hold needs a positive lifetime');
|
|
167
|
-
db.run('DELETE FROM store_kind_holds WHERE kind = ? AND expires_at <= ?', input.kind, input.nowMs);
|
|
168
|
-
const live = db.all('SELECT holder, mode FROM store_kind_holds WHERE kind = ?', input.kind);
|
|
169
|
-
const own = live.find((h) => h.holder === input.holder);
|
|
170
|
-
if (own && own.mode !== input.mode) {
|
|
171
|
-
throw substratError('conflict', `holder ${input.holder} holds '${input.kind}' ${own.mode}, not ${input.mode}`);
|
|
172
|
-
}
|
|
173
|
-
if ((input.renew || input.rolloutSeq !== undefined) && !own)
|
|
174
|
-
return false;
|
|
175
|
-
if (input.rolloutSeq !== undefined && rolloutAt(db, input.kind, input.rolloutSeq)?.state !== 'rolling')
|
|
176
|
-
return false;
|
|
177
|
-
const others = live.filter((h) => h.holder !== input.holder);
|
|
178
|
-
if (input.mode === 'exclusive' ? others.length > 0 : others.some((h) => h.mode === 'exclusive'))
|
|
179
|
-
return false;
|
|
180
|
-
db.run(`INSERT INTO store_kind_holds (kind, holder, mode, expires_at) VALUES (?, ?, ?, ?)
|
|
181
|
-
ON CONFLICT (kind, holder) DO UPDATE SET expires_at = excluded.expires_at`, input.kind, input.holder, input.mode, input.nowMs + input.ttlMs);
|
|
182
|
-
return true;
|
|
183
|
-
}
|
|
184
|
-
/** Drop a hold. Dropping one already gone is not an error. */
|
|
185
|
-
export function releaseStoreKindHoldIn(db, input) {
|
|
186
|
-
db.run('DELETE FROM store_kind_holds WHERE kind = ? AND holder = ?', input.kind, input.holder);
|
|
187
|
-
}
|
|
188
|
-
function assertExclusive(db, kind, holder, nowMs) {
|
|
189
|
-
const [row] = db.all("SELECT 1 AS held FROM store_kind_holds WHERE kind = ? AND holder = ? AND mode = 'exclusive' AND expires_at > ?", kind, holder, nowMs);
|
|
190
|
-
if (!row)
|
|
191
|
-
throw substratError('conflict', `'${kind}' is not held exclusively by ${holder}`);
|
|
192
|
-
}
|
|
193
|
-
/**
|
|
194
|
-
* Begin a rollout or a rollback of a stored release, as the exclusive holder. A rollout left
|
|
195
|
-
* `rolling` by an earlier holder ends `diverged` here: its scripts may be on either release, and
|
|
196
|
-
* this rollout reaches all of them. A rollback must name the current release's previous good one.
|
|
197
|
-
*/
|
|
198
|
-
export function beginStoreKindRolloutIn(db, input) {
|
|
199
|
-
assertExclusive(db, input.kind, input.holder, input.nowMs);
|
|
200
|
-
if (!storeKindReleaseIn(db, input.kind, input.sha256)) {
|
|
201
|
-
throw substratError('not_found', `release ${input.sha256} of '${input.kind}' is not stored`);
|
|
202
|
-
}
|
|
203
|
-
db.run(`UPDATE store_kind_rollouts SET state = 'diverged', ended_at = ?, detail = 'its holder stopped before the rollout ended'
|
|
204
|
-
WHERE kind = ? AND state = 'rolling'`, input.at, input.kind);
|
|
205
|
-
const { current, rollbackTarget, unfinishedRollback } = storeKindStateIn(db, input.kind, input.nowMs);
|
|
206
|
-
// A rollback under way to an earlier release blocks every rollout until it ends good. One onto
|
|
207
|
-
// the current release (undoing a diverged rollout) does not: if a script refuses to go below its
|
|
208
|
-
// schema, that rollback can never finish, and going forward is the way out.
|
|
209
|
-
if (input.action === 'rollout' && unfinishedRollback && unfinishedRollback !== current?.sha256) {
|
|
210
|
-
throw substratError('conflict', `a rollback of '${input.kind}' to ${unfinishedRollback} is part way through; post the rollback again to finish it before any rollout`);
|
|
211
|
-
}
|
|
212
|
-
let previousGood;
|
|
213
|
-
if (input.action === 'rollback') {
|
|
214
|
-
if (!current || !rollbackTarget)
|
|
215
|
-
throw substratError('conflict', `'${input.kind}' has no previous good release to roll back to`);
|
|
216
|
-
if (rollbackTarget !== input.sha256) {
|
|
217
|
-
throw substratError('conflict', `a rollback of '${input.kind}' returns to ${rollbackTarget}, not ${input.sha256}`);
|
|
218
|
-
}
|
|
219
|
-
if (input.sha256 === current.sha256) {
|
|
220
|
-
// Undoing a diverged rollout: back onto the current release, whose previous good stays.
|
|
221
|
-
previousGood = current.previousGoodSha256;
|
|
222
|
-
}
|
|
223
|
-
else {
|
|
224
|
-
const [made] = db.all(`SELECT previous_good_sha256 FROM store_kind_rollouts
|
|
225
|
-
WHERE kind = ? AND sha256 = ? AND state = 'good' ORDER BY seq DESC LIMIT 1`, input.kind, input.sha256);
|
|
226
|
-
previousGood = made?.previous_good_sha256 ?? null;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
else {
|
|
230
|
-
// Rolling out the current release again (a resume) keeps where a rollback from it returns to.
|
|
231
|
-
previousGood = current ? (current.sha256 === input.sha256 ? current.previousGoodSha256 : current.sha256) : null;
|
|
232
|
-
}
|
|
233
|
-
const next = Number(db.all('SELECT COALESCE(MAX(seq), 0) + 1 AS next FROM store_kind_rollouts WHERE kind = ?', input.kind)[0].next);
|
|
234
|
-
db.run(`INSERT INTO store_kind_rollouts (${ROLLOUT_COLUMNS}, holder) VALUES (?, ?, ?, ?, ?, ?, 'rolling', ?, ?, NULL, NULL, ?)`, input.kind, next, input.sha256, input.action, current?.sha256 ?? null, previousGood, input.actor, input.at, input.holder);
|
|
235
|
-
return rolloutAt(db, input.kind, next);
|
|
236
|
-
}
|
|
237
|
-
/** End a rollout the caller began, as the exclusive holder. A good one makes its release current. */
|
|
238
|
-
export function finishStoreKindRolloutIn(db, input) {
|
|
239
|
-
assertExclusive(db, input.kind, input.holder, input.nowMs);
|
|
240
|
-
const row = rolloutAt(db, input.kind, input.seq);
|
|
241
|
-
if (!row)
|
|
242
|
-
throw substratError('not_found', `'${input.kind}' has no rollout ${input.seq}`);
|
|
243
|
-
if (row.state !== 'rolling')
|
|
244
|
-
throw substratError('conflict', `rollout ${input.seq} of '${input.kind}' already ended ${row.state}`);
|
|
245
|
-
db.run('UPDATE store_kind_rollouts SET state = ?, ended_at = ?, detail = ? WHERE kind = ? AND seq = ?', input.state, input.at, input.detail, input.kind, input.seq);
|
|
246
|
-
if (input.state === 'good') {
|
|
247
|
-
db.run(`INSERT INTO store_kind_current (kind, sha256, seq) VALUES (?, ?, ?)
|
|
248
|
-
ON CONFLICT (kind) DO UPDATE SET sha256 = excluded.sha256, seq = excluded.seq`, input.kind, row.sha256, input.seq);
|
|
249
|
-
}
|
|
250
|
-
return rolloutAt(db, input.kind, input.seq);
|
|
251
|
-
}
|
|
252
|
-
//# sourceMappingURL=store-kind-releases.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"store-kind-releases.js","sourceRoot":"","sources":["../src/store-kind-releases.ts"],"names":[],"mappings":"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"}
|