node-red-contrib-influxdb3 1.0.9 → 1.1.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/README.md +12 -0
- package/influxdb3.html +35 -1
- package/influxdb3.js +54 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -64,6 +64,18 @@ Writes data points to InfluxDB v3.
|
|
|
64
64
|
- **Name**: Optional node name
|
|
65
65
|
- **Measurement**: Default measurement name (can be overridden by `msg.measurement`)
|
|
66
66
|
- **Database**: Optional database override (uses connection default if not set)
|
|
67
|
+
- **Partial writes**: Accept the valid lines of a batch even if other lines are rejected (InfluxDB 3 Core/Enterprise only)
|
|
68
|
+
- **No sync**: Respond without waiting for WAL persistence — faster writes without durability confirmation (InfluxDB 3 Core/Enterprise only)
|
|
69
|
+
|
|
70
|
+
#### Partial Writes
|
|
71
|
+
|
|
72
|
+
By default a batch write is all-or-nothing: one invalid line causes InfluxDB to reject the entire batch. With **Partial writes** enabled, InfluxDB writes the valid lines and reports the rejected ones. The node then:
|
|
73
|
+
|
|
74
|
+
- shows a yellow `partial write` status instead of an error
|
|
75
|
+
- logs a warning listing each rejected line and the reason
|
|
76
|
+
- forwards the message with the details attached as `msg.partialWriteErrors`, an array of `{ lineNumber, errorMessage, originalLine }` objects
|
|
77
|
+
|
|
78
|
+
Enabling **Partial writes** or **No sync** routes the write through the InfluxDB v3 API endpoint, which is only available on InfluxDB 3 Core and Enterprise. On other deployments (Cloud Serverless/Dedicated, Clustered) leave both options disabled — writes there use the v2-compatible endpoint, where these options are not supported and would cause writes to fail. When **No sync** is enabled without **Partial writes**, the node keeps the all-or-nothing write semantics.
|
|
67
79
|
|
|
68
80
|
## Usage
|
|
69
81
|
|
package/influxdb3.html
CHANGED
|
@@ -86,7 +86,9 @@
|
|
|
86
86
|
influxdb: { type: 'influxdb3-config', required: true },
|
|
87
87
|
name: { value: '' },
|
|
88
88
|
measurement: { value: '' },
|
|
89
|
-
database: { value: '' }
|
|
89
|
+
database: { value: '' },
|
|
90
|
+
allowPartialWrites: { value: false },
|
|
91
|
+
noSync: { value: false }
|
|
90
92
|
},
|
|
91
93
|
inputs: 1,
|
|
92
94
|
outputs: 1,
|
|
@@ -117,6 +119,16 @@
|
|
|
117
119
|
<label for="node-input-database"><i class="fa fa-database"></i> Database</label>
|
|
118
120
|
<input type="text" id="node-input-database" placeholder="Override default database (optional)">
|
|
119
121
|
</div>
|
|
122
|
+
<div class="form-row">
|
|
123
|
+
<label for="node-input-allowPartialWrites"><i class="fa fa-tasks"></i> Partial writes</label>
|
|
124
|
+
<input type="checkbox" id="node-input-allowPartialWrites" style="width:auto;">
|
|
125
|
+
<span>Allow partial writes (InfluxDB 3 Core/Enterprise only)</span>
|
|
126
|
+
</div>
|
|
127
|
+
<div class="form-row">
|
|
128
|
+
<label for="node-input-noSync"><i class="fa fa-bolt"></i> No sync</label>
|
|
129
|
+
<input type="checkbox" id="node-input-noSync" style="width:auto;">
|
|
130
|
+
<span>Don't wait for WAL persistence (InfluxDB 3 Core/Enterprise only)</span>
|
|
131
|
+
</div>
|
|
120
132
|
</script>
|
|
121
133
|
|
|
122
134
|
<script type="text/html" data-help-name="influxdb3-write">
|
|
@@ -144,6 +156,10 @@
|
|
|
144
156
|
<dl class="message-properties">
|
|
145
157
|
<dt>payload <span class="property-type">object</span></dt>
|
|
146
158
|
<dd>The original payload is passed through</dd>
|
|
159
|
+
<dt class="optional">partialWriteErrors <span class="property-type">array</span></dt>
|
|
160
|
+
<dd>Only set when a partial write occurred (see <b>Partial writes</b> below).
|
|
161
|
+
An array of <code>{ lineNumber, errorMessage, originalLine }</code> objects
|
|
162
|
+
describing the lines InfluxDB rejected</dd>
|
|
147
163
|
</dl>
|
|
148
164
|
|
|
149
165
|
<h3>Details</h3>
|
|
@@ -213,8 +229,26 @@
|
|
|
213
229
|
<dd>The measurement name to use. Can be overridden by <code>msg.measurement</code></dd>
|
|
214
230
|
<dt>Database</dt>
|
|
215
231
|
<dd>Optional database override. If not set, uses the database from the connection config</dd>
|
|
232
|
+
<dt>Partial writes</dt>
|
|
233
|
+
<dd>When enabled, InfluxDB accepts the valid lines of a batch even if other lines
|
|
234
|
+
are rejected (InfluxDB 3 Core/Enterprise only)</dd>
|
|
235
|
+
<dt>No sync</dt>
|
|
236
|
+
<dd>When enabled, InfluxDB responds without waiting for WAL persistence — faster
|
|
237
|
+
writes but no durability confirmation (InfluxDB 3 Core/Enterprise only)</dd>
|
|
216
238
|
</dl>
|
|
217
239
|
|
|
240
|
+
<h3>Partial writes</h3>
|
|
241
|
+
<p>By default a batch write is all-or-nothing: one invalid line causes InfluxDB to
|
|
242
|
+
reject the entire batch. With <b>Partial writes</b> enabled, the valid lines are
|
|
243
|
+
written and the rejected lines are reported: the node shows a yellow
|
|
244
|
+
<i>partial write</i> status, logs a warning with the per-line errors, and forwards
|
|
245
|
+
the message with the details in <code>msg.partialWriteErrors</code>.</p>
|
|
246
|
+
<p>Enabling <b>Partial writes</b> or <b>No sync</b> sends the write through the
|
|
247
|
+
InfluxDB v3 API endpoint, which is only available on InfluxDB 3 Core and
|
|
248
|
+
Enterprise. On other deployments (Cloud Serverless/Dedicated, Clustered) leave
|
|
249
|
+
both options disabled — writes there use the v2-compatible endpoint, where these
|
|
250
|
+
options are not supported.</p>
|
|
251
|
+
|
|
218
252
|
<h3>Examples</h3>
|
|
219
253
|
<h4>Example 1: Simple temperature reading</h4>
|
|
220
254
|
<pre>msg.measurement = "temperature";
|
package/influxdb3.js
CHANGED
|
@@ -12,7 +12,7 @@ module.exports = function(RED) {
|
|
|
12
12
|
// Point.setTag(name, value)
|
|
13
13
|
// Point.setTimestamp(date)
|
|
14
14
|
// Point.toLineProtocol()
|
|
15
|
-
const { InfluxDBClient, Point } = require('@influxdata/influxdb3-client');
|
|
15
|
+
const { InfluxDBClient, Point, PartialWriteError } = require('@influxdata/influxdb3-client');
|
|
16
16
|
const fs = require('fs');
|
|
17
17
|
const { validateLineProtocol } = require('./lib/line-protocol');
|
|
18
18
|
|
|
@@ -155,6 +155,10 @@ module.exports = function(RED) {
|
|
|
155
155
|
this.influxdb = RED.nodes.getNode(config.influxdb);
|
|
156
156
|
this.measurement = config.measurement;
|
|
157
157
|
this.database = config.database;
|
|
158
|
+
/** @type {boolean} */
|
|
159
|
+
this.allowPartialWrites = config.allowPartialWrites === true;
|
|
160
|
+
/** @type {boolean} */
|
|
161
|
+
this.noSync = config.noSync === true;
|
|
158
162
|
|
|
159
163
|
const node = this;
|
|
160
164
|
let statusTimeout = null;
|
|
@@ -516,8 +520,29 @@ module.exports = function(RED) {
|
|
|
516
520
|
);
|
|
517
521
|
}
|
|
518
522
|
|
|
523
|
+
// Both acceptPartial and noSync exist only on the V3 API endpoint,
|
|
524
|
+
// so opting into either selects it. With neither enabled, no write
|
|
525
|
+
// options are passed and the client default (V2 endpoint) is used,
|
|
526
|
+
// preserving previous behaviour.
|
|
527
|
+
let writeOptions = null;
|
|
528
|
+
if (node.allowPartialWrites || node.noSync) {
|
|
529
|
+
writeOptions = { useV2Api: false };
|
|
530
|
+
if (node.noSync) {
|
|
531
|
+
writeOptions.noSync = true;
|
|
532
|
+
}
|
|
533
|
+
if (!node.allowPartialWrites) {
|
|
534
|
+
// noSync without partial writes: keep the all-or-nothing
|
|
535
|
+
// semantics the V2 endpoint would have provided.
|
|
536
|
+
writeOptions.acceptPartial = false;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
|
|
519
540
|
// Write to InfluxDB
|
|
520
|
-
|
|
541
|
+
if (writeOptions) {
|
|
542
|
+
await client.write(lineProtocol, targetDatabase, undefined, writeOptions);
|
|
543
|
+
} else {
|
|
544
|
+
await client.write(lineProtocol, targetDatabase);
|
|
545
|
+
}
|
|
521
546
|
|
|
522
547
|
setStatus({ fill: 'green', shape: 'dot', text: 'written' }, 3000);
|
|
523
548
|
|
|
@@ -525,6 +550,33 @@ module.exports = function(RED) {
|
|
|
525
550
|
done();
|
|
526
551
|
|
|
527
552
|
} catch (error) {
|
|
553
|
+
// The client raises PartialWriteError both when the server accepted
|
|
554
|
+
// the valid lines (partial write occurred) and when it rejected the
|
|
555
|
+
// whole batch (acceptPartial=false). Only the former is a partial
|
|
556
|
+
// success; the server signals it with this specific error text.
|
|
557
|
+
if (node.allowPartialWrites &&
|
|
558
|
+
error instanceof PartialWriteError &&
|
|
559
|
+
typeof error.message === 'string' &&
|
|
560
|
+
error.message.toLowerCase().includes('partial write')) {
|
|
561
|
+
const lineErrors = error.lineErrors || [];
|
|
562
|
+
const detail = lineErrors
|
|
563
|
+
.map((le) => `line ${le.lineNumber}: ${le.errorMessage}`)
|
|
564
|
+
.join('; ');
|
|
565
|
+
node.warn(
|
|
566
|
+
`Partial write: InfluxDB rejected ${lineErrors.length} line(s), ` +
|
|
567
|
+
`the remaining lines were written. ${detail}`
|
|
568
|
+
);
|
|
569
|
+
msg.partialWriteErrors = lineErrors;
|
|
570
|
+
setStatus({
|
|
571
|
+
fill: 'yellow',
|
|
572
|
+
shape: 'dot',
|
|
573
|
+
text: `partial write: ${lineErrors.length} line(s) rejected`
|
|
574
|
+
});
|
|
575
|
+
send(msg);
|
|
576
|
+
done();
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
|
|
528
580
|
const shortMsg = error.message
|
|
529
581
|
? (error.message.length > 80 ? error.message.substring(0, 80) + '...' : error.message)
|
|
530
582
|
: 'unknown error';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-influxdb3",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Node-RED nodes for InfluxDB v3 integration",
|
|
5
5
|
"main": "influxdb3.js",
|
|
6
6
|
"files": [
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@influxdata/influxdb3-client": "^2.
|
|
45
|
+
"@influxdata/influxdb3-client": "^2.3.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@eslint/js": "^10.0.1",
|