Oneway rpc (dispatch like)

Hi dear developers!
I feel lack of one feature.
It is sending a message to another service without garanties.
Example:

class A:
    name = 'service_a'
    b = MessageProxy('service_b')

   def send_message(self, message):
       b.hello('I am a!')

class B:
    name = 'service_b'

   @message
   def hello(self, msg):
       print(msg)

The same as with rpc except that if B is not online nothing happens. If I use rpc and B is offline b.hello() will hang.

I could do what I need using event dispatcher but in this case B must known about A. In my case I would not want to do like this.

Please advise.
Thanks.

You can use nameko.messaging.Publisher to publish to a queue defined by you and then use nameko.messaging.consume to consume from the same queue by different service.

Assuming you have a RabbitMQ running we can create a config file like this:

# config.yml
AMQP_URI: amqp://guest:guest@localhost:5672/

our ServiceA will be talking to ServiceB

# service.py

import time

from kombu import Exchange, Queue
from nameko.messaging import Publisher, consume
from nameko.web.handlers import http

MY_ROUTING_KEY = "my_routing_key"
my_exchange = Exchange(name="my_exchange")

my_queue = Queue(exchange=my_exchange, routing_key=MY_ROUTING_KEY, name=MY_ROUTING_KEY)


class ServiceA:
    name = "service_a"

    my_publisher = Publisher(queue=my_queue)

    @http("GET", "/hello/<name>")
    def hello(self, request, name):
        payload = {"name": name}
        self.my_publisher(payload, routing_key=MY_ROUTING_KEY)
        print(f"published payload with name: {name}")
        return 200, "Hello, {}!".format(name)


class ServiceB:
    name = "service_b"

    @consume(queue=my_queue)
    def hello(self, payload):
        print("sleeping for 2 seconds")
        time.sleep(2)
        print(f"received payload: {payload}")

You can run the above:

$ nameko run --config config.yml service

starting services: service_a, service_b
Connected to amqp://guest:**@127.0.0.1:5672//

You can call method hello in ServiceA in a separate console window:

$ curl localhost:8000/hello/bob

Hello, bob!

You’ll see that message is processed asynchronously and method in ServiceA is not blocked by processing of the payload by ServiceB

In you main console you should see something like:

sleeping for 2 seconds
published payload with name: bob
127.0.0.1 - - [24/Nov/2019 15:30:25] "GET /hello/bob HTTP/1.1" 200 128 0.007280
received payload: {'name': 'bob'}

Where last line is printed after 2 seconds delay.

Hope this helps.
Jakub

Hi!
Thank you much for the solution.
I will try it.