sliftutils 1.7.118 → 1.7.119
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/index.d.ts +2 -1
- package/package.json +1 -1
- package/storage/remoteStorage/blobStore.ts +5 -6
- package/storage/remoteStorage/createArchives.ts +5 -1
- package/storage/remoteStorage/dist/blobStore.ts.cache +7 -10
- package/storage/remoteStorage/dist/createArchives.ts.cache +7 -3
- package/storage/remoteStorage/dist/intermediateManagement.ts.cache +5 -8
- package/storage/remoteStorage/dist/remoteConfig.ts.cache +7 -4
- package/storage/remoteStorage/dist/storageServerState.ts.cache +5 -2
- package/storage/remoteStorage/dist/storeSync.ts.cache +6 -3
- package/storage/remoteStorage/intermediateManagement.ts +3 -5
- package/storage/remoteStorage/remoteConfig.d.ts +2 -1
- package/storage/remoteStorage/remoteConfig.ts +6 -3
- package/storage/remoteStorage/storageServerState.ts +3 -0
- package/storage/remoteStorage/storeSync.ts +3 -1
|
@@ -188,11 +188,9 @@ async function maintainIntermediates(): Promise<void> {
|
|
|
188
188
|
let key = `${account}/${bucketName}`;
|
|
189
189
|
let newest = await readNewestRoutingFile(account, bucketName);
|
|
190
190
|
if (!newest) continue;
|
|
191
|
-
let routing
|
|
192
|
-
|
|
193
|
-
routing
|
|
194
|
-
} catch (e) {
|
|
195
|
-
console.error(`Skipping switchover maintenance for bucket ${key}: its routing config could not be parsed (${(e as Error).message})`);
|
|
191
|
+
let routing = parseRoutingData(newest.data);
|
|
192
|
+
if (!routing) {
|
|
193
|
+
console.error(`Skipping switchover maintenance for bucket ${key}: its routing config could not be parsed`);
|
|
196
194
|
continue;
|
|
197
195
|
}
|
|
198
196
|
let expired = expireIntermediateSources(routing, Date.now());
|
|
@@ -60,5 +60,6 @@ export declare function assertValidRemoteConfig(config: RemoteConfig): void;
|
|
|
60
60
|
export declare function sourceIdentity(sourceConfig: SourceConfig | undefined): string;
|
|
61
61
|
/** What an index entry records as the holder of its bytes (see ArchivesSource.url), so it must name the endpoint FOREVER. An intermediate is a switchover's temporary alternate port onto another source, and that port is gone for good once its window passes - so it is recorded as the source it was split out of, which holds the same bucket and outlives it. */
|
|
62
62
|
export declare function sourcePersistentUrl(sourceConfig: SourceConfig | undefined, folder: string): string;
|
|
63
|
-
|
|
63
|
+
/** Reads a stored routing config. NEVER throws: this runs on every READ of a stored config, and a torn/corrupt file must not brick the paths that would fix it - above all writeRoutingConfig, where throwing while reading the OLD config blocks the write of the NEW one forever. Unreadable data is logged and read as undefined - the same as the file not existing. Judging a config on its way IN is the writer's job (see assertValidRemoteConfig at the write entry points), where rejecting bad data with a throw is correct. */
|
|
64
|
+
export declare function parseRoutingData(data: Buffer): RemoteConfig | undefined;
|
|
64
65
|
export declare function serializeRemoteConfig(config: RemoteConfig): Buffer;
|
|
@@ -288,16 +288,19 @@ function storeIdentity(source: SourceConfig): string {
|
|
|
288
288
|
return `${source.intermediate || source.url}|${source.name}`;
|
|
289
289
|
}
|
|
290
290
|
|
|
291
|
-
|
|
291
|
+
/** Reads a stored routing config. NEVER throws: this runs on every READ of a stored config, and a torn/corrupt file must not brick the paths that would fix it - above all writeRoutingConfig, where throwing while reading the OLD config blocks the write of the NEW one forever. Unreadable data is logged and read as undefined - the same as the file not existing. Judging a config on its way IN is the writer's job (see assertValidRemoteConfig at the write entry points), where rejecting bad data with a throw is correct. */
|
|
292
|
+
export function parseRoutingData(data: Buffer): RemoteConfig | undefined {
|
|
292
293
|
let text = data.toString();
|
|
293
294
|
let parsed: RemoteConfig;
|
|
294
295
|
try {
|
|
295
296
|
parsed = JSON.parse(text) as RemoteConfig;
|
|
296
297
|
} catch (e) {
|
|
297
|
-
|
|
298
|
+
console.error(`Ignoring a stored routing config - it is not valid JSON (${String(e)}). Data: ${JSON.stringify(text).slice(0, 500)}`);
|
|
299
|
+
return undefined;
|
|
298
300
|
}
|
|
299
301
|
if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.sources)) {
|
|
300
|
-
|
|
302
|
+
console.error(`Ignoring a stored routing config - it must be { version?, sources: [...] }, was ${text.slice(0, 500)}`);
|
|
303
|
+
return undefined;
|
|
301
304
|
}
|
|
302
305
|
return normalizeRemoteConfig(parsed);
|
|
303
306
|
}
|
|
@@ -193,6 +193,9 @@ export async function writeRoutingConfig(account: string, bucketName: string, na
|
|
|
193
193
|
assertWritesAllowed();
|
|
194
194
|
let store = getStore(account, bucketName, name);
|
|
195
195
|
let incoming = parseRoutingData(data);
|
|
196
|
+
if (!incoming) {
|
|
197
|
+
throw new Error(`Routing config write rejected - not a parseable config. The data written for ${account}/${bucketName} (store ${JSON.stringify(name)}) is not a valid { version?, sources: [...] } JSON config (${data.length} bytes)`);
|
|
198
|
+
}
|
|
196
199
|
let current = await readRoutingFromDisk(account, bucketName);
|
|
197
200
|
let stored = reinjectIntermediates(current, incoming);
|
|
198
201
|
let storedData = Buffer.from(serializeRemoteConfig(stored));
|
|
@@ -127,7 +127,9 @@ export class StoreSync {
|
|
|
127
127
|
try {
|
|
128
128
|
let theirs = await source.get2(ROUTING_FILE, { internal: true });
|
|
129
129
|
if (!theirs || !theirs.data || !theirs.data.length) continue;
|
|
130
|
-
let
|
|
130
|
+
let theirRouting = parseRoutingData(theirs.data);
|
|
131
|
+
if (!theirRouting) continue;
|
|
132
|
+
let version = getConfigVersion(theirRouting);
|
|
131
133
|
if (version <= this.store.routingVersion()) continue;
|
|
132
134
|
console.log(`Routing config version ${version} found on ${source.getDebugName()} (we have ${this.store.routingVersion()}, store ${this.store.folder}): taking it`);
|
|
133
135
|
// Stamped NOW, not with their write time: configs are ordered by version, and this one is newer by that ordering. Their file can easily be older by write time (ours was rewritten locally more recently), and the store's only-take-the-latest rule would then drop it - leaving us finding the same newer version on every poll and never adopting it.
|