signalk-aiscast 0.3.1 → 0.4.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.0
4
+
5
+ - The offline queue writes far less to the SD card. Each queue file used to be rewritten from scratch every fifteen seconds as sentences were added to it, so a boat at anchor hearing a slow trickle of traffic wrote the same data to the card a dozen times over. Sentences are now appended to the end of a file and nothing is rewritten, which on a quiet anchorage cuts the writing to a fraction of what it was.
6
+ - A replay the server only partly accepts no longer rewrites anything on disk, and a queue file damaged by a power cut costs one sentence instead of the five hundred it was sharing a file with.
7
+ - The queue keeps working when the plugin cannot delete a file, as happens when an SD card turns read-only. A queue file that could neither be read nor removed used to stop the replay where it stood until the next reconnect, and files the server had already taken could be left behind in a way that made the 100 MB cap discard data that had not been sent yet. Files that will not delete are now set aside, retried in the background, and never replayed.
8
+
3
9
  ## 0.3.1
4
10
 
5
11
  - Fixes a queue that never emptied. While the plugin was replaying a backlog to aiscast it wrote every sentence its receiver heard to a new queue file, so it traded one file for another and the replay never reached the end. On a boat that had been offline a while, the queue directory stayed at tens of thousands of files no matter how long the connection was up. A replay now carries up to a thousand sentences from as many files in one frame, and sentences heard mid-replay go out from memory.
package/dist/uplink.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { Link } from "./link.js";
2
+ export declare const SEGMENT_MAX: number;
2
3
  export interface UplinkStats {
3
4
  sent: number;
4
5
  queued: number;
@@ -22,7 +23,11 @@ export declare class Uplink {
22
23
  private seen;
23
24
  private listing;
24
25
  private sizes;
26
+ private stale;
25
27
  private bytes;
28
+ private head;
29
+ private sending;
30
+ private unwritable;
26
31
  private lastName;
27
32
  private limits;
28
33
  private paceUntil;
@@ -48,18 +53,20 @@ export declare class Uplink {
48
53
  private exclusive;
49
54
  private flush;
50
55
  private flushOnce;
51
- private write;
56
+ private append;
52
57
  private remove;
53
- private measure;
58
+ private sweep;
59
+ private repair;
60
+ private scan;
54
61
  private newName;
55
- private readQueueFile;
56
- private countQueued;
62
+ private readFrom;
57
63
  private enforceCap;
58
64
  private trim;
65
+ private countFrom;
59
66
  private drain;
60
67
  private drainLoop;
61
68
  private nextBatch;
62
- private keep;
69
+ private settle;
63
70
  private publish;
64
71
  private pruneSeen;
65
72
  }
package/dist/uplink.js CHANGED
@@ -1,14 +1,22 @@
1
- import { mkdir, readdir, readFile, rename, stat, unlink, writeFile } from "node:fs/promises";
1
+ import { appendFile, mkdir, open, readdir, readFile, truncate, unlink } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
3
  import { payloadKey, tagged } from "./nmea.js";
4
4
  const ACK_TIMEOUT = 30_000;
5
5
  const FLUSH_EVERY = 15_000; // in-memory backlog to disk; a crash loses at most this much
6
- const FILE_MAX = 500; // sentences per queue file
6
+ const FLUSH_AT = 500; // backlog sentences that bring a flush forward
7
+ export const SEGMENT_MAX = 1024 * 1024; // bytes per segment file before the next append rolls over
8
+ const READ_BYTES = 256 * 1024; // window one frame is read through; comfortably more than a full frame holds
7
9
  const QUEUE_MAX_BYTES = 100 * 1024 * 1024;
8
10
  const CAP_EVERY = 60_000;
9
11
  const SEEN_TTL = 5 * 60_000; // payloads received from aiscast are never published back within this window
10
12
  const SEEN_MAX = 20_000;
11
- const READ_BATCH = 32; // queue files read at once at start; the disk is usually an SD card
13
+ const SCAN_BATCH = 8; // segments read at once at start; the disk is usually an SD card
14
+ const NEWLINE = 0x0a;
15
+ const SUFFIX = ".log";
16
+ // Errors that say a queue entry will never be readable, whatever the disk does next. Anything else (an
17
+ // exhausted file table, a bad sector, a busy device) may clear, and a segment must not be discarded over one
18
+ // of those while the sentences in it are still there to send.
19
+ const UNREADABLE = new Set(["EISDIR", "ENOTDIR", "EACCES", "EPERM", "ELOOP", "ENAMETOOLONG"]);
12
20
  // The server's publish limits, until a welcome frame gives this station's own. A frame is truncated to
13
21
  // `frame`, and anything past `perMin` is dropped and still acked, so both have to be respected here.
14
22
  const DEFAULT_LIMITS = { frame: 1000, perMin: 6000 };
@@ -16,6 +24,12 @@ const PACE_MARGIN = 0.9; // of the per-minute limit: clock skew and jitter must
16
24
  const LIMIT_WINDOW = 60_000; // the server's publish limit resets on a window this long
17
25
  // Sends received sentences to aiscast as they arrive; anything not acked, or heard while offline, waits on disk
18
26
  // and is replayed oldest-first on the next connection before live sending resumes.
27
+ //
28
+ // The queue is a directory of append-only segments, each one newline-delimited sentences, rolled over at
29
+ // SEGMENT_MAX. Sentences are only ever appended, and a frame the server takes only advances a byte offset
30
+ // into the oldest segment, so nothing on disk is rewritten between the append that puts a sentence there and
31
+ // the unlink that drops the whole segment. That offset is in memory, so a restart replays the oldest segment
32
+ // from its start; aiscast drops the duplicates, and the replay is bounded by one segment.
19
33
  export class Uplink {
20
34
  link;
21
35
  log;
@@ -31,9 +45,13 @@ export class Uplink {
31
45
  ackTimer = null;
32
46
  capTimer = null;
33
47
  seen = new Map();
34
- listing = []; // queue file names, oldest first; the drain works from this, not readdir
35
- sizes = new Map(); // bytes per queue file, kept up to date as files come and go
48
+ listing = []; // segment names, oldest first; the drain works from this, not readdir
49
+ sizes = new Map(); // bytes per segment, kept up to date as they grow and go
50
+ stale = new Set(); // segments done with that would not delete; retried by `sweep`
36
51
  bytes = 0;
52
+ head = 0; // bytes of listing[0] the server has already taken
53
+ sending = null; // newest segment a frame in flight was read from
54
+ unwritable = null; // segment an append failed on; the next one starts elsewhere
37
55
  lastName = 0;
38
56
  limits = { ...DEFAULT_LIMITS };
39
57
  paceUntil = 0;
@@ -55,11 +73,14 @@ export class Uplink {
55
73
  }
56
74
  async start() {
57
75
  this.stopped = false;
76
+ this.head = 0;
58
77
  await mkdir(this.dir, { recursive: true });
59
- this.listing = (await readdir(this.dir)).filter((f) => f.endsWith(".json")).sort();
60
- this.lastName = Number(this.listing.at(-1)?.slice(0, -".json".length)) || 0;
61
- await this.measure();
62
- this.stats.queued = await this.countQueued();
78
+ this.listing = (await readdir(this.dir)).filter((f) => f.endsWith(SUFFIX)).sort();
79
+ this.lastName = Number(this.listing.at(-1)?.slice(0, -SUFFIX.length)) || 0;
80
+ const tail = this.listing.at(-1);
81
+ if (tail !== undefined)
82
+ await this.repair(tail);
83
+ this.stats.queued = await this.scan();
63
84
  this.link.on("open", this.onOpen);
64
85
  this.link.on("close", this.onClose);
65
86
  this.link.on("frame", this.onFrame);
@@ -115,7 +136,7 @@ export class Uplink {
115
136
  else {
116
137
  this.backlog.push(line);
117
138
  this.stats.queued++;
118
- if (this.backlog.length >= FILE_MAX)
139
+ if (this.backlog.length >= FLUSH_AT)
119
140
  this.flush();
120
141
  }
121
142
  }
@@ -205,9 +226,9 @@ export class Uplink {
205
226
  this.stats.queued += live.length;
206
227
  }
207
228
  }
208
- // Queue-file work runs one operation at a time, in order. The flush timer, the drain and the cap check all
229
+ // Queue work runs one operation at a time, in order. The flush timer, the drain and the cap check all
209
230
  // mutate the same directory and the same listing, and every one of them awaits partway through: without
210
- // this, a flush could top up a file the drain had already read and was about to delete.
231
+ // this, a flush could roll a segment the drain had already read and was about to unlink.
211
232
  exclusive(work) {
212
233
  const run = this.queueOp.then(work);
213
234
  this.queueOp = run.then(() => { }, () => { });
@@ -216,137 +237,223 @@ export class Uplink {
216
237
  flush() {
217
238
  return this.exclusive(() => this.flushOnce()).catch(() => { });
218
239
  }
219
- // Backlog → the newest queue file while it has room, then files of FILE_MAX. Topping up is what keeps a
220
- // long offline stretch from leaving a file behind every fifteen seconds: the count follows the sentences
221
- // owed, not the time spent offline. Never throws: a full or read-only disk must not take the Signal K
222
- // process down, so whatever is not on disk yet stays in the backlog and is retried next time.
240
+ // Backlog → the end of the newest segment. Appending is what keeps a long offline stretch cheap: the cost
241
+ // of a flush follows the sentences it carries, not the size of the segment they land in. Never throws: a
242
+ // full or read-only disk must not take the Signal K process down, so an append that fails leaves its
243
+ // sentences in the backlog to be retried next time.
223
244
  async flushOnce() {
224
- if (this.backlog.length === 0)
225
- return;
226
- const sentences = this.backlog;
227
- this.backlog = [];
228
- const tail = this.listing.at(-1);
229
- const room = tail ? await this.readQueueFile(tail) : null;
230
- const topUp = room !== null && room.length < FILE_MAX;
231
- const pending = topUp ? room.concat(sentences) : sentences;
232
- const onDisk = topUp ? room.length : 0; // the tail's own sentences, already safe, at the front of pending
233
- for (let i = 0; i < pending.length; i += FILE_MAX) {
234
- const name = i === 0 && topUp ? tail : this.newName();
235
- if (!(await this.write(name, pending.slice(i, i + FILE_MAX)))) {
236
- this.backlog.unshift(...pending.slice(Math.max(i, onDisk))); // keep what did not land, oldest first
237
- return;
245
+ // In batches, because the backlog is not bounded by FLUSH_AT. That only brings a flush forward, and a
246
+ // burst can pile up far past it before the first one gets its turn at the lock. One append has to stay
247
+ // small next to a segment for the rollover in `append` to bound anything.
248
+ for (let failures = 0; this.backlog.length > 0;) {
249
+ if (await this.append(this.backlog.splice(0, FLUSH_AT))) {
250
+ failures = 0;
251
+ continue;
238
252
  }
239
- if (name !== tail)
240
- this.listing.push(name); // newest name sorts last, so appending keeps the order
253
+ // One retry, which `append` starts on a new segment: the first failure may have been the entry at the
254
+ // tail rather than the disk, and that is worth finding out now rather than a flush interval from now.
255
+ if (++failures > 1)
256
+ return;
241
257
  }
242
258
  }
243
- // One queue file, written whole. The temp file keeps a half-written array from ever being picked up: the
244
- // listing only takes .json, and rename is atomic.
245
- async write(name, sentences) {
246
- const path = join(this.dir, name);
247
- const tmp = `${path}.tmp`;
248
- const data = JSON.stringify(sentences);
259
+ // One batch onto the newest segment, or onto a new one. False when it did not land, in which case the
260
+ // sentences are back at the front of the backlog.
261
+ async append(sentences) {
262
+ const data = Buffer.from(sentences.map((s) => `${s}\n`).join(""));
263
+ // Three reasons to start a segment rather than append to the newest one. A full one rolls over instead of
264
+ // splitting the append, since a batch is small next to a segment and letting one overshoot costs a little
265
+ // size and saves writing any part of it twice. One a frame in flight was read from rolls over however
266
+ // much room it has left, since that frame was read against the size it had then and appending would put
267
+ // sentences behind an end the drain has already passed. And one an append has already failed on rolls
268
+ // over whatever is wrong with it: an entry that is not a writable file would otherwise keep every later
269
+ // sentence out of the queue for as long as it sat at the tail.
270
+ const tail = this.listing.at(-1);
271
+ const fresh = tail === undefined ||
272
+ tail === this.sending ||
273
+ tail === this.unwritable ||
274
+ (this.sizes.get(tail) ?? 0) >= SEGMENT_MAX;
275
+ const name = fresh ? this.newName() : tail;
276
+ if (fresh) {
277
+ // Listed before the append, not after: a write that fails partway still leaves bytes on disk, and a
278
+ // segment nothing tracks is one the cap cannot reclaim and the drain will never look at.
279
+ this.listing.push(name); // the newest name sorts last, so appending keeps the order
280
+ this.sizes.set(name, 0);
281
+ }
249
282
  try {
250
- await writeFile(tmp, data);
251
- await rename(tmp, path);
283
+ await appendFile(join(this.dir, name), data);
252
284
  }
253
285
  catch (err) {
254
286
  this.log(`queue write failed: ${err.message}`);
255
- await unlink(tmp).catch(() => { });
287
+ // A disk that filled up can take part of an append. Cutting back to the last whole sentence and
288
+ // re-measuring leaves a clean end for the retry, which re-appends every sentence from the backlog.
289
+ await this.repair(name);
290
+ this.unwritable = name;
291
+ this.backlog.unshift(...sentences);
256
292
  return false;
257
293
  }
258
- const size = Buffer.byteLength(data);
259
- this.bytes += size - (this.sizes.get(name) ?? 0);
260
- this.sizes.set(name, size);
294
+ this.sizes.set(name, (this.sizes.get(name) ?? 0) + data.length);
295
+ this.bytes += data.length;
261
296
  return true;
262
297
  }
263
- // Deletes a queue file. False when it would not go: the caller leaves it on the listing rather than
264
- // stranding a file on disk that nothing will look at again until the next start.
298
+ // Deletes a segment whose sentences are done with, delivered or dropped. One that will not go is set aside
299
+ // for `sweep` and stops being accounted for either way: it is off the listing, so counting bytes nothing
300
+ // can reclaim would only drive the cap to discard queued sentences that are still deliverable.
265
301
  async remove(name) {
302
+ this.bytes -= this.sizes.get(name) ?? 0;
303
+ this.sizes.delete(name);
266
304
  try {
267
305
  await unlink(join(this.dir, name));
268
306
  }
269
307
  catch (err) {
308
+ if (err.code === "ENOENT")
309
+ return; // already gone is the outcome wanted
270
310
  this.log(`queue delete failed: ${err.message}`);
271
- return false;
311
+ this.stale.add(name);
312
+ }
313
+ }
314
+ // Retries the segments that would not delete. For the life of the process they are never read or replayed,
315
+ // only deleted: the server already has their sentences, or they hold none worth sending. The set is not
316
+ // kept on disk, so a restart reads them back as ordinary segments and sends them once more; that costs a
317
+ // duplicate aiscast already drops, which is cheaper than a second durable file to keep correct.
318
+ async sweep() {
319
+ for (const name of [...this.stale]) {
320
+ try {
321
+ await unlink(join(this.dir, name));
322
+ }
323
+ catch (err) {
324
+ if (err.code !== "ENOENT")
325
+ return; // still failing; again next tick
326
+ }
327
+ this.stale.delete(name);
328
+ }
329
+ }
330
+ // Cuts a segment back to its last complete sentence and brings its measured size in line with the disk. A
331
+ // crash, or an append that failed partway, can leave one ending mid-sentence, and appending to that would
332
+ // splice the next sentence onto the broken one.
333
+ async repair(name) {
334
+ const path = join(this.dir, name);
335
+ try {
336
+ const buf = await readFile(path);
337
+ const cut = buf.length > 0 && buf[buf.length - 1] !== NEWLINE ? buf.lastIndexOf(NEWLINE) + 1 : buf.length;
338
+ if (cut !== buf.length) {
339
+ await truncate(path, cut);
340
+ this.log(`queue: trimmed a half-written sentence from ${name}`);
341
+ }
342
+ this.bytes += cut - (this.sizes.get(name) ?? 0);
343
+ this.sizes.set(name, cut);
344
+ }
345
+ catch (err) {
346
+ if (err.code === "ENOENT")
347
+ return; // the append never got as far as creating it
348
+ this.log(`queue repair failed: ${err.message}`);
272
349
  }
273
- this.bytes -= this.sizes.get(name) ?? 0;
274
- this.sizes.delete(name);
275
- return true;
276
350
  }
277
- // Queue size on disk, measured once at start. Batched: a backlog of many thousands of files must not put
278
- // that many requests in flight at once.
279
- async measure() {
351
+ // Size and sentence count of every segment, measured once at start. One pass: counting needs the contents
352
+ // anyway, and the size comes off the same buffer. Batched, so a long backlog does not put every segment in
353
+ // memory at once.
354
+ async scan() {
280
355
  this.sizes.clear();
356
+ this.stale.clear();
281
357
  this.bytes = 0;
282
- for (let i = 0; i < this.listing.length; i += READ_BATCH) {
283
- const batch = this.listing.slice(i, i + READ_BATCH);
284
- const sizes = await Promise.all(batch.map((f) => stat(join(this.dir, f)).then((x) => x.size, () => 0)));
285
- sizes.forEach((size, j) => {
286
- this.sizes.set(batch[j], size);
287
- this.bytes += size;
358
+ let queued = 0;
359
+ for (let i = 0; i < this.listing.length; i += SCAN_BATCH) {
360
+ const names = this.listing.slice(i, i + SCAN_BATCH);
361
+ const read = await Promise.all(names.map((f) => readFile(join(this.dir, f)).catch(() => null)));
362
+ read.forEach((buf, j) => {
363
+ this.sizes.set(names[j], buf?.length ?? 0);
364
+ this.bytes += buf?.length ?? 0;
365
+ if (buf)
366
+ for (let k = 0; k < buf.length; k++)
367
+ if (buf[k] === NEWLINE)
368
+ queued++;
288
369
  });
289
370
  }
371
+ return queued;
290
372
  }
291
- // Monotonic, so a file written in the same millisecond as the last one cannot take its name.
373
+ // Monotonic, so a segment rolled in the same millisecond as the last one cannot take its name.
292
374
  newName() {
293
375
  const now = Date.now();
294
376
  this.lastName = now > this.lastName ? now : this.lastName + 1;
295
- return `${this.lastName}.json`;
377
+ return `${this.lastName}${SUFFIX}`;
296
378
  }
297
- async readQueueFile(name) {
379
+ // Complete sentences from one segment, starting at `from`, or why there were none.
380
+ async readFrom(name, from) {
381
+ let fh;
298
382
  try {
299
- const parsed = JSON.parse(await readFile(join(this.dir, name), "utf8"));
300
- return Array.isArray(parsed) ? parsed : null;
383
+ fh = await open(join(this.dir, name), "r");
384
+ const size = (await fh.stat()).size;
385
+ const len = Math.min(READ_BYTES, size - from);
386
+ if (len <= 0)
387
+ return "spent";
388
+ const buf = Buffer.allocUnsafe(len);
389
+ const { bytesRead } = await fh.read(buf, 0, len, from);
390
+ // Everything up to the last newline is whole. No newline at all means nothing in the window is a
391
+ // sentence a frame could carry, since no real one runs to READ_BYTES, so what is there is damage.
392
+ const cut = buf.subarray(0, bytesRead).lastIndexOf(NEWLINE);
393
+ if (cut < 0)
394
+ return "damaged";
395
+ const lines = buf.subarray(0, cut).toString("utf8").split("\n");
396
+ const to = from + cut + 1;
397
+ return { lines, widths: lines.map((l) => Buffer.byteLength(l) + 1), to, eof: to >= size };
301
398
  }
302
- catch {
303
- return null;
304
- }
305
- }
306
- // Sentences already on disk, for the status line. Read in batches: a backlog of many thousands of files
307
- // would otherwise hold up plugin start one open() at a time.
308
- async countQueued() {
309
- let n = 0;
310
- const bad = new Set();
311
- for (let i = 0; i < this.listing.length; i += READ_BATCH) {
312
- const batch = this.listing.slice(i, i + READ_BATCH);
313
- const read = await Promise.all(batch.map((f) => this.readQueueFile(f)));
314
- read.forEach((sentences, j) => {
315
- if (sentences)
316
- n += sentences.length;
317
- else
318
- bad.add(batch[j]);
319
- });
399
+ catch (err) {
400
+ const code = err.code ?? "";
401
+ if (code === "ENOENT")
402
+ return "spent";
403
+ this.log(`queue read failed: ${err.message}`);
404
+ return UNREADABLE.has(code) ? "damaged" : "failed";
320
405
  }
321
- for (const f of bad) {
322
- if (!(await this.remove(f)))
323
- bad.delete(f); // still on disk: keep it listed rather than lose track of it
406
+ finally {
407
+ await fh?.close().catch(() => { });
324
408
  }
325
- if (bad.size > 0)
326
- this.listing = this.listing.filter((f) => !bad.has(f));
327
- return n;
328
409
  }
329
- // Oldest files go when the queue outgrows its cap. This runs during a drain as well: a replay is paced,
410
+ // Oldest segments go when the queue outgrows its cap. This runs during a drain as well: a replay is paced,
330
411
  // so a receiver busy enough to outrun it would otherwise grow the queue past the cap unchecked.
331
412
  async enforceCap() {
413
+ if (this.stale.size > 0)
414
+ await this.exclusive(() => this.sweep());
332
415
  if (this.bytes <= QUEUE_MAX_BYTES)
333
416
  return; // the running total, so an idle tick touches no files at all
334
417
  await this.exclusive(() => this.trim());
335
418
  }
336
419
  async trim() {
337
- let i = 0;
338
- for (; i < this.listing.length && this.bytes > QUEUE_MAX_BYTES; i++) {
339
- const name = this.listing[i];
340
- const n = (await this.readQueueFile(name))?.length ?? 0;
341
- if (!(await this.remove(name)))
342
- break; // leave it listed: a file nothing can see is a file nothing frees
343
- this.stats.dropped += n;
344
- this.stats.queued -= n;
420
+ while (this.listing.length > 0 && this.bytes > QUEUE_MAX_BYTES) {
421
+ const name = this.listing[0];
422
+ const owed = await this.countFrom(name, this.head); // what goes is what was never sent
423
+ // Could not be read this time. The cap waits a tick rather than discard a segment whose sentences may
424
+ // still be sitting there, the same call the drain makes on a read that only failed.
425
+ if (owed === null)
426
+ break;
427
+ await this.remove(name);
428
+ this.listing.shift();
429
+ this.head = 0;
430
+ this.stats.dropped += owed;
431
+ this.stats.queued -= owed;
432
+ }
433
+ }
434
+ // Sentences a segment still owes from `from` on. Null when it could not be read this time and may read
435
+ // fine later, which the caller must not mistake for a segment that owes nothing.
436
+ async countFrom(name, from) {
437
+ try {
438
+ const buf = await readFile(join(this.dir, name));
439
+ let n = 0;
440
+ for (let i = from; i < buf.length; i++)
441
+ if (buf[i] === NEWLINE)
442
+ n++;
443
+ return n;
444
+ }
445
+ catch (err) {
446
+ const code = err.code ?? "";
447
+ if (code === "ENOENT")
448
+ return 0; // already gone, so nothing is owed
449
+ if (UNREADABLE.has(code))
450
+ return 0; // damaged: its sentences went with its contents
451
+ this.log(`queue count failed: ${err.message}`);
452
+ return null;
345
453
  }
346
- this.listing.splice(0, i);
347
454
  }
348
455
  // Replay the queue oldest-first, one frame in flight, then let live sending resume. A drain that is cut
349
- // short (socket closed, ack timeout) leaves the unacked remainder on disk for the next open.
456
+ // short (socket closed, ack timeout) leaves the head where it was, so the next one resumes there.
350
457
  drain() {
351
458
  if (this.draining) {
352
459
  this.drainAgain = true;
@@ -369,10 +476,17 @@ export class Uplink {
369
476
  return;
370
477
  const batch = await this.exclusive(() => this.nextBatch());
371
478
  if (!batch) {
372
- if (this.backlog.length === 0)
373
- return; // disk and memory both empty: live sending resumes
374
- // Sentences heard during the drain go out straight from memory. Writing them to a file only to read
375
- // it back would hand the drain a fresh file on every pass, and it would never reach the end.
479
+ if (this.backlog.length === 0) {
480
+ // Disk and memory both empty: live sending resumes, and nothing is owed whatever the running count
481
+ // says. Reconciling here is what keeps the status line honest after a segment counted at start
482
+ // turns out to be damaged, since its sentences are gone and their number went with them. Only when
483
+ // the listing is clear: a segment left alone after a failed read still holds sentences to send.
484
+ if (this.listing.length === 0)
485
+ this.stats.queued = 0;
486
+ return;
487
+ }
488
+ // Sentences heard during the drain go out straight from memory. Writing them to a segment only to
489
+ // read it back would hand the drain fresh work on every pass, and it would never reach the end.
376
490
  const chunk = this.backlog.splice(0, this.limits.frame);
377
491
  const accepted = await this.publish(chunk);
378
492
  if (accepted === null) {
@@ -383,74 +497,83 @@ export class Uplink {
383
497
  this.backlog.unshift(...chunk.slice(accepted));
384
498
  continue;
385
499
  }
386
- const chunk = batch.sentences.slice(0, this.limits.frame);
387
- const accepted = await this.publish(chunk);
388
- // Nothing acked, or the remainder would not write: the files are as they were on disk, so hand them
389
- // straight back to the next drain.
390
- const kept = accepted !== null && (await this.exclusive(() => this.keep(batch, accepted)));
391
- if (accepted === null || !kept) {
392
- this.listing.unshift(...batch.files.map((f) => f.name));
500
+ const accepted = await this.publish(batch.sentences);
501
+ // Settled either way. Never acked means nothing on disk was touched and the head never moved, so the
502
+ // next drain starts on the same sentence this one was sending; the segments still have to come back
503
+ // into play for appending. Settling reports what it actually accounted for, which is short of the ack
504
+ // when the cap took a segment out from under the frame and counted those sentences itself.
505
+ this.stats.queued -= await this.exclusive(() => this.settle(batch, accepted ?? 0));
506
+ if (accepted === null)
393
507
  return;
394
- }
395
- this.stats.queued -= accepted;
396
508
  }
397
509
  }
398
- // The oldest queued sentences, up to one frame's worth, and the files they came from. Spanning several
399
- // files per frame is what lets a backlog of thousands of small files drain in batches rather than one
400
- // round trip each.
510
+ // The oldest queued sentences, up to one frame's worth, and the segment ranges they came from. A frame is
511
+ // filled from as many segments as it takes, so segments at the head that rolled over small do not each
512
+ // cost their own round trip.
401
513
  async nextBatch() {
402
514
  const sentences = [];
403
- const files = [];
404
- while (this.listing.length > 0 && sentences.length < this.limits.frame) {
405
- const names = this.listing.slice(0, READ_BATCH); // read ahead: one open() at a time crawls on an SD card
406
- const read = await Promise.all(names.map((f) => this.readQueueFile(f)));
407
- let taken = 0;
408
- for (const queued of read) {
409
- if (!queued) {
410
- const name = names[taken];
411
- if (!(await this.remove(name)))
412
- return files.length > 0 ? { sentences, files } : null;
413
- taken++;
414
- continue;
415
- }
416
- // One oversized file still goes on its own; `keep` puts back whatever the frame did not cover.
417
- if (files.length > 0 && sentences.length + queued.length > this.limits.frame)
418
- break;
419
- sentences.push(...queued);
420
- files.push({ name: names[taken++], count: queued.length });
421
- if (sentences.length >= this.limits.frame)
515
+ const widths = [];
516
+ const chunks = [];
517
+ while (sentences.length < this.limits.frame && chunks.length < this.listing.length) {
518
+ const name = this.listing[chunks.length];
519
+ const from = chunks.length === 0 ? this.head : 0;
520
+ const got = await this.readFrom(name, from);
521
+ if (typeof got === "string") {
522
+ // A read that only failed leaves the segment alone: the disk may well come back, and discarding one
523
+ // over a full file table or a bad sector would throw away sentences still waiting to be sent. Spent
524
+ // and damaged segments go, and only from the head, since the offset belongs to the head alone.
525
+ if (got === "failed" || chunks.length > 0)
422
526
  break;
527
+ await this.remove(name);
528
+ this.listing.shift();
529
+ this.head = 0;
530
+ continue;
423
531
  }
424
- this.listing.splice(0, taken);
425
- if (taken < names.length)
426
- break; // stopped short: the frame is full
532
+ const take = Math.min(this.limits.frame - sentences.length, got.lines.length);
533
+ let to = from;
534
+ for (let j = 0; j < take; j++)
535
+ to += got.widths[j];
536
+ sentences.push(...got.lines.slice(0, take));
537
+ widths.push(...got.widths.slice(0, take));
538
+ const whole = take === got.lines.length && got.eof;
539
+ chunks.push({ name, from, to, count: take, eof: whole });
540
+ if (!whole)
541
+ break; // more of this segment is waiting: the next frame starts where this one stopped
427
542
  }
428
- return files.length > 0 ? { sentences, files } : null;
543
+ if (chunks.length === 0)
544
+ return null;
545
+ // Marked inside the lock, so no flush can land on the segment between reading it and holding it.
546
+ this.sending = chunks[chunks.length - 1].name;
547
+ return { sentences, widths, chunks };
429
548
  }
430
- // Settles the files a frame came from against what the server actually took. Files it took whole are
431
- // deleted; the one the ack stopped inside is rewritten with its own remaining tail, and the files after it
432
- // are already right on disk and only go back on the listing. So only ever one file is rewritten, and it
433
- // can only shrink: a rate-limited replay cannot pile a whole frame into a single file. False when that
434
- // rewrite failed, in which case nothing was deleted and the caller puts every file back.
435
- async keep(batch, accepted) {
436
- let start = 0; // where the file at `i` begins within batch.sentences
549
+ // Moves the head past the sentences the server actually took. Segments taken whole are unlinked, and the
550
+ // one the ack stopped inside keeps its place with the offset moved on. Nothing is rewritten, so a frame
551
+ // the server only partly took costs no writes at all. Returns how many sentences it accounted for, which
552
+ // is all the server took unless the cap reached a segment first and counted that one itself.
553
+ async settle(batch, accepted) {
554
+ this.sending = null;
437
555
  let i = 0;
438
- while (i < batch.files.length && start + batch.files[i].count <= accepted) {
439
- start += batch.files[i].count;
440
- i++;
441
- }
442
- if (i < batch.files.length && accepted > start) {
443
- const tail = batch.sentences.slice(accepted, start + batch.files[i].count);
444
- if (!(await this.write(batch.files[i].name, tail)))
445
- return false;
446
- }
447
- this.listing.unshift(...batch.files.slice(i).map((f) => f.name));
448
- for (const f of batch.files.slice(0, i)) {
449
- // A file the server has taken but that will not delete is left where it is rather than put back on the
450
- // listing: re-sending it forever is worse than the duplicate the next start makes, which aiscast drops.
451
- await this.remove(f.name);
556
+ for (const chunk of batch.chunks) {
557
+ // Trimmed by the cap while the frame was in flight, along with everything the frame drew after it.
558
+ if (this.listing[0] !== chunk.name)
559
+ return i;
560
+ if (accepted - i < chunk.count) {
561
+ let to = chunk.from;
562
+ for (let j = i; j < accepted; j++)
563
+ to += batch.widths[j];
564
+ this.head = to;
565
+ return accepted;
566
+ }
567
+ i += chunk.count;
568
+ if (!chunk.eof) {
569
+ this.head = chunk.to; // the frame filled up inside this segment; the rest of it waits
570
+ return i;
571
+ }
572
+ await this.remove(chunk.name);
573
+ this.listing.shift();
574
+ this.head = 0;
452
575
  }
453
- return true;
576
+ return i;
454
577
  }
455
578
  // One publish frame, paced to stay under the server's per-minute limit: sentences past it are dropped
456
579
  // and acked all the same, so an unpaced replay loses most of the backlog it is trying to deliver.
@@ -1 +1 @@
1
- {"version":3,"file":"uplink.js","sourceRoot":"","sources":["../src/uplink.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"uplink.js","sourceRoot":"","sources":["../src/uplink.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signalk-aiscast",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "aiscast, the Open Waters AIS network, for Signal K: show nearby traffic without an AIS receiver and share what yours hears.",
5
5
  "license": "MIT",
6
6
  "author": "Brandon Keepers <brandon@opensoul.org>",