1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Created Design: Node Messaging API (markdown)

Nick O'Leary 2017-03-08 13:54:51 +00:00
parent a39b9c7847
commit 1aa0ca7a15

@ -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.