From 1aa0ca7a15e20532959d8f3ee54930c38b46e67f Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Wed, 8 Mar 2017 13:54:51 +0000 Subject: [PATCH] Created Design: Node Messaging API (markdown) --- Design:-Node-Messaging-API.md | 93 +++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 Design:-Node-Messaging-API.md diff --git a/Design:-Node-Messaging-API.md b/Design:-Node-Messaging-API.md new file mode 100644 index 0000000..a9dcf30 --- /dev/null +++ b/Design:-Node-Messaging-API.md @@ -0,0 +1,93 @@ +The current mechanism for a node to handle messages is as follows: + + - a handler is registered for the `input` event + - within that handler a node can call `this.send()` as many times as it wants + - if an error is hit, it can call `this.error(err,msg)` + +``` +var node = this; +this.on('input', function(msg) { + // do something with 'msg' + if (!err) { + node.send(msg); + } else { + node.error(err,msg); + } +}); +``` + +This simple system has a few limitations that we want to address: + + 1. we cannot correlate a message being received with one being sent - particularly when there is async code involved in the handler + 2. we do not know if a node has finished processing a received message + 3. due to 1 & 2, we cannot build any timeout feature into the node + 4. we know of a use case where an embedder of node-red requires nodes to be strictly one-in, one-out, and that should be policed by the runtime. Putting aside the specifics, we cannot provide any such mode of operation with the current model + +This design note explores how this mechanism could be updated to satisfy these limitations. + +--- + +### Option 1: Add a `node.complete` function - v1 + +The first proposal is to add a new function to the Node object that can be called when a node has finished handling a message. + +``` +this.on('input', function(msg) { + // do something with 'msg' + if (!err) { + node.send(msg); + } else { + node.error(err,msg); + } + node.complete(msg); +}); +``` + + - this relies on the user passing msg through - something that could be a source of programming error. + - it would need clear semantics over when it was called and how it relates to `node.error`. + +### Option 2: Add a `node.complete` function - v2 + +The second proposal is similar to the first, but the `complete` function can also be used to indicate a failure: + +``` +this.on('input', function(msg) { + // do something with 'msg' + if (!err) { + node.send(msg); + node.complete(msg); + } else { + // Log the error, but don't provide the msg obj here + node.error(err); + // Provide the err - which will trigger any Catch nodes + node.complete(msg,err); + } +}); +``` + + - this relies on the user passing msg through - something that could be a source of programming error. + - it would need clear semantics over when it was called and how it relates to `node.error`. + + +### Option 3: Pass in scoped `send` and `done` functions + +If the event handler is registered with three arguments, the runtime will pass in functions that should be used to send or mark the msg as handled. + +``` +this.on('input', function(msg, send, done) { + // do something with 'msg' + if (!err) { + send(msg); + done(); + } else { + // Log the error, but don't provide the msg obj here + done(err); + } +}); +``` + + - this feels the most 'node.js-like'. The presence of a `done` callback is familiar to many apis. Calling it + without an argument is considered success, with an argument is considered failure. + - the functions can be scoped to the received message so the node does not need to provide the message back + - the runtime can tell if the handler expects these extra arguments or not, so can adapt its behaviour to match + - need to consider whether the node should still be allowed to use `node.send` and `node.error` directly. It would be possible to disable either of these functions if we see this new style message handler registered. There is certainly a case to support `node.error` regardless - a single message can legitimately trigger multiple errors. \ No newline at end of file