signalk-maintenance-tracker 1.1.0 → 1.1.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.
- package/CHANGELOG.md +12 -0
- package/dist/signalk/runtime.js +49 -7
- package/dist/signalk/runtime.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
# v1.1.1
|
|
2
|
+
|
|
3
|
+
A small release with one important fix for your SD card's lifespan.
|
|
4
|
+
|
|
5
|
+
## Fixes
|
|
6
|
+
|
|
7
|
+
- **Runtime updates no longer hammer the disk.** Every SignalK runtime delta
|
|
8
|
+
was written straight to the database — up to several commits (and disk syncs)
|
|
9
|
+
per second while the engine was running. Runtime values are now kept in
|
|
10
|
+
memory and flushed in a single transaction at most once per minute, with a
|
|
11
|
+
final flush on shutdown so engine hours still survive restarts.
|
|
12
|
+
|
|
1
13
|
# v1.1.0
|
|
2
14
|
|
|
3
15
|
This release teaches Maintenance Tracker to talk to your spares locker, adds
|
package/dist/signalk/runtime.js
CHANGED
|
@@ -1,25 +1,35 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RuntimeManager = void 0;
|
|
3
|
+
exports.RuntimeManager = exports.FLUSH_INTERVAL_MS = void 0;
|
|
4
|
+
/** Floor between runtime_cache commits — deltas can arrive many times per
|
|
5
|
+
* second, and persisting each one hammers the disk. */
|
|
6
|
+
exports.FLUSH_INTERVAL_MS = 60_000;
|
|
4
7
|
/**
|
|
5
8
|
* Subscribes to the union of all task runtime paths on vessels.self, keeps an
|
|
6
9
|
* in-memory map of the latest value, and persists it to runtime_cache so
|
|
7
10
|
* values survive restarts (§10.2).
|
|
8
11
|
*
|
|
12
|
+
* Deltas only touch the in-memory map; dirty values are flushed to the DB in
|
|
13
|
+
* one transaction at most once per FLUSH_INTERVAL_MS (and on stop()).
|
|
14
|
+
*
|
|
9
15
|
* This is the single seconds→hours conversion boundary: SignalK runtime paths
|
|
10
16
|
* are seconds; everything stored/returned here is hours.
|
|
11
17
|
*/
|
|
12
18
|
class RuntimeManager {
|
|
13
19
|
app;
|
|
14
20
|
db;
|
|
21
|
+
flushIntervalMs;
|
|
15
22
|
values = new Map();
|
|
16
23
|
paths = [];
|
|
17
24
|
unsubscribes = [];
|
|
18
25
|
listeners = [];
|
|
19
26
|
lastUpdate = null;
|
|
20
|
-
|
|
27
|
+
dirty = new Set();
|
|
28
|
+
flushTimer = null;
|
|
29
|
+
constructor(app, db, flushIntervalMs = exports.FLUSH_INTERVAL_MS) {
|
|
21
30
|
this.app = app;
|
|
22
31
|
this.db = db;
|
|
32
|
+
this.flushIntervalMs = flushIntervalMs;
|
|
23
33
|
this.loadCache();
|
|
24
34
|
}
|
|
25
35
|
loadCache() {
|
|
@@ -71,19 +81,51 @@ class RuntimeManager {
|
|
|
71
81
|
const hours = v.value / 3600; // SignalK runtime is seconds (§10.2)
|
|
72
82
|
const timestamp = new Date().toISOString();
|
|
73
83
|
this.values.set(v.path, { value: hours, timestamp });
|
|
74
|
-
this.
|
|
75
|
-
.prepare(`INSERT INTO runtime_cache (path, value, timestamp) VALUES (?, ?, ?)
|
|
76
|
-
ON CONFLICT(path) DO UPDATE SET value = excluded.value, timestamp = excluded.timestamp`)
|
|
77
|
-
.run(v.path, hours, timestamp);
|
|
84
|
+
this.dirty.add(v.path);
|
|
78
85
|
this.lastUpdate = timestamp;
|
|
79
86
|
changed = true;
|
|
80
87
|
}
|
|
81
88
|
}
|
|
82
|
-
if (changed)
|
|
89
|
+
if (changed) {
|
|
90
|
+
this.scheduleFlush();
|
|
83
91
|
for (const fn of this.listeners)
|
|
84
92
|
fn();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
scheduleFlush() {
|
|
96
|
+
if (this.flushTimer)
|
|
97
|
+
return;
|
|
98
|
+
this.flushTimer = setTimeout(() => this.flush(), this.flushIntervalMs);
|
|
99
|
+
this.flushTimer.unref?.();
|
|
100
|
+
}
|
|
101
|
+
/** Persist all dirty values in a single transaction. */
|
|
102
|
+
flush() {
|
|
103
|
+
if (this.flushTimer) {
|
|
104
|
+
clearTimeout(this.flushTimer);
|
|
105
|
+
this.flushTimer = null;
|
|
106
|
+
}
|
|
107
|
+
if (!this.dirty.size)
|
|
108
|
+
return;
|
|
109
|
+
const upsert = this.db.prepare(`INSERT INTO runtime_cache (path, value, timestamp) VALUES (?, ?, ?)
|
|
110
|
+
ON CONFLICT(path) DO UPDATE SET value = excluded.value, timestamp = excluded.timestamp`);
|
|
111
|
+
this.db.exec('BEGIN');
|
|
112
|
+
try {
|
|
113
|
+
for (const path of this.dirty) {
|
|
114
|
+
const entry = this.values.get(path);
|
|
115
|
+
if (entry)
|
|
116
|
+
upsert.run(path, entry.value, entry.timestamp);
|
|
117
|
+
}
|
|
118
|
+
this.db.exec('COMMIT');
|
|
119
|
+
this.dirty.clear();
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
this.db.exec('ROLLBACK');
|
|
123
|
+
this.app.error?.(`maintenance-tracker runtime cache flush failed: ${err}`);
|
|
124
|
+
}
|
|
85
125
|
}
|
|
86
126
|
stop() {
|
|
127
|
+
// Flush before the plugin closes the DB so values survive restarts.
|
|
128
|
+
this.flush();
|
|
87
129
|
this.teardown();
|
|
88
130
|
this.paths = [];
|
|
89
131
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/signalk/runtime.ts"],"names":[],"mappings":";;;AAEA
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/signalk/runtime.ts"],"names":[],"mappings":"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"}
|