@chkit/plugin-backfill 0.1.0-beta.19 → 0.1.0-beta.20
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/async-backfill.d.ts +64 -0
- package/dist/async-backfill.d.ts.map +1 -0
- package/dist/async-backfill.js +251 -0
- package/dist/async-backfill.js.map +1 -0
- package/dist/check.d.ts +9 -0
- package/dist/check.d.ts.map +1 -0
- package/dist/check.js +79 -0
- package/dist/check.js.map +1 -0
- package/dist/chunking/analyze.d.ts +38 -0
- package/dist/chunking/analyze.d.ts.map +1 -0
- package/dist/chunking/analyze.js +76 -0
- package/dist/chunking/analyze.js.map +1 -0
- package/dist/chunking/build.d.ts +11 -0
- package/dist/chunking/build.d.ts.map +1 -0
- package/dist/chunking/build.js +51 -0
- package/dist/chunking/build.js.map +1 -0
- package/dist/chunking/introspect.d.ts +34 -0
- package/dist/chunking/introspect.d.ts.map +1 -0
- package/dist/chunking/introspect.js +96 -0
- package/dist/chunking/introspect.js.map +1 -0
- package/dist/chunking/splitter.d.ts +20 -0
- package/dist/chunking/splitter.d.ts.map +1 -0
- package/dist/chunking/splitter.js +76 -0
- package/dist/chunking/splitter.js.map +1 -0
- package/dist/chunking/sql.d.ts +12 -0
- package/dist/chunking/sql.d.ts.map +1 -0
- package/dist/chunking/sql.js +221 -0
- package/dist/chunking/sql.js.map +1 -0
- package/dist/chunking/types.d.ts +29 -0
- package/dist/chunking/types.d.ts.map +1 -0
- package/dist/chunking/types.js +2 -0
- package/dist/chunking/types.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/options.d.ts +151 -4
- package/dist/options.d.ts.map +1 -1
- package/dist/options.js +160 -143
- package/dist/options.js.map +1 -1
- package/dist/payload.d.ts +6 -20
- package/dist/payload.d.ts.map +1 -1
- package/dist/payload.js +7 -21
- package/dist/payload.js.map +1 -1
- package/dist/planner.d.ts +4 -31
- package/dist/planner.d.ts.map +1 -1
- package/dist/planner.js +85 -336
- package/dist/planner.js.map +1 -1
- package/dist/plugin.d.ts +4 -3
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +234 -228
- package/dist/plugin.js.map +1 -1
- package/dist/queries.d.ts +21 -0
- package/dist/queries.d.ts.map +1 -0
- package/dist/queries.js +113 -0
- package/dist/queries.js.map +1 -0
- package/dist/state.d.ts +7 -31
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +33 -132
- package/dist/state.js.map +1 -1
- package/dist/types.d.ts +32 -124
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -3
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ResolvedChxConfig } from '@chkit/core';
|
|
2
|
+
import type { BackfillDoctorReport, BackfillStatusSummary } from './types.js';
|
|
3
|
+
export declare function getBackfillStatus(input: {
|
|
4
|
+
planId: string;
|
|
5
|
+
configPath: string;
|
|
6
|
+
config: Pick<ResolvedChxConfig, 'metaDir'>;
|
|
7
|
+
stateDir?: string;
|
|
8
|
+
}): Promise<BackfillStatusSummary>;
|
|
9
|
+
export declare function cancelBackfillRun(input: {
|
|
10
|
+
planId: string;
|
|
11
|
+
configPath: string;
|
|
12
|
+
config: Pick<ResolvedChxConfig, 'metaDir'>;
|
|
13
|
+
stateDir?: string;
|
|
14
|
+
}): Promise<BackfillStatusSummary>;
|
|
15
|
+
export declare function getBackfillDoctorReport(input: {
|
|
16
|
+
planId: string;
|
|
17
|
+
configPath: string;
|
|
18
|
+
config: Pick<ResolvedChxConfig, 'metaDir'>;
|
|
19
|
+
stateDir?: string;
|
|
20
|
+
}): Promise<BackfillDoctorReport>;
|
|
21
|
+
//# sourceMappingURL=queries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../src/queries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAWpD,OAAO,KAAK,EACV,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,YAAY,CAAA;AAEnB,wBAAsB,iBAAiB,CAAC,KAAK,EAAE;IAC7C,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAA;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA8BjC;AAED,wBAAsB,iBAAiB,CAAC,KAAK,EAAE;IAC7C,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAA;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA6BjC;AAED,wBAAsB,uBAAuB,CAAC,KAAK,EAAE;IACnD,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAA;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAgEhC"}
|
package/dist/queries.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { BackfillConfigError } from './errors.js';
|
|
2
|
+
import { backfillPaths, nowIso, readPlan, readRun, summarizeRunStatus, writeJson, } from './state.js';
|
|
3
|
+
export async function getBackfillStatus(input) {
|
|
4
|
+
const { plan, stateDir } = await readPlan({
|
|
5
|
+
planId: input.planId,
|
|
6
|
+
configPath: input.configPath,
|
|
7
|
+
config: input.config,
|
|
8
|
+
stateDir: input.stateDir,
|
|
9
|
+
});
|
|
10
|
+
const paths = backfillPaths(stateDir, plan.planId);
|
|
11
|
+
const run = await readRun(paths.runPath);
|
|
12
|
+
if (!run) {
|
|
13
|
+
return {
|
|
14
|
+
planId: plan.planId,
|
|
15
|
+
target: plan.target,
|
|
16
|
+
status: 'planned',
|
|
17
|
+
totals: {
|
|
18
|
+
total: plan.chunks.length,
|
|
19
|
+
pending: plan.chunks.length,
|
|
20
|
+
submitted: 0,
|
|
21
|
+
running: 0,
|
|
22
|
+
done: 0,
|
|
23
|
+
failed: 0,
|
|
24
|
+
},
|
|
25
|
+
rowsWritten: 0,
|
|
26
|
+
updatedAt: plan.createdAt,
|
|
27
|
+
runPath: paths.runPath,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
return summarizeRunStatus(run, paths.runPath, plan);
|
|
31
|
+
}
|
|
32
|
+
export async function cancelBackfillRun(input) {
|
|
33
|
+
const { plan, stateDir } = await readPlan({
|
|
34
|
+
planId: input.planId,
|
|
35
|
+
configPath: input.configPath,
|
|
36
|
+
config: input.config,
|
|
37
|
+
stateDir: input.stateDir,
|
|
38
|
+
});
|
|
39
|
+
const paths = backfillPaths(stateDir, plan.planId);
|
|
40
|
+
const run = await readRun(paths.runPath);
|
|
41
|
+
if (!run) {
|
|
42
|
+
throw new BackfillConfigError(`Run state not found for plan ${plan.planId}. Start with backfill run before cancel.`);
|
|
43
|
+
}
|
|
44
|
+
if (run.status === 'completed') {
|
|
45
|
+
throw new BackfillConfigError(`Run already completed for plan ${plan.planId}; cannot cancel.`);
|
|
46
|
+
}
|
|
47
|
+
if (run.status === 'cancelled') {
|
|
48
|
+
return summarizeRunStatus(run, paths.runPath, plan);
|
|
49
|
+
}
|
|
50
|
+
run.status = 'cancelled';
|
|
51
|
+
run.completedAt = nowIso();
|
|
52
|
+
run.lastError = 'Cancelled by operator';
|
|
53
|
+
await writeJson(paths.runPath, run);
|
|
54
|
+
return summarizeRunStatus(run, paths.runPath, plan);
|
|
55
|
+
}
|
|
56
|
+
export async function getBackfillDoctorReport(input) {
|
|
57
|
+
const { plan, stateDir } = await readPlan({
|
|
58
|
+
planId: input.planId,
|
|
59
|
+
configPath: input.configPath,
|
|
60
|
+
config: input.config,
|
|
61
|
+
stateDir: input.stateDir,
|
|
62
|
+
});
|
|
63
|
+
const paths = backfillPaths(stateDir, plan.planId);
|
|
64
|
+
const run = await readRun(paths.runPath);
|
|
65
|
+
const status = run
|
|
66
|
+
? summarizeRunStatus(run, paths.runPath, plan)
|
|
67
|
+
: {
|
|
68
|
+
planId: plan.planId,
|
|
69
|
+
target: plan.target,
|
|
70
|
+
status: 'planned',
|
|
71
|
+
totals: { total: plan.chunks.length, pending: plan.chunks.length, submitted: 0, running: 0, done: 0, failed: 0 },
|
|
72
|
+
rowsWritten: 0,
|
|
73
|
+
updatedAt: plan.createdAt,
|
|
74
|
+
runPath: paths.runPath,
|
|
75
|
+
};
|
|
76
|
+
const issueCodes = [];
|
|
77
|
+
const recommendations = [];
|
|
78
|
+
const failedChunkIds = [];
|
|
79
|
+
if (run) {
|
|
80
|
+
for (const [chunkId, state] of Object.entries(run.progress)) {
|
|
81
|
+
if (state.status === 'failed')
|
|
82
|
+
failedChunkIds.push(chunkId);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (status.status === 'planned') {
|
|
86
|
+
issueCodes.push('backfill_plan_missing');
|
|
87
|
+
recommendations.push(`Run: chkit plugin backfill run --plan-id ${status.planId}`);
|
|
88
|
+
}
|
|
89
|
+
if (status.status === 'failed') {
|
|
90
|
+
issueCodes.push('backfill_chunk_failed_retry_exhausted');
|
|
91
|
+
recommendations.push(`Inspect status: chkit plugin backfill status --plan-id ${status.planId}`);
|
|
92
|
+
recommendations.push(`Retry failed chunks: chkit plugin backfill resume --plan-id ${status.planId} --replay-failed`);
|
|
93
|
+
}
|
|
94
|
+
if (status.status === 'cancelled') {
|
|
95
|
+
issueCodes.push('backfill_required_pending');
|
|
96
|
+
recommendations.push(`Resume execution: chkit plugin backfill resume --plan-id ${status.planId} --replay-failed`);
|
|
97
|
+
}
|
|
98
|
+
if (status.status === 'running') {
|
|
99
|
+
issueCodes.push('backfill_required_pending');
|
|
100
|
+
recommendations.push(`Monitor progress: chkit plugin backfill status --plan-id ${status.planId}`);
|
|
101
|
+
}
|
|
102
|
+
if (issueCodes.length === 0) {
|
|
103
|
+
recommendations.push('No remediation required.');
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
planId: status.planId,
|
|
107
|
+
status: status.status,
|
|
108
|
+
issueCodes,
|
|
109
|
+
recommendations,
|
|
110
|
+
failedChunkIds,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=queries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.js","sourceRoot":"","sources":["../src/queries.ts"],"names":[],"mappings":"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"}
|
package/dist/state.d.ts
CHANGED
|
@@ -1,54 +1,30 @@
|
|
|
1
1
|
import type { ResolvedChxConfig } from '@chkit/core';
|
|
2
|
-
import type { BackfillEnvironment,
|
|
2
|
+
import type { BackfillEnvironment, BackfillPathSet, BackfillPlanState, BackfillRunState, BackfillStatusSummary, ReadPlanOutput } from './types.js';
|
|
3
3
|
export declare function hashId(input: string): string;
|
|
4
4
|
export declare function nowIso(): string;
|
|
5
|
-
export declare function
|
|
6
|
-
export declare function computeCompatibilityToken(input: {
|
|
7
|
-
plan: BackfillPlanState;
|
|
8
|
-
options: NormalizedBackfillPluginOptions;
|
|
9
|
-
}): string;
|
|
10
|
-
export declare function planIdentity(target: string, from: string, to: string, chunkHours: number, timeColumn: string, envFingerprint?: string): string;
|
|
5
|
+
export declare function randomPlanId(): string;
|
|
11
6
|
export declare function computeEnvironmentFingerprint(clickhouse: {
|
|
12
7
|
url: string;
|
|
13
|
-
database
|
|
8
|
+
database?: string;
|
|
14
9
|
} | undefined): BackfillEnvironment | undefined;
|
|
15
10
|
export declare function ensureEnvironmentMatch(input: {
|
|
16
11
|
plan: BackfillPlanState;
|
|
17
12
|
clickhouse: {
|
|
18
13
|
url: string;
|
|
19
|
-
database
|
|
14
|
+
database?: string;
|
|
20
15
|
} | undefined;
|
|
21
16
|
forceEnvironment: boolean;
|
|
22
17
|
}): void;
|
|
23
|
-
export declare function computeBackfillStateDir(config: Pick<ResolvedChxConfig, 'metaDir'>, configPath: string,
|
|
18
|
+
export declare function computeBackfillStateDir(config: Pick<ResolvedChxConfig, 'metaDir'>, configPath: string, stateDir?: string): string;
|
|
24
19
|
export declare function backfillPaths(stateDir: string, planId: string): BackfillPathSet;
|
|
25
20
|
export declare function writeJson(filePath: string, value: unknown): Promise<void>;
|
|
26
|
-
export declare function readExistingPlan(planPath: string): Promise<BackfillPlanState | null>;
|
|
27
21
|
export declare function readPlan(input: {
|
|
28
22
|
planId: string;
|
|
29
23
|
configPath: string;
|
|
30
24
|
config: Pick<ResolvedChxConfig, 'metaDir'>;
|
|
31
|
-
|
|
25
|
+
stateDir?: string;
|
|
32
26
|
}): Promise<ReadPlanOutput>;
|
|
33
27
|
export declare function readRun(runPath: string): Promise<BackfillRunState | null>;
|
|
34
|
-
export declare function createRunState(input: {
|
|
35
|
-
plan: BackfillPlanState;
|
|
36
|
-
options: NormalizedBackfillPluginOptions;
|
|
37
|
-
execution: BackfillExecutionOptions;
|
|
38
|
-
}): BackfillRunState;
|
|
39
|
-
export declare function collectActiveRunTargets(runsDir: string): Promise<Map<string, string>>;
|
|
40
28
|
export declare function listPlanIds(plansDir: string): Promise<string[]>;
|
|
41
|
-
export declare function summarizeRunStatus(run: BackfillRunState, runPath: string,
|
|
42
|
-
export declare function persistRunAndEvent(input: {
|
|
43
|
-
run: BackfillRunState;
|
|
44
|
-
runPath: string;
|
|
45
|
-
eventPath: string;
|
|
46
|
-
event: Record<string, unknown>;
|
|
47
|
-
}): Promise<void>;
|
|
48
|
-
export declare function ensureRunCompatibility(input: {
|
|
49
|
-
run: BackfillRunState;
|
|
50
|
-
plan: BackfillPlanState;
|
|
51
|
-
options: NormalizedBackfillPluginOptions;
|
|
52
|
-
forceCompatibility: boolean;
|
|
53
|
-
}): void;
|
|
29
|
+
export declare function summarizeRunStatus(run: BackfillRunState, runPath: string, plan: BackfillPlanState): BackfillStatusSummary;
|
|
54
30
|
//# sourceMappingURL=state.d.ts.map
|
package/dist/state.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAGpD,OAAO,KAAK,EACV,mBAAmB,EACnB,
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAGpD,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,cAAc,EACf,MAAM,YAAY,CAAA;AAEnB,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,wBAAgB,MAAM,IAAI,MAAM,CAE/B;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,6BAA6B,CAC3C,UAAU,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,GACzD,mBAAmB,GAAG,SAAS,CASjC;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,IAAI,EAAE,iBAAiB,CAAA;IACvB,UAAU,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAA;IAC1D,gBAAgB,EAAE,OAAO,CAAA;CAC1B,GAAG,IAAI,CAeP;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,EAC1C,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAKR;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,eAAe,CAU/E;AAOD,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/E;AAED,wBAAsB,QAAQ,CAAC,KAAK,EAAE;IACpC,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAA;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,GAAG,OAAO,CAAC,cAAc,CAAC,CAY1B;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAE/E;AAED,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAOrE;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,iBAAiB,GACtB,qBAAqB,CAmCvB"}
|
package/dist/state.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto';
|
|
1
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
2
2
|
import { existsSync } from 'node:fs';
|
|
3
|
-
import {
|
|
3
|
+
import { mkdir, readFile, readdir, writeFile } from 'node:fs/promises';
|
|
4
4
|
import { dirname, join, resolve } from 'node:path';
|
|
5
5
|
import { BackfillConfigError } from './errors.js';
|
|
6
6
|
export function hashId(input) {
|
|
@@ -9,45 +9,18 @@ export function hashId(input) {
|
|
|
9
9
|
export function nowIso() {
|
|
10
10
|
return new Date().toISOString();
|
|
11
11
|
}
|
|
12
|
-
export function
|
|
13
|
-
|
|
14
|
-
return JSON.stringify(value);
|
|
15
|
-
}
|
|
16
|
-
if (Array.isArray(value)) {
|
|
17
|
-
return `[${value.map((item) => stableSerialize(item)).join(',')}]`;
|
|
18
|
-
}
|
|
19
|
-
const entries = Object.entries(value).sort(([a], [b]) => a.localeCompare(b));
|
|
20
|
-
return `{${entries
|
|
21
|
-
.map(([key, item]) => `${JSON.stringify(key)}:${stableSerialize(item)}`)
|
|
22
|
-
.join(',')}}`;
|
|
23
|
-
}
|
|
24
|
-
export function computeCompatibilityToken(input) {
|
|
25
|
-
// Exclude retryDelayMs — it's a runtime behavior setting that doesn't
|
|
26
|
-
// affect data integrity and shouldn't break compatibility on upgrade.
|
|
27
|
-
const { retryDelayMs: _, ...compatDefaults } = input.options.defaults;
|
|
28
|
-
return hashId(stableSerialize({
|
|
29
|
-
planId: input.plan.planId,
|
|
30
|
-
target: input.plan.target,
|
|
31
|
-
from: input.plan.from,
|
|
32
|
-
to: input.plan.to,
|
|
33
|
-
planOptions: input.plan.options,
|
|
34
|
-
runtimeDefaults: compatDefaults,
|
|
35
|
-
runtimePolicy: input.options.policy,
|
|
36
|
-
runtimeLimits: input.options.limits,
|
|
37
|
-
}));
|
|
38
|
-
}
|
|
39
|
-
export function planIdentity(target, from, to, chunkHours, timeColumn, envFingerprint) {
|
|
40
|
-
const base = `${target}|${from}|${to}|${chunkHours}|${timeColumn}`;
|
|
41
|
-
return envFingerprint ? `${base}|${envFingerprint}` : base;
|
|
12
|
+
export function randomPlanId() {
|
|
13
|
+
return randomBytes(8).toString('hex');
|
|
42
14
|
}
|
|
43
15
|
export function computeEnvironmentFingerprint(clickhouse) {
|
|
44
16
|
if (!clickhouse)
|
|
45
17
|
return undefined;
|
|
18
|
+
const database = clickhouse.database ?? 'default';
|
|
46
19
|
const origin = new URL(clickhouse.url).origin;
|
|
47
20
|
return {
|
|
48
|
-
fingerprint: hashId(`${origin}|${
|
|
21
|
+
fingerprint: hashId(`${origin}|${database}`).slice(0, 16),
|
|
49
22
|
url: origin,
|
|
50
|
-
database
|
|
23
|
+
database,
|
|
51
24
|
};
|
|
52
25
|
}
|
|
53
26
|
export function ensureEnvironmentMatch(input) {
|
|
@@ -67,24 +40,21 @@ export function ensureEnvironmentMatch(input) {
|
|
|
67
40
|
`but current config points to ${current.url} (database: ${current.database}). ` +
|
|
68
41
|
`Retry with --force-environment to override.`);
|
|
69
42
|
}
|
|
70
|
-
export function computeBackfillStateDir(config, configPath,
|
|
71
|
-
if (
|
|
72
|
-
return resolve(dirname(configPath),
|
|
43
|
+
export function computeBackfillStateDir(config, configPath, stateDir) {
|
|
44
|
+
if (stateDir && stateDir.length > 0) {
|
|
45
|
+
return resolve(dirname(configPath), stateDir);
|
|
73
46
|
}
|
|
74
47
|
return resolve(dirname(configPath), config.metaDir, 'backfill');
|
|
75
48
|
}
|
|
76
49
|
export function backfillPaths(stateDir, planId) {
|
|
77
50
|
const plansDir = join(stateDir, 'plans');
|
|
78
51
|
const runsDir = join(stateDir, 'runs');
|
|
79
|
-
const eventsDir = join(stateDir, 'events');
|
|
80
52
|
return {
|
|
81
53
|
stateDir,
|
|
82
54
|
plansDir,
|
|
83
55
|
runsDir,
|
|
84
|
-
eventsDir,
|
|
85
56
|
planPath: join(plansDir, `${planId}.json`),
|
|
86
57
|
runPath: join(runsDir, `${planId}.json`),
|
|
87
|
-
eventPath: join(eventsDir, `${planId}.ndjson`),
|
|
88
58
|
};
|
|
89
59
|
}
|
|
90
60
|
async function readJsonMaybe(filePath) {
|
|
@@ -96,15 +66,8 @@ export async function writeJson(filePath, value) {
|
|
|
96
66
|
await mkdir(dirname(filePath), { recursive: true });
|
|
97
67
|
await writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
|
|
98
68
|
}
|
|
99
|
-
async function appendEvent(eventPath, event) {
|
|
100
|
-
await mkdir(dirname(eventPath), { recursive: true });
|
|
101
|
-
await appendFile(eventPath, `${JSON.stringify({ at: nowIso(), ...event })}\n`, 'utf8');
|
|
102
|
-
}
|
|
103
|
-
export async function readExistingPlan(planPath) {
|
|
104
|
-
return readJsonMaybe(planPath);
|
|
105
|
-
}
|
|
106
69
|
export async function readPlan(input) {
|
|
107
|
-
const stateDir = computeBackfillStateDir(input.config, input.configPath, input.
|
|
70
|
+
const stateDir = computeBackfillStateDir(input.config, input.configPath, input.stateDir);
|
|
108
71
|
const paths = backfillPaths(stateDir, input.planId);
|
|
109
72
|
const plan = await readJsonMaybe(paths.planPath);
|
|
110
73
|
if (!plan) {
|
|
@@ -119,51 +82,6 @@ export async function readPlan(input) {
|
|
|
119
82
|
export async function readRun(runPath) {
|
|
120
83
|
return readJsonMaybe(runPath);
|
|
121
84
|
}
|
|
122
|
-
export function createRunState(input) {
|
|
123
|
-
const startedAt = nowIso();
|
|
124
|
-
return {
|
|
125
|
-
planId: input.plan.planId,
|
|
126
|
-
target: input.plan.target,
|
|
127
|
-
status: 'planned',
|
|
128
|
-
createdAt: startedAt,
|
|
129
|
-
startedAt,
|
|
130
|
-
updatedAt: startedAt,
|
|
131
|
-
replayDone: input.execution.replayDone ?? false,
|
|
132
|
-
replayFailed: input.execution.replayFailed ?? false,
|
|
133
|
-
compatibilityToken: computeCompatibilityToken({
|
|
134
|
-
plan: input.plan,
|
|
135
|
-
options: input.options,
|
|
136
|
-
}),
|
|
137
|
-
options: input.plan.options,
|
|
138
|
-
chunks: input.plan.chunks.map((chunk) => ({
|
|
139
|
-
id: chunk.id,
|
|
140
|
-
from: chunk.from,
|
|
141
|
-
to: chunk.to,
|
|
142
|
-
status: 'pending',
|
|
143
|
-
attempts: 0,
|
|
144
|
-
idempotencyToken: chunk.idempotencyToken,
|
|
145
|
-
sqlTemplate: chunk.sqlTemplate,
|
|
146
|
-
})),
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
export async function collectActiveRunTargets(runsDir) {
|
|
150
|
-
const active = new Map();
|
|
151
|
-
if (!existsSync(runsDir))
|
|
152
|
-
return active;
|
|
153
|
-
const entries = await readdir(runsDir, { withFileTypes: true });
|
|
154
|
-
for (const entry of entries) {
|
|
155
|
-
if (!entry.isFile() || !entry.name.endsWith('.json'))
|
|
156
|
-
continue;
|
|
157
|
-
const file = join(runsDir, entry.name);
|
|
158
|
-
const run = await readRun(file);
|
|
159
|
-
if (!run)
|
|
160
|
-
continue;
|
|
161
|
-
if (run.status !== 'running')
|
|
162
|
-
continue;
|
|
163
|
-
active.set(run.planId, run.target);
|
|
164
|
-
}
|
|
165
|
-
return active;
|
|
166
|
-
}
|
|
167
85
|
export async function listPlanIds(plansDir) {
|
|
168
86
|
if (!existsSync(plansDir))
|
|
169
87
|
return [];
|
|
@@ -173,60 +91,43 @@ export async function listPlanIds(plansDir) {
|
|
|
173
91
|
.map((entry) => entry.name.replace(/\.json$/, ''))
|
|
174
92
|
.sort();
|
|
175
93
|
}
|
|
176
|
-
export function summarizeRunStatus(run, runPath,
|
|
177
|
-
const
|
|
178
|
-
total:
|
|
94
|
+
export function summarizeRunStatus(run, runPath, plan) {
|
|
95
|
+
const totals = {
|
|
96
|
+
total: plan.chunks.length,
|
|
179
97
|
pending: 0,
|
|
98
|
+
submitted: 0,
|
|
180
99
|
running: 0,
|
|
181
100
|
done: 0,
|
|
182
101
|
failed: 0,
|
|
183
|
-
skipped: 0,
|
|
184
102
|
};
|
|
185
|
-
let attempts = 0;
|
|
186
103
|
let rowsWritten = 0;
|
|
187
|
-
for (const chunk of
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
if (
|
|
195
|
-
|
|
196
|
-
if (
|
|
197
|
-
|
|
198
|
-
if (
|
|
199
|
-
|
|
104
|
+
for (const chunk of plan.chunks) {
|
|
105
|
+
const state = run.progress[chunk.id];
|
|
106
|
+
if (!state) {
|
|
107
|
+
totals.pending += 1;
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
rowsWritten += state.writtenRows ?? 0;
|
|
111
|
+
if (state.status === 'pending')
|
|
112
|
+
totals.pending += 1;
|
|
113
|
+
else if (state.status === 'submitted')
|
|
114
|
+
totals.submitted += 1;
|
|
115
|
+
else if (state.status === 'running')
|
|
116
|
+
totals.running += 1;
|
|
117
|
+
else if (state.status === 'done')
|
|
118
|
+
totals.done += 1;
|
|
119
|
+
else if (state.status === 'failed')
|
|
120
|
+
totals.failed += 1;
|
|
200
121
|
}
|
|
201
122
|
return {
|
|
202
123
|
planId: run.planId,
|
|
203
124
|
target: run.target,
|
|
204
125
|
status: run.status,
|
|
205
|
-
totals
|
|
206
|
-
attempts,
|
|
126
|
+
totals,
|
|
207
127
|
rowsWritten,
|
|
208
128
|
updatedAt: run.updatedAt,
|
|
209
129
|
runPath,
|
|
210
|
-
eventPath,
|
|
211
130
|
lastError: run.lastError,
|
|
212
131
|
};
|
|
213
132
|
}
|
|
214
|
-
export async function persistRunAndEvent(input) {
|
|
215
|
-
input.run.updatedAt = nowIso();
|
|
216
|
-
await writeJson(input.runPath, input.run);
|
|
217
|
-
await appendEvent(input.eventPath, input.event);
|
|
218
|
-
}
|
|
219
|
-
export function ensureRunCompatibility(input) {
|
|
220
|
-
if (!input.run.compatibilityToken)
|
|
221
|
-
return;
|
|
222
|
-
const expected = computeCompatibilityToken({
|
|
223
|
-
plan: input.plan,
|
|
224
|
-
options: input.options,
|
|
225
|
-
});
|
|
226
|
-
if (input.run.compatibilityToken === expected)
|
|
227
|
-
return;
|
|
228
|
-
if (input.forceCompatibility)
|
|
229
|
-
return;
|
|
230
|
-
throw new BackfillConfigError(`Run compatibility check failed for plan ${input.plan.planId}. Runtime options changed since last checkpoint. Retry with --force-compatibility to acknowledge override.`);
|
|
231
|
-
}
|
|
232
133
|
//# sourceMappingURL=state.js.map
|
package/dist/state.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACtE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAIlD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAUjD,MAAM,UAAU,MAAM,CAAC,KAAa;IAClC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AACzD,CAAC;AAED,MAAM,UAAU,MAAM;IACpB,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;AACjC,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;AACvC,CAAC;AAED,MAAM,UAAU,6BAA6B,CAC3C,UAA0D;IAE1D,IAAI,CAAC,UAAU;QAAE,OAAO,SAAS,CAAA;IACjC,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,IAAI,SAAS,CAAA;IACjD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,MAAM,CAAA;IAC7C,OAAO;QACL,WAAW,EAAE,MAAM,CAAC,GAAG,MAAM,IAAI,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;QACzD,GAAG,EAAE,MAAM;QACX,QAAQ;KACT,CAAA;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAItC;IACC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW;QAAE,OAAM;IACnC,IAAI,CAAC,KAAK,CAAC,UAAU;QAAE,OAAM;IAE7B,MAAM,OAAO,GAAG,6BAA6B,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;IAC/D,IAAI,CAAC,OAAO;QAAE,OAAM;IACpB,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,KAAK,OAAO,CAAC,WAAW;QAAE,OAAM;IACtE,IAAI,KAAK,CAAC,gBAAgB;QAAE,OAAM;IAElC,MAAM,IAAI,mBAAmB,CAC3B,iCAAiC,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI;QACpD,wBAAwB,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,eAAe,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,KAAK;QACrG,gCAAgC,OAAO,CAAC,GAAG,eAAe,OAAO,CAAC,QAAQ,KAAK;QAC/E,6CAA6C,CAChD,CAAA;AACH,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,MAA0C,EAC1C,UAAkB,EAClB,QAAiB;IAEjB,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,OAAO,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,CAAA;IAC/C,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;AACjE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,QAAgB,EAAE,MAAc;IAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IACxC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IACtC,OAAO;QACL,QAAQ;QACR,QAAQ;QACR,OAAO;QACP,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,GAAG,MAAM,OAAO,CAAC;QAC1C,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,MAAM,OAAO,CAAC;KACzC,CAAA;AACH,CAAC;AAED,KAAK,UAAU,aAAa,CAAI,QAAgB;IAC9C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAA;IACtC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAM,CAAA;AAC1D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,QAAgB,EAAE,KAAc;IAC9D,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACnD,MAAM,SAAS,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;AAC1E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,KAK9B;IACC,MAAM,QAAQ,GAAG,uBAAuB,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;IACxF,MAAM,KAAK,GAAG,aAAa,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IACnD,MAAM,IAAI,GAAG,MAAM,aAAa,CAAoB,KAAK,CAAC,QAAQ,CAAC,CAAA;IACnE,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,mBAAmB,CAAC,4BAA4B,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;IAC7E,CAAC;IACD,OAAO;QACL,IAAI;QACJ,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,QAAQ;KACT,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAe;IAC3C,OAAO,aAAa,CAAmB,OAAO,CAAC,CAAA;AACjD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAgB;IAChD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,CAAA;IACpC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,QAAQ,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;IAChE,OAAO,OAAO;SACX,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;SACjE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;SACjD,IAAI,EAAE,CAAA;AACX,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,GAAqB,EACrB,OAAe,EACf,IAAuB;IAEvB,MAAM,MAAM,GAAG;QACb,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;QACzB,OAAO,EAAE,CAAC;QACV,SAAS,EAAE,CAAC;QACZ,OAAO,EAAE,CAAC;QACV,IAAI,EAAE,CAAC;QACP,MAAM,EAAE,CAAC;KACV,CAAA;IAED,IAAI,WAAW,GAAG,CAAC,CAAA;IACnB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QACpC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,CAAC,OAAO,IAAI,CAAC,CAAA;YACnB,SAAQ;QACV,CAAC;QACD,WAAW,IAAI,KAAK,CAAC,WAAW,IAAI,CAAC,CAAA;QACrC,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;YAAE,MAAM,CAAC,OAAO,IAAI,CAAC,CAAA;aAC9C,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW;YAAE,MAAM,CAAC,SAAS,IAAI,CAAC,CAAA;aACvD,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;YAAE,MAAM,CAAC,OAAO,IAAI,CAAC,CAAA;aACnD,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM;YAAE,MAAM,CAAC,IAAI,IAAI,CAAC,CAAA;aAC7C,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ;YAAE,MAAM,CAAC,MAAM,IAAI,CAAC,CAAA;IACxD,CAAC;IAED,OAAO;QACL,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,MAAM;QACN,WAAW;QACX,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,OAAO;QACP,SAAS,EAAE,GAAG,CAAC,SAAS;KACzB,CAAA;AACH,CAAC"}
|