@lossless.org/client 1.23.0 → 1.23.1

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.
@@ -1,22 +1,19 @@
1
1
  import * as plugins from './plugins.js';
2
2
  import { assertDataOptions } from './classes.operationbudget.js';
3
3
  import { SmartdataPersistenceError, isMongoDuplicateKeyError } from './classes.persistence.js';
4
- import { logger } from './logging.js';
5
4
  /** The collection that holds the counters. */
6
5
  export const writeRevisionsCollectionName = '__smartdata_write_revisions';
7
6
  /** The counter every write revision belongs to; a new generation restarts all counters. */
8
7
  const epochId = '$epoch';
8
+ /** Joins a counter's id and the slot of one of its shards, or ends the id of its list. No counter id contains it. */
9
+ const shardSeparator = '\u0000';
9
10
  /**
10
- * Joins a counter's id and the suffix of one of its entries. No counter id
11
- * contains it, so a counter's base and entries are exactly the ids from the
12
- * counter's own up to, not including, the id followed by `entryRangeEnd`.
11
+ * Slots per counter, the base included: as many transactions that overlap in
12
+ * time can bump one counter without conflicting on it.
13
13
  */
14
- const entrySeparator = '\u0000';
15
- const entryRangeEnd = '\u0001';
16
- /** Entries one process adds to a counter before it folds the counter's entries into its base. */
17
- const compactionEntries = 64;
18
- const maximumCompactedEntries = 1024;
19
- const compactionTimeoutMs = 5_000;
14
+ const counterShards = 16;
15
+ /** Counters whose slots a database instance remembers, beyond those an open transaction holds. */
16
+ const maximumRememberedCounters = 4096;
20
17
  const maximumPartitionLength = 512;
21
18
  const maximumPinnedPartitions = 64;
22
19
  /** Beyond this many documents, a write by selector bumps the shared counter instead. */
@@ -46,13 +43,17 @@ export const isSmartdataWriteRevisionsActive = (dbArg) => partitionFields.has(db
46
43
  const partitionOf = (valueArg) => typeof valueArg === 'string'
47
44
  && valueArg.length <= maximumPartitionLength
48
45
  && valueArg.isWellFormed()
49
- && !valueArg.includes(entrySeparator)
46
+ && !valueArg.includes(shardSeparator)
50
47
  ? valueArg
51
48
  : undefined;
52
49
  /** @internal The counter of one partition of a collection. */
53
50
  export const partitionRevisionId = (collectionArg, partitionArg) => `${collectionArg}$s${partitionArg}`;
54
51
  /** @internal The counter of a collection's writes that no partition can place. */
55
52
  export const sharedRevisionId = (collectionArg) => `${collectionArg}$*`;
53
+ /** @internal The document of a counter's slot: the base for slot 0, a shard otherwise. */
54
+ export const revisionSlotId = (idArg, slotArg) => slotArg === 0 ? idArg : `${idArg}${shardSeparator}${slotArg}`;
55
+ /** @internal The document that lists how many slots of a counter are in use; none means only the base. */
56
+ export const revisionSlotListId = (idArg) => `${idArg}${shardSeparator}`;
56
57
  /**
57
58
  * @internal The counter a stored value of the partition field belongs to:
58
59
  * its partition's for a string the counters can name, the shared one otherwise.
@@ -139,15 +140,89 @@ export const writeRevisionBumpsOfKey = (keyArg, idsArg) => {
139
140
  }
140
141
  return bumps;
141
142
  };
142
- export const beginSmartdataWriteRevisionCommit = (dbArg, idsArg) => {
143
- const commits = revisionCommitsOfDb(dbArg);
144
- const ids = new Set(idsArg);
145
- commits.pending.add(ids);
146
- for (const snapshot of commits.snapshots) {
147
- if (snapshot.keys.some((keyArg) => writeRevisionBumpsOfKey(keyArg, ids) > 0))
148
- snapshot.lost = true;
143
+ /** Per database instance, in least recently bumped order. */
144
+ const revisionSlotsOfDbs = new WeakMap();
145
+ /**
146
+ * The slot of a counter an attempt that started at `attemptStartedAtArg`
147
+ * bumps: from the preferred one on, the first that no attempt of this instance
148
+ * holds or ended since then, whose commit the attempt's snapshot might not
149
+ * see. Without one, the first that none holds, and the preferred one last.
150
+ * Transactions of other instances may still take the same slot; a conflict
151
+ * then fails the attempt, and its retry starts after the slot's end, so it
152
+ * moves on to another.
153
+ */
154
+ const chooseRevisionSlot = (counterArg, attemptStartedAtArg) => {
155
+ let unheld;
156
+ for (let offset = 0; offset < counterShards; offset++) {
157
+ const slot = (counterArg.preferred + offset) % counterShards;
158
+ const state = counterArg.slots[slot];
159
+ if (state.holders > 0)
160
+ continue;
161
+ if (state.endedAt < attemptStartedAtArg)
162
+ return slot;
163
+ unheld ??= slot;
149
164
  }
150
- return () => { commits.pending.delete(ids); };
165
+ return unheld ?? counterArg.preferred;
166
+ };
167
+ export const beginSmartdataWriteRevisionAttempt = (dbArg, attemptStartedAtArg) => {
168
+ const taken = [];
169
+ const slots = new Map();
170
+ let pending;
171
+ let finished = false;
172
+ return {
173
+ slots,
174
+ bump: (idArg) => {
175
+ if (finished || slots.has(idArg))
176
+ return;
177
+ let counters = revisionSlotsOfDbs.get(dbArg);
178
+ if (!counters) {
179
+ counters = new Map();
180
+ revisionSlotsOfDbs.set(dbArg, counters);
181
+ }
182
+ const counter = counters.get(idArg) ?? {
183
+ preferred: 0,
184
+ slots: Array.from({ length: counterShards }, () => ({ holders: 0, endedAt: -Infinity })),
185
+ };
186
+ counters.delete(idArg);
187
+ counters.set(idArg, counter);
188
+ const slot = chooseRevisionSlot(counter, attemptStartedAtArg);
189
+ counter.slots[slot].holders++;
190
+ taken.push([counter, slot]);
191
+ slots.set(idArg, slot);
192
+ for (const [id, remembered] of counters) {
193
+ if (counters.size <= maximumRememberedCounters)
194
+ break;
195
+ if (remembered.slots.every((slotArg) => slotArg.holders === 0))
196
+ counters.delete(id);
197
+ }
198
+ },
199
+ commit: () => {
200
+ if (finished || pending)
201
+ return;
202
+ const commits = revisionCommitsOfDb(dbArg);
203
+ const ids = new Set(slots.keys());
204
+ pending = ids;
205
+ commits.pending.add(ids);
206
+ for (const snapshot of commits.snapshots) {
207
+ if (snapshot.keys.some((keyArg) => writeRevisionBumpsOfKey(keyArg, ids) > 0))
208
+ snapshot.lost = true;
209
+ }
210
+ },
211
+ finish: (committedArg) => {
212
+ if (finished)
213
+ return;
214
+ finished = true;
215
+ if (pending)
216
+ revisionCommitsOfDb(dbArg).pending.delete(pending);
217
+ const endedAt = performance.now();
218
+ for (const [counter, slot] of taken) {
219
+ counter.slots[slot].holders--;
220
+ counter.slots[slot].endedAt = endedAt;
221
+ if (committedArg)
222
+ counter.preferred = slot;
223
+ }
224
+ },
225
+ };
151
226
  };
152
227
  /**
153
228
  * @internal The snapshot keys one read depends on. A read the field pins
@@ -177,9 +252,12 @@ const connectedDb = (dbArg) => {
177
252
  };
178
253
  /**
179
254
  * @internal The current value of each snapshot key, or `undefined` for a key
180
- * whose value cannot be known: a missing epoch means the counters restarted.
181
- * Every counter and collection sum is one read, so a compaction that moves
182
- * entries into a base never shows half done. Bounded by its own deadline.
255
+ * whose value cannot be known: a missing epoch means the counters restarted,
256
+ * and a counter with a value or slot count no writer stores stays unknown. One
257
+ * query reads the epoch, the bases and their lists, a second the listed
258
+ * shards. Every part only grows, and a slot is listed by the transaction that
259
+ * first bumps it, so a write that commits between the two queries shows in
260
+ * this snapshot or in the next, never in neither. Bounded by its own deadline.
183
261
  */
184
262
  const readStoredWriteRevisionSnapshot = async (dbArg, keysArg) => {
185
263
  const collection = revisionsCollection(connectedDb(dbArg));
@@ -190,10 +268,11 @@ const readStoredWriteRevisionSnapshot = async (dbArg, keysArg) => {
190
268
  timeoutMode: 'cursorLifetime',
191
269
  signal,
192
270
  });
271
+ const readDocuments = async (idsArg) => new Map((await collection.find({ _id: { $in: idsArg } }, { projection: { n: 1, generation: 1, slots: 1 }, ...options() }).toArray()).map((documentArg) => [documentArg._id, documentArg]));
193
272
  // `$sum` skips a value that is not a number, so such values are counted apart.
194
- const sumOf = async (fromArg, toArg) => {
273
+ const sumOf = async (collectionArg) => {
195
274
  const [sum] = await collection.aggregate([
196
- { $match: { _id: { $gte: fromArg, $lt: toArg } } },
275
+ { $match: { _id: { $gte: `${collectionArg}$`, $lt: `${collectionArg}%` } } },
197
276
  { $group: { _id: null, n: { $sum: '$n' }, invalid: { $sum: { $cond: [{ $isNumber: '$n' }, 0, 1] } } } },
198
277
  ], options()).toArray();
199
278
  if (sum === undefined)
@@ -202,27 +281,43 @@ const readStoredWriteRevisionSnapshot = async (dbArg, keysArg) => {
202
281
  ? String(sum.n)
203
282
  : undefined;
204
283
  };
205
- const sums = keysArg.flatMap((keyArg) => {
206
- if (keyArg.startsWith('c')) {
207
- const id = keyArg.slice(1);
208
- return [[keyArg, sumOf(id, `${id}${entryRangeEnd}`)]];
209
- }
210
- if (keyArg.startsWith('r')) {
211
- const collectionName = keyArg.slice(1);
212
- return [[keyArg, sumOf(`${collectionName}$`, `${collectionName}%`)]];
213
- }
214
- return [];
215
- });
216
- const [epoch, ...values] = await Promise.all([
217
- collection.findOne({ _id: epochId }, { projection: { n: 1, generation: 1 }, ...options() }),
218
- ...sums.map(([, sumArg]) => sumArg),
284
+ const counterIds = keysArg.flatMap((keyArg) => keyArg.startsWith('c') ? [keyArg.slice(1)] : []);
285
+ const ranges = keysArg.flatMap((keyArg) => keyArg.startsWith('r') ? [keyArg.slice(1)] : []);
286
+ const [bases, ...sums] = await Promise.all([
287
+ readDocuments([epochId, ...counterIds.flatMap((idArg) => [idArg, revisionSlotListId(idArg)])]),
288
+ ...ranges.map(sumOf),
219
289
  ]);
290
+ /** The slots each counter's list holds, or `undefined` for a count no writer stores. */
291
+ const slotCounts = new Map(counterIds.map((idArg) => {
292
+ const list = bases.get(revisionSlotListId(idArg));
293
+ const count = list === undefined ? 1 : list.slots;
294
+ return [idArg, Number.isSafeInteger(count) && count >= 1 && count <= counterShards
295
+ ? count
296
+ : undefined];
297
+ }));
298
+ const shardIds = counterIds.flatMap((idArg) => Array.from({ length: (slotCounts.get(idArg) ?? 1) - 1 }, (_unusedArg, indexArg) => revisionSlotId(idArg, indexArg + 1)));
299
+ const shards = shardIds.length === 0 ? new Map() : await readDocuments(shardIds);
220
300
  const snapshot = new Map();
301
+ const epoch = bases.get(epochId);
221
302
  snapshot.set(epochKey, typeof epoch?.generation === 'string' && Number.isSafeInteger(epoch.n)
222
303
  ? `${epoch.generation}:${epoch.n}`
223
304
  : undefined);
224
- for (const [index, [key]] of sums.entries())
225
- snapshot.set(key, values[index]);
305
+ for (const id of counterIds) {
306
+ const count = slotCounts.get(id);
307
+ let sum = count === undefined ? undefined : 0;
308
+ for (let slot = 0; sum !== undefined && slot < count; slot++) {
309
+ // A slot is missing until its first bump commits; a later one may commit first.
310
+ const document = slot === 0 ? bases.get(id) : shards.get(revisionSlotId(id, slot));
311
+ if (document === undefined)
312
+ continue;
313
+ sum = Number.isSafeInteger(document.n) && Number.isSafeInteger(sum + document.n)
314
+ ? sum + document.n
315
+ : undefined;
316
+ }
317
+ snapshot.set(counterKey(id), sum === undefined ? undefined : String(sum));
318
+ }
319
+ for (const [index, collectionName] of ranges.entries())
320
+ snapshot.set(rangeKey(collectionName), sums[index]);
226
321
  return snapshot;
227
322
  };
228
323
  export const readWriteRevisionSnapshot = async (dbArg, keysArg) => {
@@ -276,98 +371,40 @@ export const bumpSmartdataWriteRevisionEpoch = async (dbArg, optionsArg) => {
276
371
  };
277
372
  /**
278
373
  * @internal Bumps the counters a transaction's writes touched, inside that
279
- * transaction, right before its commit: one new entry per counter, which no
280
- * concurrent transaction writes.
374
+ * transaction, right before its commit: each in the slot it took. A shard
375
+ * bump first makes sure the counter's list exists and holds the slot; once it
376
+ * does, neither update changes it, so later bumps of listed slots write only
377
+ * their own document. A slot whose value is no number stays as it is, which
378
+ * keeps its counter unknown, and the write still commits.
281
379
  */
282
- export const flushSmartdataWriteRevisions = async (mongoDbArg, rawSessionArg, idsArg, signalArg) => {
283
- if (idsArg.size === 0)
380
+ export const flushSmartdataWriteRevisions = async (mongoDbArg, rawSessionArg, slotsArg, signalArg) => {
381
+ if (slotsArg.size === 0)
284
382
  return;
285
- await revisionsCollection(mongoDbArg).insertMany([...idsArg].map((idArg) => ({
286
- _id: `${idArg}${entrySeparator}${plugins.nodeCrypto.randomUUID()}`,
287
- n: 1,
288
- })), {
383
+ const operations = [];
384
+ for (const [id, slot] of [...slotsArg].sort(([aArg], [bArg]) => aArg < bArg ? -1 : aArg > bArg ? 1 : 0)) {
385
+ if (slot > 0) {
386
+ const listId = revisionSlotListId(id);
387
+ operations.push({ updateOne: { filter: { _id: listId }, update: { $setOnInsert: { n: 0 } }, upsert: true } }, {
388
+ updateOne: {
389
+ filter: { _id: listId, $or: [{ slots: { $exists: false } }, { slots: { $lt: slot + 1 } }] },
390
+ update: { $set: { slots: slot + 1 } },
391
+ },
392
+ });
393
+ }
394
+ const slotId = revisionSlotId(id, slot);
395
+ operations.push({
396
+ updateOne: {
397
+ filter: { _id: slotId, $or: [{ n: { $type: 'int' } }, { n: { $type: 'long' } }, { n: { $type: 'double' } }] },
398
+ update: { $inc: { n: 1 } },
399
+ },
400
+ }, { updateOne: { filter: { _id: slotId }, update: { $setOnInsert: { n: 1 } }, upsert: true } });
401
+ }
402
+ await revisionsCollection(mongoDbArg).bulkWrite(operations, {
289
403
  ordered: true,
290
404
  session: rawSessionArg,
291
405
  ...(signalArg === undefined ? {} : { signal: signalArg }),
292
406
  });
293
407
  };
294
- const revisionCompactions = new WeakMap();
295
- /**
296
- * Folds up to `maximumCompactedEntries` entries of one counter into its base
297
- * in one transaction, which keeps the counter's value. A concurrent compaction
298
- * of the same counter conflicts on the base and on the entries, and the driver
299
- * retries it within the deadline; one that still fails leaves the entries for
300
- * the next.
301
- */
302
- const compactWriteRevisionEntries = async (dbArg, idArg, signalArg) => {
303
- const collection = revisionsCollection(connectedDb(dbArg));
304
- const abortable = { signal: signalArg };
305
- const session = dbArg.mongoDbClient.startSession();
306
- try {
307
- await session.withTransaction(async () => {
308
- const entries = await collection.find({ _id: { $gt: `${idArg}${entrySeparator}`, $lt: `${idArg}${entryRangeEnd}` } }, { projection: { n: 1 }, limit: maximumCompactedEntries, session, ...abortable }).toArray();
309
- if (entries.length === 0)
310
- return;
311
- let sum = 0;
312
- for (const entry of entries) {
313
- if (!Number.isSafeInteger(entry.n)) {
314
- throw new SmartdataPersistenceError('invalid_document', `Write-revision entry "${entry._id}" holds no safe integer.`);
315
- }
316
- sum += entry.n;
317
- if (!Number.isSafeInteger(sum)) {
318
- throw new SmartdataPersistenceError('invalid_document', `Write-revision entries of "${idArg}" do not sum to a safe integer.`);
319
- }
320
- }
321
- await collection.deleteMany({ _id: { $in: entries.map((entryArg) => entryArg._id) } }, { session, ...abortable });
322
- await collection.updateOne({ _id: idArg }, { $inc: { n: sum } }, { upsert: true, session, ...abortable });
323
- }, { timeoutMS: compactionTimeoutMs });
324
- }
325
- finally {
326
- await session.endSession();
327
- }
328
- };
329
- /**
330
- * @internal Counts the entries a committed transaction of this process added,
331
- * and starts a compaction of each counter that reached `compactionEntries`.
332
- * Compactions run in the background; `stopSmartdataWriteRevisionCompactions`
333
- * ends them.
334
- */
335
- export const noteSmartdataWriteRevisionEntries = (dbArg, idsArg) => {
336
- if (idsArg.size === 0 || dbArg.status !== 'connected' || !isSmartdataWriteRevisionsActive(dbArg))
337
- return;
338
- let state = revisionCompactions.get(dbArg);
339
- if (!state) {
340
- state = { entries: new Map(), running: new Map(), controller: new AbortController() };
341
- revisionCompactions.set(dbArg, state);
342
- }
343
- const compactions = state;
344
- for (const id of idsArg) {
345
- const entries = (compactions.entries.get(id) ?? 0) + 1;
346
- if (entries < compactionEntries || compactions.running.has(id)) {
347
- compactions.entries.set(id, entries);
348
- continue;
349
- }
350
- compactions.entries.delete(id);
351
- const signal = compactions.controller.signal;
352
- const compaction = compactWriteRevisionEntries(dbArg, id, signal)
353
- .catch((errorArg) => {
354
- if (signal.aborted)
355
- return;
356
- logger.log('warn', `Compacting the write revisions of "${id}" failed; a later compaction retries: ${errorArg instanceof Error ? errorArg.message : String(errorArg)}`);
357
- })
358
- .finally(() => { compactions.running.delete(id); });
359
- compactions.running.set(id, compaction);
360
- }
361
- };
362
- /** @internal Aborts the database's compactions and waits until they settled; `close()` calls it. */
363
- export const stopSmartdataWriteRevisionCompactions = async (dbArg) => {
364
- const state = revisionCompactions.get(dbArg);
365
- if (!state)
366
- return;
367
- revisionCompactions.delete(dbArg);
368
- state.controller.abort();
369
- await Promise.allSettled(state.running.values());
370
- };
371
408
  /**
372
409
  * @internal The counters of the documents a write by selector is about to
373
410
  * change, read in its transaction before it runs. Snapshot isolation makes
@@ -392,4 +429,4 @@ export const readPreviousRevisionIds = async (dbArg, collectionArg, rawSessionAr
392
429
  }
393
430
  return ids;
394
431
  };
395
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy53cml0ZXJldmlzaW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL25vc3FsZGIvY2xhc3Nlcy53cml0ZXJldmlzaW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUd4QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUVqRSxPQUFPLEVBQUUseUJBQXlCLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMvRixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBdUJ0Qyw4Q0FBOEM7QUFDOUMsTUFBTSxDQUFDLE1BQU0sNEJBQTRCLEdBQUcsNkJBQTZCLENBQUM7QUFRMUUsMkZBQTJGO0FBQzNGLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQztBQUN6Qjs7OztHQUlHO0FBQ0gsTUFBTSxjQUFjLEdBQUcsUUFBUSxDQUFDO0FBQ2hDLE1BQU0sYUFBYSxHQUFHLFFBQVEsQ0FBQztBQUMvQixpR0FBaUc7QUFDakcsTUFBTSxpQkFBaUIsR0FBRyxFQUFFLENBQUM7QUFDN0IsTUFBTSx1QkFBdUIsR0FBRyxJQUFJLENBQUM7QUFDckMsTUFBTSxtQkFBbUIsR0FBRyxLQUFLLENBQUM7QUFDbEMsTUFBTSxzQkFBc0IsR0FBRyxHQUFHLENBQUM7QUFDbkMsTUFBTSx1QkFBdUIsR0FBRyxFQUFFLENBQUM7QUFDbkMsd0ZBQXdGO0FBQ3hGLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLElBQUksQ0FBQztBQUM1QyxNQUFNLGlCQUFpQixHQUFHLEtBQUssQ0FBQztBQUVoQyxNQUFNLGVBQWUsR0FBRyxJQUFJLE9BQU8sRUFBdUIsQ0FBQztBQUUzRCw2RkFBNkY7QUFDN0YsTUFBTSxDQUFDLE1BQU0sZ0NBQWdDLEdBQUcsQ0FBQyxLQUFrQixFQUFFLFVBQW1CLEVBQVEsRUFBRTtJQUNoRyxJQUFJLFVB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
432
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy53cml0ZXJldmlzaW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL25vc3FsZGIvY2xhc3Nlcy53cml0ZXJldmlzaW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUd4QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUVqRSxPQUFPLEVBQUUseUJBQXlCLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQXlCL0YsOENBQThDO0FBQzlDLE1BQU0sQ0FBQyxNQUFNLDRCQUE0QixHQUFHLDZCQUE2QixDQUFDO0FBVTFFLDJGQUEyRjtBQUMzRixNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUM7QUFDekIscUhBQXFIO0FBQ3JILE1BQU0sY0FBYyxHQUFHLFFBQVEsQ0FBQztBQUNoQzs7O0dBR0c7QUFDSCxNQUFNLGFBQWEsR0FBRyxFQUFFLENBQUM7QUFDekIsa0dBQWtHO0FBQ2xHLE1BQU0seUJBQXlCLEdBQUcsSUFBSSxDQUFDO0FBQ3ZDLE1BQU0sc0JBQXNCLEdBQUcsR0FBRyxDQUFDO0FBQ25DLE1BQU0sdUJBQXVCLEdBQUcsRUFBRSxDQUFDO0FBQ25DLHdGQUF3RjtBQUN4RixNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxJQUFJLENBQUM7QUFDNUMsTUFBTSxpQkFBaUIsR0FBRyxLQUFLLENBQUM7QUFFaEMsTUFBTSxlQUFlLEdBQUcsSUFBSSxPQUFPLEVBQXVCLENBQUM7QUFFM0QsNkZBQTZGO0FBQzdGLE1BQU0sQ0FBQyxNQUFNLGdDQUFnQyxHQUFHLENBQUMsS0FBa0IsRUFBRSxVQUFtQixFQUFRLEVBQUU7SUFDaEcsSUFBSSxVQUFVLEtBQUssU0FBUztRQUFFLE9BQU87SUFDckMsTUFBTSxFQUFFLGNBQWMsRUFBRSxHQUFHLGlCQUFpQixDQUFDLFVBQVUsRUFBRSxDQUFDLGdCQUFnQixDQUFDLENB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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lossless.org/client",
3
- "version": "1.23.0",
3
+ "version": "1.23.1",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "registry": "https://verdaccio.lossless.digital"
package/readme.md CHANGED
@@ -125,7 +125,7 @@ Family imports preserve the established SmartData and SmartBucket names and cons
125
125
  | Subclasses need their own binding | a subclass of a bound model that declares decorators or a persistence policy of its own and no `@Collection()`, `@managed()` or `defineCollectionModel()` binding is refused with `invalid_configuration` on every read and write, so it never writes through the parent's schema; an undecorated subclass keeps the inherited binding |
126
126
  | Observing this process's writes | `db.observeWrites({ fields, listener })` — one frozen report per acknowledged model write, `{ collection, kind, documents, anchors }` with the requested top-level fields of the written documents and of the selector's equality anchors; writes inside a `db.createSession()` transaction are reported after the commit, never after a rollback; works on NoSQLDB, where `watch()` is unsupported |
127
127
  | Following this process's reads | `db.trackReads(fn)` resolves `{ result, reads }`; `reads.changed` turns true once a write this process makes through the database's models could have changed what a model read of `fn` returned, judged by the read's query and the ids it returned, and a write it cannot place counts as one that did, so a cache keyed by `reads` rebuilds only what a write touched; works on NoSQLDB |
128
- | Following every process's writes | with `new SmartdataDb({ ..., writeRevisions: { partitionField: 'organizationId' } })` in every writer, the awaited `reads.isCurrent()` counts changes per collection and partition in the write's transaction; confirmed writes of this database that leave `reads.changed` false receive exact revision allowances, while other writers and unknown outcomes stay conservative; a revision snapshot overlapping a local commit that touches its keys is unknowable; `db.invalidateTrackedReads()` states raw writes and migrations; each write inserts its own counter entry, so concurrent writers of one partition do not conflict on it, and every process of a database upgrades together; needs an engine identified as NoSQLDB, elsewhere `isCurrent()` is always false |
128
+ | Following every process's writes | with `new SmartdataDb({ ..., writeRevisions: { partitionField: 'organizationId' } })` in every writer, the awaited `reads.isCurrent()` counts changes per collection and partition in the write's transaction; confirmed writes of this database that leave `reads.changed` false receive exact revision allowances, while other writers and unknown outcomes stay conservative; a revision snapshot overlapping a local commit that touches its keys is unknowable; `db.invalidateTrackedReads()` states raw writes and migrations; overlapping transactions of one process bump separate documents of a partition's counter, so they rarely conflict on it, a check reads the counters in one query plus one for those with shards in use, and every process of a database upgrades together; needs an engine identified as NoSQLDB, elsewhere `isCurrent()` is always false |
129
129
  | Following committed writes in commit order | with `new SmartdataDb({ ..., writeLog: { fields: ['id', 'organizationId'] } })` in every writer, `db.followWrites({ fields, onWrite, onGap })` delivers each committed transaction once with its write reports: this instance's own commits at once (`origin: 'local'`), every other commit from the engine's commit journal in commit order (`origin: 'journal'`, with its `stamp`), within 250 ms while active and a second when idle; rollbacks and aborted retry attempts deliver nothing, raw writes name their collections in `unplaced`, and a follower that falls out of the journal's 15-minute retention or meets a restarted memory engine calls `onGap` and continues from the head; needs NoSQLDB 10.9.0, elsewhere the option is inert and following is refused with `unsupported_operation` |
130
130
  | Disposable test databases on a unix socket | `SmartdataTestDatabase.create({ connection: { socketPath } })` from `@lossless.org/client/testsupport` reaches an engine that listens only on a unix-domain socket, fault helpers included; the loopback `host`/`port` form is unchanged |
131
131
 
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@lossless.org/client',
6
- version: '1.23.0',
6
+ version: '1.23.1',
7
7
  description: 'One typed client for NoSQLDB, MongoDB, SQLDB, MariaDB, ClickHouse and S3 object storage.'
8
8
  }
@@ -34,7 +34,6 @@ import {
34
34
  configureSmartdataWriteRevisions,
35
35
  ensureSmartdataWriteRevisions,
36
36
  isSmartdataWriteRevisionsActive,
37
- stopSmartdataWriteRevisionCompactions,
38
37
  type ISmartdataWriteRevisionsOptions,
39
38
  } from './classes.writerevisions.js';
40
39
  import {
@@ -432,11 +431,8 @@ export class SmartdataDb {
432
431
  try {
433
432
  const closeErrors: unknown[] = [];
434
433
  try {
435
- // Followers and compactions abort at once; their reads end with the client otherwise.
436
- const backgroundStop = Promise.all([
437
- stopSmartdataWriteFollowers(this),
438
- stopSmartdataWriteRevisionCompactions(this),
439
- ]);
434
+ // Followers abort at once; their reads end with the client otherwise.
435
+ const backgroundStop = stopSmartdataWriteFollowers(this);
440
436
  if (budget) await budget.waitFor(backgroundStop);
441
437
  await backgroundStop;
442
438
  } catch (errorArg) {
@@ -37,10 +37,10 @@ import {
37
37
  type ISmartdataReadSpec,
38
38
  } from './classes.readtracker.js';
39
39
  import {
40
- beginSmartdataWriteRevisionCommit,
40
+ beginSmartdataWriteRevisionAttempt,
41
41
  flushSmartdataWriteRevisions,
42
42
  isSmartdataWriteRevisionsActive,
43
- noteSmartdataWriteRevisionEntries,
43
+ type ISmartdataWriteRevisionAttempt,
44
44
  readPreviousRevisionIds,
45
45
  sharedRevisionId,
46
46
  writeRevisionsPartitionField,
@@ -82,6 +82,8 @@ interface ISmartdataSessionBinding {
82
82
  transactionWrites: ISmartdataTransactionWrite[];
83
83
  /** The write-revision counters the current attempt's writes bump right before its commit. */
84
84
  revisionBumps: Set<string>;
85
+ /** The slots of those counters the current attempt holds. */
86
+ revisionAttempt?: ISmartdataWriteRevisionAttempt;
85
87
  /** The reports of the current attempt's writes, which its write-log entry carries. */
86
88
  logReports: ISmartdataWriteReport[];
87
89
  /** Collections the current attempt changed in ways no report describes. */
@@ -377,12 +379,14 @@ export class SmartdataSession {
377
379
  let attemptInterruption: { error: unknown } | undefined;
378
380
  /** The session-ended rejection the last attempt failed with, and how far that transaction had got. */
379
381
  let sessionEnded: { error: SmartdataPersistenceError; end: TSmartdataTransactionEnd } | undefined;
380
- let finishRevisionCommit: (() => void) | undefined;
382
+ let revisionAttempt: ISmartdataWriteRevisionAttempt | undefined;
381
383
  /** The last attempt's write-log entry until the transaction's outcome is known. */
382
384
  let logCommit: ISmartdataWriteLogCommit | undefined;
383
385
  const runAttempt = async () => {
384
- finishRevisionCommit?.();
385
- finishRevisionCommit = undefined;
386
+ // The last attempt's slots end after this one starts, so it bumps others.
387
+ const attemptStartedAt = performance.now();
388
+ revisionAttempt?.finish(false);
389
+ revisionAttempt = beginSmartdataWriteRevisionAttempt(binding.owner, attemptStartedAt);
386
390
  // The driver starts another attempt only once the last one was aborted.
387
391
  logCommit?.settle();
388
392
  logCommit = undefined;
@@ -394,6 +398,7 @@ export class SmartdataSession {
394
398
  binding.transactionCommitReached = false;
395
399
  binding.transactionWrites = [];
396
400
  binding.revisionBumps = new Set();
401
+ binding.revisionAttempt = revisionAttempt;
397
402
  binding.logReports = [];
398
403
  binding.logUnplaced = new Set();
399
404
  callbackError = undefined;
@@ -452,8 +457,8 @@ export class SmartdataSession {
452
457
  // retried with it.
453
458
  const mongoDb = binding.client.db(binding.owner.smartdataOptions.mongoDbName);
454
459
  if (binding.revisionBumps.size > 0) {
455
- finishRevisionCommit = beginSmartdataWriteRevisionCommit(binding.owner, binding.revisionBumps);
456
- await flushSmartdataWriteRevisions(mongoDb, binding.rawSession, binding.revisionBumps, signal);
460
+ revisionAttempt.commit();
461
+ await flushSmartdataWriteRevisions(mongoDb, binding.rawSession, revisionAttempt.slots, signal);
457
462
  }
458
463
  logCommit = await flushSmartdataWriteLog(
459
464
  binding.owner,
@@ -557,7 +562,7 @@ export class SmartdataSession {
557
562
  throw rejectTransaction(error, outcome);
558
563
  } finally {
559
564
  if (!returnedFromCommit) {
560
- finishRevisionCommit?.();
565
+ revisionAttempt?.finish(false);
561
566
  logCommit?.settle();
562
567
  }
563
568
  binding.transactionActive = false;
@@ -569,6 +574,7 @@ export class SmartdataSession {
569
574
  binding.transactionEnded = undefined;
570
575
  binding.transactionWrites = [];
571
576
  binding.revisionBumps = new Set();
577
+ binding.revisionAttempt = undefined;
572
578
  binding.logReports = [];
573
579
  binding.logUnplaced = new Set();
574
580
  }
@@ -578,7 +584,7 @@ export class SmartdataSession {
578
584
  try {
579
585
  if (outcome === 'unknown') changeReadsOfTransaction(committedWrites);
580
586
  } finally {
581
- finishRevisionCommit?.();
587
+ revisionAttempt?.finish(false);
582
588
  }
583
589
  throw rejectTransaction(createTransactionSessionEndedError(transactionEnded), outcome);
584
590
  }
@@ -586,9 +592,8 @@ export class SmartdataSession {
586
592
  changeReadsOfTransaction(committedWrites);
587
593
  accountSmartdataOwnWriteRevisions(binding.owner, committedRevisionBumps);
588
594
  } finally {
589
- finishRevisionCommit?.();
595
+ revisionAttempt?.finish(true);
590
596
  }
591
- noteSmartdataWriteRevisionEntries(binding.owner, committedRevisionBumps);
592
597
  for (const write of committedWrites) {
593
598
  write.deliver?.();
594
599
  }
@@ -1051,7 +1056,10 @@ const bumpTransactionRevisions = (
1051
1056
  ): void => {
1052
1057
  const attempt = transactionContext.getStore()?.attempt;
1053
1058
  if (attempt === undefined || attempt !== bindingArg.transactionAttempt) return;
1054
- for (const id of idsArg) bindingArg.revisionBumps.add(id);
1059
+ for (const id of idsArg) {
1060
+ bindingArg.revisionBumps.add(id);
1061
+ bindingArg.revisionAttempt?.bump(id);
1062
+ }
1055
1063
  };
1056
1064
 
1057
1065
  /**