sailkick-boat 0.18.0 → 0.18.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/README.md +7 -0
- package/lib/backfill/index.js +14 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -236,6 +236,13 @@ a source archive that is still being written — a `signalk-to-influxdb-v2` buck
|
|
|
236
236
|
recording — makes the first windows re-upload today's data. The timestamps are correct,
|
|
237
237
|
but it is data the cloud already has, and a lot of wasted uplink.
|
|
238
238
|
|
|
239
|
+
**Field types come from the source, not from guessing.** Queries ask InfluxDB for the
|
|
240
|
+
`#datatype` annotation explicitly. Without it the response is unannotated and types have
|
|
241
|
+
to be inferred from the text — which fails hard on a string field whose values sometimes
|
|
242
|
+
look numeric (`"8"` emitted bare as a float, `"1.2.3.4"` quoted as a string), producing
|
|
243
|
+
`422 field type conflict` and aborting the run. Integers also keep their type instead of
|
|
244
|
+
silently becoming floats.
|
|
245
|
+
|
|
239
246
|
**Dense archives are subdivided.** A window is read whole and converted in memory, and a
|
|
240
247
|
busy boat can produce millions of points an hour (54M/day was measured on a real boat —
|
|
241
248
|
about 400 MB of CSV per hour). When a window holds more than `maxRowsPerChunk` points it
|
package/lib/backfill/index.js
CHANGED
|
@@ -79,14 +79,26 @@ function createBackfill (app, options) {
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
// --- InfluxDB reads -----------------------------------------------------------
|
|
82
|
+
// Always ask for the #datatype annotation. A raw-Flux body (Content-Type
|
|
83
|
+
// application/vnd.flux) cannot carry a dialect, and InfluxDB then returns UNANNOTATED
|
|
84
|
+
// CSV — so field types have to be guessed from the text, and guessing is wrong in a
|
|
85
|
+
// way that breaks the write outright.
|
|
86
|
+
//
|
|
87
|
+
// The case that bit: a STRING field whose values sometimes look numeric. "8" is
|
|
88
|
+
// emitted bare (a float) while "1.2.3.4" is quoted (a string), so one batch declares
|
|
89
|
+
// two types for one field and InfluxDB rejects the lot with
|
|
90
|
+
// 422 field type conflict: input field "value" on measurement "network..."
|
|
91
|
+
// With the annotation the source declares `string` and every value is quoted
|
|
92
|
+
// consistently. Integers keep their `i` suffix too, instead of silently becoming
|
|
93
|
+
// floats.
|
|
82
94
|
async function flux (conn, body) {
|
|
83
95
|
const url = `${conn.url.replace(/\/+$/, '')}/api/v2/query?org=${encodeURIComponent(conn.org)}`
|
|
84
96
|
let resp
|
|
85
97
|
try {
|
|
86
98
|
resp = await fetch(url, {
|
|
87
99
|
method: 'POST',
|
|
88
|
-
headers: { Authorization: `Token ${conn.token}`, 'Content-Type': 'application/
|
|
89
|
-
body,
|
|
100
|
+
headers: { Authorization: `Token ${conn.token}`, 'Content-Type': 'application/json', Accept: 'application/csv' },
|
|
101
|
+
body: JSON.stringify({ type: 'flux', query: body, dialect: { header: true, annotations: ['datatype'] } }),
|
|
90
102
|
signal: AbortSignal.timeout(cfg.queryTimeoutMs)
|
|
91
103
|
})
|
|
92
104
|
} catch (e) { return { ok: false, message: e.message } }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sailkick-boat",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.1",
|
|
4
4
|
"description": "EARLY ALPHA — cloud telemetry + offline maps for sailkick boats (www.sailkick.io; register on the web, paste the write token). Gapless boat→cloud telemetry sync to InfluxDB, and a local proxy that keeps the sailkick app and its charts/maps working fully offline on board.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|