@signalk/tracks-plugin 3.0.1 → 3.0.3

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.
@@ -12,15 +12,68 @@ Neither is simply better than the other, which is why both are used.
12
12
  | Size | small | far larger, which is why retention exists |
13
13
 
14
14
  The plugin writes its positions to a SQLite file in its data directory, so they
15
- survive a restart. How long they are kept depends on two settings: the own
16
- vessel's track is kept indefinitely by default, and another vessel is dropped
17
- 30 days after its last fix.
15
+ survive a restart. A power cut can still lose the most recent ones, because
16
+ they are not forced onto the storage one at a time (on an SD card each such
17
+ write can take seconds), but it cannot damage the file. How long they are kept
18
+ depends on two settings: the own vessel's track is kept indefinitely by
19
+ default, and another vessel is dropped 30 days after its last fix.
18
20
 
19
21
  So the provider is the finer record of the recent past, and the plugin's store
20
22
  is what remains of everything older. The interval and the retention are both
21
23
  settings on the plugin's configuration page, which is where their current
22
24
  defaults are shown.
23
25
 
26
+ ## Storage responsiveness and shutdown
27
+
28
+ SQLite runs in a dedicated worker, including opening the database, queries,
29
+ pruning and WAL checkpointing. A slow storage operation therefore does not block
30
+ the Signal K server's event loop. This does not make slow storage faster: a track
31
+ query can still wait behind earlier writes, while unrelated server requests can
32
+ continue. Large query results still arrive via structured cloning, and their
33
+ materialization and HTTP serialization take main-thread time, so the worker
34
+ does not remove every source of server latency.
35
+
36
+ Positions retain their arrival timestamp (or the supplied observation timestamp)
37
+ and coordinates are copied when accepted. Operations are ordered, with one batch
38
+ in flight; the entire adjacent waiting mutation run commits in one transaction,
39
+ bounded by the same queue byte/item limits. Positions
40
+ inside a context's resolution window are discarded before cloning/admission;
41
+ the worker also retains the store's throttle as a consistency guard. There is no
42
+ extra batching delay or change to the configured recording resolution, spatial
43
+ filters or schema. SQLite uses WAL with `synchronous=NORMAL`, so a commit does
44
+ not sync; the only syncs are the checkpoints, which run in the worker too.
45
+ Persisted vessel names are cached from
46
+ worker-acknowledged writes; the live data model still takes precedence.
47
+
48
+ Pending operations are bounded to 10,000 items / 8 MiB of serialized arguments,
49
+ including the batch in flight. If recording exceeds either limit, a plugin error
50
+ pauses further recording while accepted work drains. Recording automatically
51
+ resumes once both item and byte usage reach at most half capacity. The plugin
52
+ logs the gap's start time and dropped operation count (operations include names
53
+ and maintenance, not just positions). Dropped samples are not replayed.
54
+
55
+ A failed write transaction stops subsequent writes until a plugin restart;
56
+ uncertain writes are never retried. A successful rollback leaves the database
57
+ open, so History and v1 queries can still read committed tracks, including when
58
+ storage is full. Startup, worker exit or an uncertain rollback fail the whole
59
+ store. These errors remain visible instead of being replaced by healthy status.
60
+
61
+ Stopping unsubscribes input immediately, then returns a Promise that resolves
62
+ only after accepted work drains, SQLite closes and the worker exits. Plugin
63
+ lifecycle callers must await `stop()` before restarting or removing its data
64
+ directory. `start()` returns the initialization Promise; track requests submitted
65
+ during initialization wait behind it. This drain covers callers that actually
66
+ invoke and await `stop()`, such as a settings change or disabling the plugin.
67
+ The current server shutdown path does not guarantee that: a server restart can
68
+ lose accepted queued samples even on an otherwise orderly process shutdown.
69
+ Do not assume the plugin's async stop promise is awaited by the server.
70
+
71
+ Accepted but uncommitted data is still in RAM. Abrupt power loss or forced process
72
+ termination can lose pending samples; worker isolation does not promise zero data
73
+ loss. Committed records are not synced one by one either, so a power cut can
74
+ also lose the most recent of them, though never damage the file. Rollback of plugin code
75
+ must never replace the database with an older copy over newly recorded tracks.
76
+
24
77
  ## What you get with no history provider
25
78
 
26
79
  Everything comes from the plugin's own store, at whatever interval it is
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signalk/tracks-plugin",
3
- "version": "3.0.1",
3
+ "version": "3.0.3",
4
4
  "description": "Plugin to keep track of tracks of vessels",
5
5
  "type": "module",
6
6
  "exports": {