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 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
- await client.write(lineProtocol, targetDatabase);
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.9",
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.2.0"
45
+ "@influxdata/influxdb3-client": "^2.3.0"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@eslint/js": "^10.0.1",