@harperfast/harper 5.1.0-beta.3 → 5.1.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/bin/copyDb.ts +16 -3
- package/dist/bin/copyDb.js +16 -3
- package/dist/bin/copyDb.js.map +1 -1
- package/dist/resources/Table.js +43 -4
- package/dist/resources/Table.js.map +1 -1
- package/dist/resources/databases.js +135 -41
- package/dist/resources/databases.js.map +1 -1
- package/dist/resources/graphql.js +3 -0
- package/dist/resources/graphql.js.map +1 -1
- package/dist/resources/replayLogs.d.ts +1 -0
- package/dist/resources/replayLogs.js +100 -40
- package/dist/resources/replayLogs.js.map +1 -1
- package/dist/resources/replayLogsGuards.d.ts +25 -8
- package/dist/resources/replayLogsGuards.js +50 -10
- package/dist/resources/replayLogsGuards.js.map +1 -1
- package/dist/server/nodeName.js +9 -3
- package/dist/server/nodeName.js.map +1 -1
- package/dist/server/operationsServer.js +20 -0
- package/dist/server/operationsServer.js.map +1 -1
- package/dist/utility/install/installer.js +12 -6
- package/dist/utility/install/installer.js.map +1 -1
- package/package.json +3 -3
- package/resources/Table.ts +41 -4
- package/resources/databases.ts +134 -42
- package/resources/graphql.ts +3 -0
- package/resources/replayLogs.ts +114 -42
- package/resources/replayLogsGuards.ts +58 -9
- package/server/nodeName.ts +9 -3
- package/server/operationsServer.ts +17 -0
- package/studio/web/assets/{Chat-BdFickL8.js → Chat-DMBW4pI2.js} +2 -2
- package/studio/web/assets/{Chat-BdFickL8.js.map → Chat-DMBW4pI2.js.map} +1 -1
- package/studio/web/assets/{FloatingChat-CaAoco8I.js → FloatingChat-DTmhPsrm.js} +4 -4
- package/studio/web/assets/{FloatingChat-CaAoco8I.js.map → FloatingChat-DTmhPsrm.js.map} +1 -1
- package/studio/web/assets/{applications-C3y3xwyG.js → applications-CigxJarn.js} +2 -2
- package/studio/web/assets/{applications-C3y3xwyG.js.map → applications-CigxJarn.js.map} +1 -1
- package/studio/web/assets/{index-Cd3Zh3nK.js → index-oRZw5GW3.js} +6 -6
- package/studio/web/assets/index-oRZw5GW3.js.map +1 -0
- package/studio/web/assets/{index.lazy-0hLbh5Fo.js → index.lazy-DY3VcR86.js} +4 -4
- package/studio/web/assets/{index.lazy-0hLbh5Fo.js.map → index.lazy-DY3VcR86.js.map} +1 -1
- package/studio/web/assets/{profile-CwBWGuVt.js → profile-DiV60L50.js} +2 -2
- package/studio/web/assets/{profile-CwBWGuVt.js.map → profile-DiV60L50.js.map} +1 -1
- package/studio/web/assets/{setComponentFile-Dhrmd8eR.js → setComponentFile-Bz6WI4jy.js} +2 -2
- package/studio/web/assets/{setComponentFile-Dhrmd8eR.js.map → setComponentFile-Bz6WI4jy.js.map} +1 -1
- package/studio/web/assets/{status-Bykq6QcD.js → status-fW6PBpPM.js} +2 -2
- package/studio/web/assets/{status-Bykq6QcD.js.map → status-fW6PBpPM.js.map} +1 -1
- package/studio/web/assets/{swagger-ui-react-CF94s29D.js → swagger-ui-react-DRYf7G3J.js} +2 -2
- package/studio/web/assets/{swagger-ui-react-CF94s29D.js.map → swagger-ui-react-DRYf7G3J.js.map} +1 -1
- package/studio/web/assets/{useEntityRestURL-D7vuaG2W.js → useEntityRestURL-14jWKu9J.js} +2 -2
- package/studio/web/assets/{useEntityRestURL-D7vuaG2W.js.map → useEntityRestURL-14jWKu9J.js.map} +1 -1
- package/studio/web/index.html +1 -1
- package/utility/install/installer.ts +12 -5
- package/studio/web/assets/index-Cd3Zh3nK.js.map +0 -1
|
@@ -33,8 +33,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.structuresWouldShrink = structuresWouldShrink;
|
|
36
37
|
exports.replayLogs = replayLogs;
|
|
37
|
-
const rocksdb_js_1 = require("@harperfast/rocksdb-js");
|
|
38
38
|
const logger = __importStar(require("../utility/logging/harper_logger.js"));
|
|
39
39
|
const DatabaseTransaction_ts_1 = require("./DatabaseTransaction.js");
|
|
40
40
|
const node_worker_threads_1 = require("node:worker_threads");
|
|
@@ -42,6 +42,25 @@ const RequestTarget_ts_1 = require("./RequestTarget.js");
|
|
|
42
42
|
const replayLogsGuards_ts_1 = require("./replayLogsGuards.js");
|
|
43
43
|
const auditStore_ts_1 = require("./auditStore.js");
|
|
44
44
|
let warnedReplayHappening = false;
|
|
45
|
+
// True when `updated` would DROP shared structures relative to `existing` — for either the classic
|
|
46
|
+
// array form or the {named, typed} Map form, and for a form change between the two. Shared
|
|
47
|
+
// structures only ever grow (ids are stable and append-only), so a shorter replayed buffer is a
|
|
48
|
+
// stale/older entry. Used to refuse a downgrade of the durable structures dictionary during replay:
|
|
49
|
+
// since the composite key is the one RecordEncoder.getStructures reads, overwriting it with fewer
|
|
50
|
+
// structures would drop ids the decoder still needs and make existing records decode to null. This
|
|
51
|
+
// mirrors saveStructures' compatibility reject (RecordEncoder.ts). See harper-pro#362.
|
|
52
|
+
function structuresWouldShrink(existing, updated) {
|
|
53
|
+
if (Array.isArray(existing)) {
|
|
54
|
+
return !Array.isArray(updated) || updated.length < existing.length;
|
|
55
|
+
}
|
|
56
|
+
if (existing && typeof existing.get === 'function') {
|
|
57
|
+
if (!updated || typeof updated.get !== 'function')
|
|
58
|
+
return true;
|
|
59
|
+
return ((updated.get('named')?.length ?? 0) < (existing.get('named')?.length ?? 0) ||
|
|
60
|
+
(updated.get('typed')?.length ?? 0) < (existing.get('typed')?.length ?? 0));
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
45
64
|
function replayLogs(rootStore, tables) {
|
|
46
65
|
if (!node_worker_threads_1.isMainThread)
|
|
47
66
|
return; // ideally we don't do it like this, but for now this is predictable
|
|
@@ -79,34 +98,35 @@ function replayLogs(rootStore, tables) {
|
|
|
79
98
|
let lastTimestamp = 0;
|
|
80
99
|
let writes = 0;
|
|
81
100
|
let skipped = 0;
|
|
101
|
+
// Track forward progress so a backlog of unwritable entries can't grind the boot thread
|
|
102
|
+
// forever (harper#1266). `noProgressRun` counts every entry processed without a successful
|
|
103
|
+
// write since the last one — undecodable/corrupt skips AND entries for a dropped table — and
|
|
104
|
+
// is reset to 0 the moment a write succeeds, so the stall bound only fires on a genuinely
|
|
105
|
+
// write-free run.
|
|
106
|
+
let noProgressRun = 0;
|
|
107
|
+
let lastProgressTime = performance.now();
|
|
82
108
|
const txnLog = rootStore.auditStore;
|
|
83
109
|
for (const auditRecord of txnLog.getRange({ startFromLastFlushed: true, readUncommitted: true })) {
|
|
110
|
+
if (noProgressRun > 0 && (0, replayLogsGuards_ts_1.shouldAbortStalledReplay)(noProgressRun, performance.now() - lastProgressTime)) {
|
|
111
|
+
logger.fatal(`Aborting transaction-log replay in ${rootStore.databaseName} database: ${noProgressRun} consecutive audit entries with no successful write (${skipped} skipped as unrecoverable, ${writes} replayed so far). This backlog is making no forward progress and was blocking startup (harper#1266) — typically a peer transaction log whose values reference unresolvable shared structures (harper#1163), or a backlog for a dropped table. Continuing boot without replaying the remainder; shed or relocate the oversized/undecodable peer transaction log(s), or re-clone this node, to recover the unreplayed data.`);
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
84
114
|
const { type, tableId, nodeId, recordId, version, residencyId, expiresAt, originatingOperation, username, extendedType, } = auditRecord;
|
|
85
115
|
try {
|
|
86
116
|
if ((0, replayLogsGuards_ts_1.classifyAuditEntryForReplay)(extendedType, tableId, true) === 'corrupt-header') {
|
|
87
117
|
skipped++;
|
|
118
|
+
noProgressRun++;
|
|
88
119
|
continue;
|
|
89
120
|
}
|
|
90
121
|
const Table = tableById.get(tableId);
|
|
91
|
-
if (!Table)
|
|
122
|
+
if (!Table) {
|
|
123
|
+
// Entry for a table this node no longer has (dropped/foreign). Not an
|
|
124
|
+
// unrecoverable skip, but still a no-progress entry — a large backlog of them
|
|
125
|
+
// must trip the stall bound rather than grind the boot thread.
|
|
126
|
+
noProgressRun++;
|
|
92
127
|
continue;
|
|
93
|
-
const context = {
|
|
94
|
-
nodeId,
|
|
95
|
-
alreadyLogged: true,
|
|
96
|
-
version,
|
|
97
|
-
expiresAt,
|
|
98
|
-
user: { username },
|
|
99
|
-
};
|
|
100
|
-
const { primaryStore } = Table;
|
|
101
|
-
const target = new RequestTarget_ts_1.RequestTarget();
|
|
102
|
-
target.id = null;
|
|
103
|
-
const tableInstance = Table.getResource(target, context, {});
|
|
104
|
-
// TODO: If this throws an error due to being unable to access structures, we need to iterate through
|
|
105
|
-
// other transaction logs to get the latest structure. Ultimately we may have to skip records
|
|
106
|
-
if (!warnedReplayHappening) {
|
|
107
|
-
warnedReplayHappening = true;
|
|
108
|
-
console.warn('Harper was not properly shutdown, replaying transaction logs to synchronize database');
|
|
109
128
|
}
|
|
129
|
+
const { primaryStore } = Table;
|
|
110
130
|
let record;
|
|
111
131
|
try {
|
|
112
132
|
record = auditRecord.getValue(primaryStore);
|
|
@@ -118,13 +138,33 @@ function replayLogs(rootStore, tables) {
|
|
|
118
138
|
// (millions of these were observed in prod). The total skip count is logged
|
|
119
139
|
// once at the end of replay.
|
|
120
140
|
skipped++;
|
|
141
|
+
noProgressRun++;
|
|
121
142
|
continue;
|
|
122
143
|
}
|
|
123
144
|
if ((0, replayLogsGuards_ts_1.classifyAuditEntryForReplay)(extendedType, tableId, record !== undefined) === 'missing-record' ||
|
|
124
145
|
(0, replayLogsGuards_ts_1.isUndecodableValidatedWrite)(type, record)) {
|
|
125
146
|
skipped++;
|
|
147
|
+
noProgressRun++;
|
|
126
148
|
continue;
|
|
127
149
|
}
|
|
150
|
+
// Entry is replayable: build the context and instantiate the resource only now, so
|
|
151
|
+
// the skip paths above never pay those per-entry allocations (harper#1266).
|
|
152
|
+
const context = {
|
|
153
|
+
nodeId,
|
|
154
|
+
alreadyLogged: true,
|
|
155
|
+
version,
|
|
156
|
+
expiresAt,
|
|
157
|
+
user: { username },
|
|
158
|
+
};
|
|
159
|
+
const target = new RequestTarget_ts_1.RequestTarget();
|
|
160
|
+
target.id = null;
|
|
161
|
+
const tableInstance = Table.getResource(target, context, {});
|
|
162
|
+
// TODO: If this throws an error due to being unable to access structures, we need to iterate through
|
|
163
|
+
// other transaction logs to get the latest structure. Ultimately we may have to skip records
|
|
164
|
+
if (!warnedReplayHappening) {
|
|
165
|
+
warnedReplayHappening = true;
|
|
166
|
+
console.warn('Harper was not properly shutdown, replaying transaction logs to synchronize database');
|
|
167
|
+
}
|
|
128
168
|
if (lastTimestamp !== version) {
|
|
129
169
|
lastTimestamp = version;
|
|
130
170
|
try {
|
|
@@ -165,36 +205,56 @@ function replayLogs(rootStore, tables) {
|
|
|
165
205
|
tableInstance._writeInvalidate(recordId, record, options);
|
|
166
206
|
break;
|
|
167
207
|
case 'structures': {
|
|
168
|
-
const rocksTransaction = new rocksdb_js_1.Transaction(primaryStore.store);
|
|
169
208
|
const structuresAsBinary = auditRecord.getBinaryValue(primaryStore);
|
|
170
209
|
const updatedStructures = structuresAsBinary ? primaryStore.decoder.decode(structuresAsBinary) : undefined;
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
210
|
+
// Persist replayed structures where the decoder actually reads them: the RocksDB decode
|
|
211
|
+
// path (RecordEncoder.getStructures) reads `rootStore` at the COMPOSITE key
|
|
212
|
+
// [Symbol.for('structures'), name], and saveStructures writes there. This previously wrote
|
|
213
|
+
// `primaryStore` at the PLAIN key Symbol.for('structures'), which getStructures never
|
|
214
|
+
// consults — so a structure delivered only via replication stayed invisible to the decoder
|
|
215
|
+
// (records referencing it decoded to null) until a full-copy resync rewrote the row through
|
|
216
|
+
// saveStructures. See harper-pro#362 (and the #352 auth-path wedge). Because this is now the
|
|
217
|
+
// authoritative key the decoder reads, it must carry saveStructures' guards: never poison the
|
|
218
|
+
// dictionary with an undecodable value, and never downgrade it to fewer structures.
|
|
219
|
+
const encoder = primaryStore.decoder;
|
|
220
|
+
const sharedStructuresKey = [Symbol.for('structures'), encoder.name];
|
|
221
|
+
encoder.rootStore.transactionSync((txn) => {
|
|
222
|
+
// A torn/corrupt/empty structures log value decodes to null/undefined; writing it to
|
|
223
|
+
// the key the decoder reads would poison the whole table's structure dictionary.
|
|
224
|
+
if (!updatedStructures) {
|
|
225
|
+
logger.warn(`Skipping a structures replay entry that did not decode to a valid structures buffer (table ${encoder.name}).`);
|
|
226
|
+
return;
|
|
179
227
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
228
|
+
const existingStructuresBuffer = txn.getBinarySync(sharedStructuresKey);
|
|
229
|
+
const existingStructures = existingStructuresBuffer
|
|
230
|
+
? encoder.decode(existingStructuresBuffer)
|
|
231
|
+
: undefined;
|
|
232
|
+
// Refuse to overwrite a longer/newer durable buffer with an older/shorter replayed
|
|
233
|
+
// one — dropping ids the decoder still needs would make existing records decode to
|
|
234
|
+
// null. saveStructures rejects incompatible writes the same way (RecordEncoder.ts).
|
|
235
|
+
if (existingStructures && structuresWouldShrink(existingStructures, updatedStructures)) {
|
|
236
|
+
logger.warn(`Replay log structures for table ${encoder.name} are fewer than the durable buffer; keeping the durable structures.`);
|
|
237
|
+
return;
|
|
187
238
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
239
|
+
txn.putSync(sharedStructuresKey, asBinary(structuresAsBinary));
|
|
240
|
+
}, { retryOnBusy: true });
|
|
241
|
+
// No in-memory assignment is needed: the remainder of the replay decodes through
|
|
242
|
+
// getStructures/loadStructures, which re-reads this composite key (now correct) whenever a
|
|
243
|
+
// record references a not-yet-loaded structure id. We deliberately do NOT route through
|
|
244
|
+
// saveStructures, which would set structureUpdate and re-log the structure during replay.
|
|
194
245
|
}
|
|
195
246
|
}
|
|
247
|
+
// Forward progress: a write was staged successfully, so reset the no-progress
|
|
248
|
+
// trackers. Doing this AFTER the switch (not before) means a slow or throwing
|
|
249
|
+
// write is neither counted as progress nor charged to the stall bound (harper#1266).
|
|
250
|
+
noProgressRun = 0;
|
|
251
|
+
lastProgressTime = performance.now();
|
|
196
252
|
}
|
|
197
253
|
catch (err) {
|
|
254
|
+
// A write that threw made no forward progress either — count it toward the stall
|
|
255
|
+
// bound so a continuous stream of throwing writes can't grind the boot thread
|
|
256
|
+
// indefinitely (and the per-entry error log below can't spam unboundedly). harper#1266
|
|
257
|
+
noProgressRun++;
|
|
198
258
|
logger.error(`Error writing from replay of log`, err, {
|
|
199
259
|
version,
|
|
200
260
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replayLogs.js","sourceRoot":"","sources":["../../resources/replayLogs.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"replayLogs.js","sourceRoot":"","sources":["../../resources/replayLogs.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,21 +16,38 @@ export declare const RECORD_BEARING_FLAGS: number;
|
|
|
16
16
|
*/
|
|
17
17
|
export declare function classifyAuditEntryForReplay(action: number | undefined, tableId: number | undefined, hasRecord: boolean): 'corrupt-header' | 'missing-record' | null;
|
|
18
18
|
/**
|
|
19
|
-
* Whether an audit entry
|
|
20
|
-
*
|
|
19
|
+
* Whether an audit entry runs `validate()` during replay but its record body failed to decode,
|
|
20
|
+
* and so must be skipped.
|
|
21
21
|
*
|
|
22
22
|
* `RecordEncoder.decode` returns `null` (not `undefined`, and it does not throw) when a value
|
|
23
23
|
* fails to decode — e.g. structure-dictionary divergence, which surfaces as msgpackr's
|
|
24
24
|
* "Data read, but end of buffer not reached". `classifyAuditEntryForReplay` only catches a
|
|
25
|
-
* `undefined` body, so a `null` slips through;
|
|
26
|
-
*
|
|
25
|
+
* `undefined` body, so a `null` slips through; the replay path then calls `validate()`, which
|
|
26
|
+
* dereferences the record and crashes on the missing body.
|
|
27
27
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
28
|
+
* Scoped to the actions whose replay reaches `validate()`: `put`/`patch` (via `_writeUpdate` →
|
|
29
|
+
* `save()`) and `message` (via `_writePublish` → `transaction.addWrite` → `save()`; the publish
|
|
30
|
+
* `validate` hook fires whenever the replay context has no `source`, which it never does). Other
|
|
31
|
+
* record-bearing actions must NOT be skipped on a `null` body — notably `invalidate`, which
|
|
32
|
+
* legitimately stores a `null` partial record on a table with no index fields and never reaches
|
|
33
|
+
* `validate()`; `relocate`/`delete` ignore the body entirely. See harper#1255.
|
|
32
34
|
*/
|
|
33
35
|
export declare function isUndecodableValidatedWrite(type: string | undefined, record: unknown): boolean;
|
|
36
|
+
export declare const REPLAY_NO_PROGRESS_COUNT_LIMIT = 100000;
|
|
37
|
+
export declare const REPLAY_NO_PROGRESS_TIME_LIMIT_MS = 60000;
|
|
38
|
+
export declare const REPLAY_NO_PROGRESS_TIME_SKIP_FLOOR = 1000;
|
|
39
|
+
/**
|
|
40
|
+
* Whether boot replay should abort because it is making no forward progress — a backlog of
|
|
41
|
+
* unwritable entries (undecodable/corrupt, or for a dropped table) that produces no writes
|
|
42
|
+
* (harper#1266). Returns `true` once the contiguous run of no-progress entries since the last
|
|
43
|
+
* successful write crosses the count bound, or once it has both built up past the time-skip floor
|
|
44
|
+
* AND burned the time bound. All inputs are measured since the last write, so a productive replay
|
|
45
|
+
* (which keeps resetting them) never trips this; only a genuinely stalled, write-free grind does.
|
|
46
|
+
*
|
|
47
|
+
* @param noProgressRun consecutive entries processed without a successful write
|
|
48
|
+
* @param msSinceProgress wall-clock ms elapsed since the last successful write
|
|
49
|
+
*/
|
|
50
|
+
export declare function shouldAbortStalledReplay(noProgressRun: number, msSinceProgress: number, countLimit?: number, timeLimitMs?: number, timeSkipFloor?: number): boolean;
|
|
34
51
|
/**
|
|
35
52
|
* Wraps a transaction-log query iterator so a corrupt/torn frame ends that log's iteration
|
|
36
53
|
* cleanly instead of escaping as an uncaughtException. rocksdb-js throws a bounded RangeError
|
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
// running over potentially millions of entries, pinning CPU. These guards classify each
|
|
10
10
|
// entry up front so the loop can skip cleanly.
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.RECORD_BEARING_FLAGS = void 0;
|
|
12
|
+
exports.REPLAY_NO_PROGRESS_TIME_SKIP_FLOOR = exports.REPLAY_NO_PROGRESS_TIME_LIMIT_MS = exports.REPLAY_NO_PROGRESS_COUNT_LIMIT = exports.RECORD_BEARING_FLAGS = void 0;
|
|
13
13
|
exports.classifyAuditEntryForReplay = classifyAuditEntryForReplay;
|
|
14
14
|
exports.isUndecodableValidatedWrite = isUndecodableValidatedWrite;
|
|
15
|
+
exports.shouldAbortStalledReplay = shouldAbortStalledReplay;
|
|
15
16
|
exports.endIteratorOnCorruptFrame = endIteratorOnCorruptFrame;
|
|
16
17
|
// Mirrors `HAS_RECORD` (16) | `HAS_PARTIAL_RECORD` (32) from auditStore.ts — the action
|
|
17
18
|
// bits the writer sets when an entry carries (or should carry) a record body. Redeclared
|
|
@@ -43,22 +44,61 @@ function classifyAuditEntryForReplay(action, tableId, hasRecord) {
|
|
|
43
44
|
return null;
|
|
44
45
|
}
|
|
45
46
|
/**
|
|
46
|
-
* Whether an audit entry
|
|
47
|
-
*
|
|
47
|
+
* Whether an audit entry runs `validate()` during replay but its record body failed to decode,
|
|
48
|
+
* and so must be skipped.
|
|
48
49
|
*
|
|
49
50
|
* `RecordEncoder.decode` returns `null` (not `undefined`, and it does not throw) when a value
|
|
50
51
|
* fails to decode — e.g. structure-dictionary divergence, which surfaces as msgpackr's
|
|
51
52
|
* "Data read, but end of buffer not reached". `classifyAuditEntryForReplay` only catches a
|
|
52
|
-
* `undefined` body, so a `null` slips through;
|
|
53
|
-
*
|
|
53
|
+
* `undefined` body, so a `null` slips through; the replay path then calls `validate()`, which
|
|
54
|
+
* dereferences the record and crashes on the missing body.
|
|
54
55
|
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
56
|
+
* Scoped to the actions whose replay reaches `validate()`: `put`/`patch` (via `_writeUpdate` →
|
|
57
|
+
* `save()`) and `message` (via `_writePublish` → `transaction.addWrite` → `save()`; the publish
|
|
58
|
+
* `validate` hook fires whenever the replay context has no `source`, which it never does). Other
|
|
59
|
+
* record-bearing actions must NOT be skipped on a `null` body — notably `invalidate`, which
|
|
60
|
+
* legitimately stores a `null` partial record on a table with no index fields and never reaches
|
|
61
|
+
* `validate()`; `relocate`/`delete` ignore the body entirely. See harper#1255.
|
|
59
62
|
*/
|
|
60
63
|
function isUndecodableValidatedWrite(type, record) {
|
|
61
|
-
return record == null && (type === 'put' || type === 'patch');
|
|
64
|
+
return record == null && (type === 'put' || type === 'patch' || type === 'message');
|
|
65
|
+
}
|
|
66
|
+
// A node that crashed unclean replays its unflushed audit backlog on boot. When that backlog is
|
|
67
|
+
// dominated by entries that can't be written — undecodable values (the #1163 structure-dictionary
|
|
68
|
+
// divergence), corrupt headers, or entries for a dropped table — every iteration makes no forward
|
|
69
|
+
// progress. A large enough backlog then grinds the main thread for minutes with zero progress,
|
|
70
|
+
// blocking startup entirely (harper#1266). These bounds let replay give up on a run that is making
|
|
71
|
+
// no progress so boot can proceed; the operator then sheds/relocates the offending peer log (or
|
|
72
|
+
// re-clones). They are deliberately conservative: a healthy replay produces writes, which reset
|
|
73
|
+
// the progress tracking, so neither bound can trip on it.
|
|
74
|
+
// Max consecutive no-progress entries (since the last successful write) before the replay is
|
|
75
|
+
// treated as stalled. ~100k contiguous unwritable entries is unambiguously degenerate and caps the
|
|
76
|
+
// wasted grind well below the multi-minute hangs observed in prod.
|
|
77
|
+
exports.REPLAY_NO_PROGRESS_COUNT_LIMIT = 100_000;
|
|
78
|
+
// Max wall-clock time (ms) since the last successful write before the replay is treated as stalled.
|
|
79
|
+
// Belt-and-suspenders for the count bound: if individual entries are slow enough that fewer than the
|
|
80
|
+
// count limit still burns minutes, this still bounds the hang.
|
|
81
|
+
exports.REPLAY_NO_PROGRESS_TIME_LIMIT_MS = 60_000;
|
|
82
|
+
// The time bound only applies once a substantial no-progress run has built up. Without this floor a
|
|
83
|
+
// single skipped entry followed by an unrelated latency spike (a GC pause, disk throttling, one
|
|
84
|
+
// slow write) would trip the time bound and abort an otherwise-healthy replay; requiring a real run
|
|
85
|
+
// of no-progress entries keeps the time bound a signal of a genuine grind, not a transient stall.
|
|
86
|
+
exports.REPLAY_NO_PROGRESS_TIME_SKIP_FLOOR = 1_000;
|
|
87
|
+
/**
|
|
88
|
+
* Whether boot replay should abort because it is making no forward progress — a backlog of
|
|
89
|
+
* unwritable entries (undecodable/corrupt, or for a dropped table) that produces no writes
|
|
90
|
+
* (harper#1266). Returns `true` once the contiguous run of no-progress entries since the last
|
|
91
|
+
* successful write crosses the count bound, or once it has both built up past the time-skip floor
|
|
92
|
+
* AND burned the time bound. All inputs are measured since the last write, so a productive replay
|
|
93
|
+
* (which keeps resetting them) never trips this; only a genuinely stalled, write-free grind does.
|
|
94
|
+
*
|
|
95
|
+
* @param noProgressRun consecutive entries processed without a successful write
|
|
96
|
+
* @param msSinceProgress wall-clock ms elapsed since the last successful write
|
|
97
|
+
*/
|
|
98
|
+
function shouldAbortStalledReplay(noProgressRun, msSinceProgress, countLimit = exports.REPLAY_NO_PROGRESS_COUNT_LIMIT, timeLimitMs = exports.REPLAY_NO_PROGRESS_TIME_LIMIT_MS, timeSkipFloor = exports.REPLAY_NO_PROGRESS_TIME_SKIP_FLOOR) {
|
|
99
|
+
if (noProgressRun >= countLimit)
|
|
100
|
+
return true;
|
|
101
|
+
return noProgressRun >= timeSkipFloor && msSinceProgress >= timeLimitMs;
|
|
62
102
|
}
|
|
63
103
|
/**
|
|
64
104
|
* Wraps a transaction-log query iterator so a corrupt/torn frame ends that log's iteration
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replayLogsGuards.js","sourceRoot":"","sources":["../../resources/replayLogsGuards.ts"],"names":[],"mappings":";AAAA,qFAAqF;AACrF,uFAAuF;AACvF,EAAE;AACF,yFAAyF;AACzF,uFAAuF;AACvF,iFAAiF;AACjF,sFAAsF;AACtF,wFAAwF;AACxF,+CAA+C;;;AAuB/C,kEAUC;
|
|
1
|
+
{"version":3,"file":"replayLogsGuards.js","sourceRoot":"","sources":["../../resources/replayLogsGuards.ts"],"names":[],"mappings":"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"}
|
package/dist/server/nodeName.js
CHANGED
|
@@ -67,9 +67,15 @@ function getThisNodeName() {
|
|
|
67
67
|
return nodeName; // if already determined, just return
|
|
68
68
|
nodeName = env.get(hdbTerms_ts_1.CONFIG_PARAMS.NODE_HOSTNAME); // standard config
|
|
69
69
|
if (nodeName) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
const replicationHostname = env.get('replication_hostname');
|
|
71
|
+
if (replicationHostname && replicationHostname !== nodeName) {
|
|
72
|
+
// If these are both set and differ, the node identity is ambiguous. node.hostname
|
|
73
|
+
// wins (it is what this node identifies as), but if it doesn't match the name this
|
|
74
|
+
// node is registered under in hdb_nodes, replication for that name silently turns
|
|
75
|
+
// off (harper-pro#351). Do NOT blindly recommend cementing the already-picked
|
|
76
|
+
// node.hostname value — that's how a wrong identity (e.g. 'localhost') gets locked
|
|
77
|
+
// in. Steer the operator to reconcile against the registered node name instead.
|
|
78
|
+
logger_ts_1.logger.warn?.(`The node.hostname (${nodeName}) and replication.hostname (${replicationHostname}) configuration values are both set and differ. This node will identify as "${nodeName}". Ensure that name matches this node's row in system.hdb_nodes; if it does not, set node.hostname (or remove it to fall back to replication.hostname) to match the registered node name, otherwise replication for this node will be disabled.`);
|
|
73
79
|
}
|
|
74
80
|
return nodeName;
|
|
75
81
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodeName.js","sourceRoot":"","sources":["../../server/nodeName.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,
|
|
1
|
+
{"version":3,"file":"nodeName.js","sourceRoot":"","sources":["../../server/nodeName.ts"],"names":[],"mappings":"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"}
|
|
@@ -57,6 +57,7 @@ const packageUtils_js_1 = require("../utility/packageUtils.js");
|
|
|
57
57
|
const globalSchema = __importStar(require("../utility/globalSchema.js"));
|
|
58
58
|
const commonUtils = __importStar(require("../utility/common_utils.js"));
|
|
59
59
|
const userSchema = __importStar(require("../security/user.js"));
|
|
60
|
+
const auth_ts_1 = require("../security/auth.js");
|
|
60
61
|
const Server_ts_1 = require("../server/Server.js");
|
|
61
62
|
const serverHandlers_js_1 = require("./serverHelpers/serverHandlers.js");
|
|
62
63
|
const http_ts_1 = require("./http.js");
|
|
@@ -97,6 +98,25 @@ async function operationsServer(options) {
|
|
|
97
98
|
// now that server is fully loaded/ready, start listening on port provided in config settings or just use
|
|
98
99
|
// zero to wait for sockets from the main thread
|
|
99
100
|
Server_ts_1.server.http(server.server, options);
|
|
101
|
+
// The operations API runs only on the main thread, where auth's worker-only
|
|
102
|
+
// handleApplication never registers the authentication middleware. Register it here
|
|
103
|
+
// (after the node server, so its port already exists) so operations requests get
|
|
104
|
+
// `request.login`/`session`/`user` set up — without it the `login` operation that
|
|
105
|
+
// Studio uses to bootstrap a new instance fails with "No session for login".
|
|
106
|
+
// Node only: on Bun the ops API is served by delegating to Fastify via inject(), and
|
|
107
|
+
// auth is applied through fastifyAuth's Bun shim (there is no `_nodeRequest` for the
|
|
108
|
+
// auth middleware to attach the resolved user to). Register per port because `http()`
|
|
109
|
+
// tags each responder entry with `options.port || port`, so passing both ports in one
|
|
110
|
+
// call would mis-tag the secure entry with the plain port and leave the secure
|
|
111
|
+
// listener's chain without authentication.
|
|
112
|
+
if (typeof globalThis.Bun === 'undefined') {
|
|
113
|
+
if (options.port)
|
|
114
|
+
Server_ts_1.server.http(auth_ts_1.authentication, { port: options.port });
|
|
115
|
+
if (options.securePort)
|
|
116
|
+
Server_ts_1.server.http(auth_ts_1.authentication, { securePort: options.securePort });
|
|
117
|
+
if (!options.port && !options.securePort)
|
|
118
|
+
Server_ts_1.server.http(auth_ts_1.authentication, { port: 'all' });
|
|
119
|
+
}
|
|
100
120
|
// On Bun, register the Fastify instance so requests can be delegated via inject()
|
|
101
121
|
if (typeof globalThis.Bun !== 'undefined') {
|
|
102
122
|
const port = options.port || options.securePort || env.get(CONFIG_PARAMS.OPERATIONSAPI_NETWORK_PORT);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operationsServer.js","sourceRoot":"","sources":["../../server/operationsServer.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"operationsServer.js","sourceRoot":"","sources":["../../server/operationsServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -78,7 +78,13 @@ const ABORT_MSG = 'Aborting install';
|
|
|
78
78
|
const PROCESS_HOME = os.homedir();
|
|
79
79
|
const DEFAULT_HDB_ROOT = path.join(PROCESS_HOME, hdbTerms.HDB_ROOT_DIR_NAME);
|
|
80
80
|
const DEFAULT_ADMIN_USERNAME = 'admin';
|
|
81
|
-
|
|
81
|
+
// Intentionally null (not 'localhost'). Persisting a concrete node.hostname here cements a
|
|
82
|
+
// wrong identity: getThisNodeName() prefers node.hostname over replication.hostname, so a
|
|
83
|
+
// planted 'localhost' makes the node fail to find its own hdb_nodes self-row and silently
|
|
84
|
+
// disable user-DB replication (harper-pro#351 — exposed by in-place v4->v5 upgrades, where
|
|
85
|
+
// the install/migration boot would otherwise default this to 'localhost'). Leaving it unset
|
|
86
|
+
// preserves the working fallback chain (replication.hostname -> cert CN -> listening port).
|
|
87
|
+
const DEFAULT_NODE_HOSTNAME = null;
|
|
82
88
|
const DEFAULT_CONFIG_MODE = 'dev';
|
|
83
89
|
const DEV_MODE_CONFIG = {
|
|
84
90
|
[CONFIG_PARAMS.HTTP_CORS]: true,
|
|
@@ -265,11 +271,11 @@ async function installPrompts(promptOverride) {
|
|
|
265
271
|
name: hdbTerms.INSTALL_PROMPTS.NODE_HOSTNAME,
|
|
266
272
|
prefix: PROMPT_PREFIX,
|
|
267
273
|
default: DEFAULT_NODE_HOSTNAME,
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
274
|
+
// node.hostname is OPTIONAL — an unset value is valid and preferred when the operator
|
|
275
|
+
// hasn't got a stable name to pin (it falls back to replication.hostname / cert CN /
|
|
276
|
+
// listening port). Accept empty/unset rather than forcing a value, which is what used
|
|
277
|
+
// to cement 'localhost' (harper-pro#351).
|
|
278
|
+
validate: () => true,
|
|
273
279
|
message: HDB_PROMPT_MSG(INSTALL_PROMPTS.NODE_HOSTNAME),
|
|
274
280
|
},
|
|
275
281
|
{
|