diff --git a/client.js b/client.js index 9bd28fb6..324d04be 100644 --- a/client.js +++ b/client.js @@ -297,6 +297,20 @@ class InstanceConnection extends link.Link { link.attachAllMessages(this); } + async forwardEventToInstance(message, event) { + let instanceId = message.data.instance_id; + if (!this.slave.instanceInfos.has(instanceId)) { + // Instance is probably on another slave + await this.slave.forwardEventToMaster(message, event); + return; + } + + let instanceConnection = this.slave.instanceConnections.get(instanceId); + if (!instanceConnection) { return; } + + event.send(instanceConnection, message.data); + } + async forwardEventToMaster(message, event) { event.send(this.slave, message.data); } @@ -388,6 +402,16 @@ class Slave extends link.Link { return await request.send(instanceConnection, message.data); } + async forwardEventToInstance(message, event) { + let instanceId = message.data.instance_id; + if (!this.instanceInfos.has(instanceId)) { return; } + + let instanceConnection = this.instanceConnections.get(instanceId); + if (!instanceConnection) { return; } + + event.send(instanceConnection, message.data); + } + async broadcastEventToInstance(message, event) { for (let instanceConnection of this.instanceConnections.values()) { event.send(instanceConnection, message.data); diff --git a/lib/link/messages.js b/lib/link/messages.js index a385262f..bd76e4c9 100644 --- a/lib/link/messages.js +++ b/lib/link/messages.js @@ -311,8 +311,9 @@ class Event { * Links this event is valid on. Takes an array of strings * containing "-" specifications. * @param {?string} forwardTo - - * Optional target to forward this request to. Only 'master' is - * currently supported. + * Optional target to forward this request to. Supported values are + * 'master' and 'instance'. If set to 'instance' an instance_id + * property is implicity added to eventProperties. * @param {?string} broadcastTo - * Optional target to broadcast this event to. Only 'instance' is * currently supported. An event will only be broadcast towards @@ -329,7 +330,12 @@ class Event { this.forwardTo = forwardTo; this.broadcastTo = broadcastTo; - if (forwardTo !== 'master' && forwardTo !== null) { + if (forwardTo === 'instance') { + eventProperties = Object.assign( + {"instance_id": { type: "integer" }}, eventProperties + ); + + } else if (forwardTo !== 'master' && forwardTo !== null) { throw new Error(`Invalid forwardTo value ${forwardTo}`); } @@ -358,10 +364,11 @@ class Event { * for the event. * * If forwardTo was set to 'master' the `forwardEventToMaster` method on - * the link is used as the default handler. + * the link is used as the default handler. If it was set to 'instance' + * the `forwardEventToInstance` method on the link is used by default. * * If broadcastTo was set to 'instance' the `broadcastEventToInstance` - * method on the link is invoked before the handler. BUT HOW? + * method on the link is invoked before the handler. * * Does nothing if the link is not a target for this event. * @@ -376,7 +383,9 @@ class Event { if (this.links.includes(`${link.target}-${link.source}`)) { // Use forwarder if handler is not present. if (!handler) { - if (this.forwardTo === 'master') { + if (this.forwardTo === 'instance') { + handler = link.forwardEventToInstance; + } else if (this.forwardTo === 'master') { handler = link.forwardEventToMaster; } } diff --git a/master.js b/master.js index 244e8f73..e1aaa713 100644 --- a/master.js +++ b/master.js @@ -268,6 +268,16 @@ class BaseConnection extends link.Link { return await request.send(connection, message.data); } + async forwardEventToInstance(message, event) { + let instance = db.instance.get(message.data.instance_id); + if (!instance) { return; } + + let connection = slaveConnection.get(instance.slaveId); + if (!connection) { return; } + + event.send(connection, message.data); + } + async broadcastEventToInstance(message, event) { for (let slaveConnection of slaveConnections.values()) { if (slaveConnection === this) {