Surely there must be a way of informing the subber which pub server to subscribe to?
Nameko events aren’t peer-to-peer. Both publisher and subscriber connect to the same RabbitMQ broker, and the messages pass through it.
Assuming you’ve got them both connected to the same broker, the problem must be in the routing.
Your event_handler is saying subscribe me to “TandH” events from the “Environment_Events” service. Is your dispatch call in a service called “Environment_Events”?
Thanks for this. It looks like I have the module installed, but that I need to enable it. I’m running under docker:
sudo docker run -p 5672:5672 --hostname nameko-rabbitmq rabbitmq:3
So I guess enable is something like this:
sudo docker run rabbitmq-plugins enable rabbitmq_management
But I get:
Unable to find image 'rabbitmq-plugins:latest' locally
docker: Error response from daemon: pull access denied for rabbitmq-plugins,
repository does not exist or may require 'docker login'.
To run RabbitMQ broker with Management plugin enabled you can simply use this docker run command: sudo docker run -d -p 5672:5672 -p 15672:15672 --hostname rabbit --name rabbit rabbitmq:3.7-management-alpine
Port 5672 is used for AMQP connections and 15672 for Web Management console.
You get the error above because there isn’t rabbitmq-plugins:latest docker image in docker hub. You can find all available images here: https://hub.docker.com/_/rabbitmq
Yes, I could see that. But I’m not running the main app with nameko. It a large wxpython app and I wanted a sort of custom event to pop in and call a routine. If I use a config file will that be called by event_handler?
Standalone, it runs the way you suggest:
nameko run Subber_Test --broker amqp://guest:guest@192.168.1.81
But from another app, it doesn’t. I’ll try the config file.
So I tried all the above, but whatever I use I need to call a service through the nameko run command. What I have is an application called by the python2.7 command. The application run with nameko run just crashes.
I thought maybe I could use the wxpython pubsub structure but it has this line in on the wiki page:
Note that pubsub itself does not broker over a network, but only within an application.
Which makes it all but useless. I have a service on another host, which I wanted to subscribe to in a pub-sub way. I can do it in a rpc way using ClusterRpcProxy and a CONFIG variable, but not using pub-sub. It seems the same restriction applies. I can run a service to service pub-sub over the network, but not an application to service. The issue is @event_handler. If I could inject the CONFIG into that, it would work. I tried setting the components as environment vars, but still no joy. Is it possible to spell out the @event_handler long-hand with host address injection? How would I do that?
I could potentially daisy-chain my pub-subs, with two RabbitMQs, one on each host. Run a service on my client host attached to both Rabbits, run it under nameko subscribing to the remote host and re-publishing under the local host, which I could pick up with the application. Seems like a lot of work.
What do you think?
Clearly I should have come to your open day last year!!!
Will you have another one this year? I discovered nameko the week after you’d just run it.
Sorry Steve. Even though it’s right there in the title I missed the part about wxpython. Do you want the Nameko event to trigger something inside the GUI app?
It’s not simply a case of getting the config into the event handler. The @event_handler decorator is a Nameko entrypoint – it relies on various mechanisms inside the Nameko service container to work. So you can’t just decorate a method in another random class and have it work.
The same is true of the @rpc decorator. So I assume your wxpython app is not the server in the RPC relationship, but the client, and uses the RpcProxy from the nameko.standalone.rpc package?
If your wxpython application was the publisher, you could use the standalone event dispatcher (in nameko.standalone.events). Unfortunately there is no standalone event handler. It’s quite a lot harder to consume messages than it is to send them – you need to maintain a persistent connection to the broker, which means a background thread, co-routine, or blocking wait, and which one of those is appropriate depends where you’re using it. So it doesn’t come out of the box.
In Nameko 3.x there is a utility which consumes AMQP messages and the various AMQP entrypoints use it. You might be able to use this as a starting point for consuming events inside a wxpython app.
Exactly. What you say about the @rpc is also true. It sends a message to the @rpc broker on another host and gets the reply. It works, but the applications hangs while it does that (only for a second or two). I could put that call in a background thread and then there would be no hanging at all, which might be better.
I have now got a version of the subscription service which then resends the message locally. That also works. The issue is how to get it into the app. Even the wxpython pubsub only works within a single gui instance. I could poll for it, but that defeats the whole object of it all, I might as well go back to using rpc. pubsub should just shout when its ready and the app comes and gets it. Rather than the app saying are you done yet, are you done yet, are you done yet… ?
Do all pubsubs work like this? What do you think? Am I just using the wrong paradigm. Is there a pusub paradigm that I’m not aware of?
We’ve been around the houses in this thread, and I might now be a bit lost!
From a quick read of the pypubsub docs, it’s intended to help decouple bits of a single application (especially useful for GUIs), not let an application respond to events on other machines. Nameko Events and pypubsub both use a “publisher-subscriber” pattern but they are very different.
I think the crux of this all is that you have a concurrency problem. Your wxpython application has its own eventloop. This is why the app hangs when you make a blocking call with the standalone RPC proxy. I guess pypubsub is integrated into that eventloop, so every time your xwpython application goes around the loop it checks to see if there are any new events and calls any handlers you’ve set up for them.
In contrast, there is nothing in that eventloop or any other background thread that is listening for AMQP messages and calling your @event_handler decorated method.
I don’t know much about wxpython, but I would try to separate the two concerns:
Spin up a background thread that can consume messages from AMQP. You can use the Consumer utility from Nameko 3 or just use Kombu or similar directly.
When an AMQP message arrives, use pysubpub to publish that message in a way that your GUI app can react to
No, I think you’ve captured it perfectly. So I managed to get point 1) working with a nameko service running on my local host. I tried 2) exactly as you say, but pysubpub doesn’t even work from an external service on the same PC to another task on the same PC. Maybe I can insert a very lightweight check into the main event loop, but I don’t really know how to do that.
In the meantime, it seems easier to continue to use rpc and then just put it into a thread. I could, I suppose, pypubsub the answer intra-app.
I think I learned that in architecture pub-sub needs to be service to service and async, but rpc can be app to service and then needs to be sync, although it can be threaded to reduce impact on GUI performance.