Closed valerykustov closed 1 year ago
Callbacks cannot be invoked in external workers. An external worker is a write-only instance, it cannot receive anything. If you want bidirectional support, then connect to the server as a client.
Thank you for your suggestion!
But I thought that is the purpose of publication of callback
messages in the pub/sub system, i.e. redis in this example. It even contains the ack text:
{'args': ('Ack from JS! eventName: backgroundMessage, data: "background '
'message from hook"',),
'host_id': '69e34b8ccefa499e897885c431b46327',
'id': 2,
'method': 'callback',
'namespace': '/',
'sid': 'room_1'}
Then maybe it should be a feature request to make external workers execute the callbacks which they receive?
External workers do not read from the queue, they only write. If you look at the code you will notice that the client manager instance is initialized with the write_only=True
option.
The method that you are using to communicate with the server from the Celery worker is really not the most flexible, it was built long ago and has been obsoleted by the client in the python-socketio package, which has bidirectional support.
The payload that is written to the pub/sub queue does include the callback, but this was built for a completely different purpose, which is to support horizontally scaled servers. The support for external processes was never extended to take advantage of this, because at this point using a client is actually preferred.
Thank you for clarification! I'll try to switch to another mechanism.
Description
I have a SocketIO client and two HTTP entrypoints. When a request comes to the first of them the server emits to the client. When a request comes to the second one the servers creates a background Celery task which then emits to the client. Both emits have a callback function assigned to them. Both emits reach the client. However, the callback is not invoked for the Celery emit though the acknowledgment is received.
Steps to reproduce:
You need redis server installed and available at localhost.
Versions:
Files structure:
background/main.py
:background/tasks.py
:background/templates/user.html
:background/celery.sh
:Start redis server and run Celery:
/bin/bash background/celery.sh
. Then start the application and visit http://localhost:5002/user/1.Now if you open http://localhost:5002/online_message_to/1 then a message will be delivered to the client and you'll see something like this in the server logs:
Notice the last line. It is created from the
ack_callback
function.If you open http://localhost:5002/background_message_to/1 then a message will be delivered, too. But the callback will not be invoked. The server logs will look like this:
The Celery logs will look like this:
Both logs are missing the print of the ack.
The expected behaviour:
The callback should be invoked and the acknowledgment should be printed to the Celery logs. But I'm not pretty sure about it though as I am new to both Celery and SocketIO.