Skip to content
This repository has been archived by the owner on Jun 11, 2024. It is now read-only.

Allow some modules to publish any event #3263

Closed
jondubois opened this issue Apr 4, 2019 · 6 comments
Closed

Allow some modules to publish any event #3263

jondubois opened this issue Apr 4, 2019 · 6 comments

Comments

@jondubois
Copy link
Contributor

Expected behavior

Sometimes a module may want to publish events which it only knows at runtime.
For example, the Network module should be able to publish any kind of event on the node (depending on messages it receives from the network).

Actual behavior

Currently, the module needs to specify the complete list of events that it exposes during boot. This can be useful in terms of imposing constraints for some modules but it's too restrictive for modules like the network module. There should be a way for a module to specify that it can publish any event (maybe a wildcard '*'?).

In the feature/create_network_module branch, the constraint was disabled completely so that any module can publish any event.

@diego-G
Copy link

diego-G commented Apr 4, 2019

@shuse2 @jondubois possibly duplication of #3097

@shuse2
Copy link
Collaborator

shuse2 commented Apr 29, 2019

Related to this #3465 (comment)
at https://github.com/LiskHQ/lisk-sdk/pull/3465/files/dfa08e35dd9e80ef07fbaeb1683300793d05133a#diff-b75af38624760951ef9d7ddadac0d81cL182
It has to be re-restricted with the above possibility and security.

Also, affects #3154

@nazarhussain
Copy link
Contributor

nazarhussain commented Apr 29, 2019

Any module can invoke action or subscribe to events of others, but in any case it should not be able to publish events of others, by impersonating or any other case.

Let's suppose we tend to allow it then the definition of some modules would be very wage. Which module should be allowed for impersonating? And if one is allowed then why not others?

If you are referring in context that a module can publish any events for its own without its definition, that also does not make sense. A publisher only publish events, if there are or will be subscribers. When you are not defining the events first, then how subscribers aware of those and use those?

@jondubois
Copy link
Contributor Author

jondubois commented Apr 29, 2019

@nazarhussain Even with custom events, modules cannot impersonate each other because the prefix of each event will still contain the module name (e.g. the postBlock event published by the chain module is chain:postBlock). I agree with this aspect.

If the Network module publishes an event which originates from a Chain module which is running on a remote peer, it might look like network:chain:postBlock. In this case, we still know that it's the network module which is publishing the event.

When you are not defining the events first, then how subscribers aware of those and use those?

In any case, module developers need to read a module's documentation to find out what the payload of each event will look like; so they can also find out what events are available on the module from the same documentation.

On the pub/sub implementation side, there is no need to specify or restrict what channels a module can publish to. You can have dynamic channels so that any client can subscribe or publish to any channel (whether it exists or not) - This is the approach used by Redis, SocketCluster, Faye, and most pub/sub systems. The principle of creating channels/topics statically (from the beginning) is more related to Message Queues; systems like RabbitMQ, NSQ, MQTT and Kafka. But MQs are not suitable for our use case; they are too heavy and difficult to manage - This is especially true for cross-process communication on the same node.

@jondubois
Copy link
Contributor Author

jondubois commented Apr 29, 2019

Some possible approaches (this may change):

Subscribing to a remote event (from a remote peer module):

// Subscribe to the postBlock event from a remote chain module
channel.subscribe('network:chain:postBlock', handlerFunction);

// Subscribe to all remote events from all remote modules
channel.subscribe('network', handlerFunction);

OR

// Subscribe to the postBlock event from a remote chain module
channel.subscribe('network:receive:chain:postBlock', handlerFunction);

// Subscribe to all remote events from all remote modules
channel.subscribe('network:receive', handlerFunction);

OR

// Subscribe to the postBlock event from a remote chain module
channel.subscribe('network:receive::chain:postBlock', handlerFunction);

// Subscribe to all remote events from all remote modules
channel.subscribe('network:receive', handlerFunction);

OR

// Subscribe to the postBlock event from a remote chain module
channel.subscribe('network:receive/chain:postBlock', handlerFunction);

// Subscribe to all remote events from all remote modules
channel.subscribe('network:receive', handlerFunction);

Publishing remote event to a peer:

channel.invoke('network:publish', {
  event: 'chain:postBlock',
  data: {}
});

Also, we should consider whether or not it makes sense to allow a client to subscribe to all remote events from a specific module or we want to force them to specify the exact event.

@shuse2
Copy link
Collaborator

shuse2 commented Aug 18, 2020

With #5603 , this is no longer relevant

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants