opensistemas-hub / osbrain

osBrain - A general-purpose multi-agent system module written in Python
https://osbrain.readthedocs.io/en/stable/
Apache License 2.0
175 stars 43 forks source link

Is there a way to have multiple communication channels between agents? #324

Closed ghost closed 5 years ago

ghost commented 5 years ago

Say I have a controller agent that is in control of ten battery agents. Can I have multiple communication channels, one for example when the controller needs to send out general instructions to all batteries, and others when it needs to send commands to individual batteries?

Or is only one channel possible and I have to include flags or names in commands being sent out to process on the other end?

Any help will be greatly appreciated.

ocaballeror commented 5 years ago

You can definitely have multiple connections in one agent. That is why we use aliases to specify who the agent should send the message to. You can .bind(alias='') as many times as you want, specifying different aliases, and then use .send(alias='whatever') to only send the message to that address.

In your case, I would use a PUB-SUB channel for the general instructions that all batteries need to receive, and individual PUSH-PULL (or any other, to be honest) connections from the controller to each of the nodes.

Consider this code as an example:

import random
from osbrain import run_nameserver
from osbrain import run_agent

def log_main(agent, message):
    agent.log_info('MAIN: Received ' + message)

def log_direct_msg(agent, message):
    agent.log_info('DIRECT: Received ' + message)

if __name__ == '__main__':
    ns = run_nameserver()
    controller = run_agent('controller')

    # Main communication channel
    main_addr = controller.bind('PUB', alias='main')
    batteries = []
    for i in range(10):
        battery = run_agent('battery%d' % i)

        # Connect to the main PUB channel
        battery.connect(main_addr, handler=log_main)

        # Individual connection from the controller to this node
        addr = controller.bind('PUSH', alias='battery%d' % i)
        battery.connect(addr, handler=log_direct_msg)
        batteries.append(battery)

    controller.send('main', 'All batteries receive this')
    number = random.choice(range(10))
    controller.send('battery%d' % number, 'Hello battery #%d' % number)
    ns.shutdown()
ocaballeror commented 5 years ago

Also, if you are going to use a PUB-SUB pattern, I would recommend you read a bit on topics, they may come useful for a setup like this.

ghost commented 5 years ago

Thank you for replying so quickly, I'll try setting up multiple connections with different aliases.

Thanks for this library too, you guys are amazing. Would have had to learn Java for Jade if I hadn't found this library.

On Sun, 17 Mar 2019, 3:48 pm ocaballeror <notifications@github.com wrote:

Also, if you are going to use a PUB-SUB pattern, I would recommend you read a bit on topics https://osbrain.readthedocs.io/en/stable/basic_patterns.html#filtering, they may come useful for a setup like this.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/opensistemas-hub/osbrain/issues/324#issuecomment-473654040, or mute the thread https://github.com/notifications/unsubscribe-auth/AQANEIAzOwhADwujQINc0SHhCLAVuzGGks5vXh1ngaJpZM4b4NTp .

ocaballeror commented 5 years ago

All credit goes to @Peque :grin:

Glad you like it!

Peque commented 5 years ago

All credit goes to @contributors. :stuck_out_tongue_winking_eye:

@choochipastol Closing this issue as resolved. Feel free to reopen if needed. Do not hesitate to contribute to the current documentation if you feel there is something missing/unclear.