Channel Layer doesn't work for AsyncHttpConsumer
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 6.4k
- Forks
- 826
- PR merge metrics
- No merged PRs in 30d
Description
- Your OS and runtime environment, and browser if applicable
MacOS 10.13.6 x64, Python 3.5.3, Django version 2.0.5, ASGI/Channels version 2.1.6 - A
pip freezeoutput showing your package versions
absl-py==0.2.2
astor==0.6.2
astroid==1.6.4
bleach==1.5.0
CacheControl==0.12.4
cachetools==2.1.0
certifi==2018.4.16
channels==2.1.6
chardet==3.0.4
click==6.7
decorator==4.3.0
dj-database-url==0.5.0
Django==2.0.5
djangorestframework==3.8.2
firebase-admin==2.10.0
future==0.16.0
gast==0.2.0
gcloud==0.17.0
geocoder==1.38.1
google-api-core==1.2.0
google-auth==1.4.1
google-cloud-core==0.28.1
google-cloud-firestore==0.29.0
google-cloud-storage==1.10.0
google-resumable-media==0.3.1
googleapis-common-protos==1.5.3
googlemaps==2.5.1
grpcio==1.12.0
gunicorn==19.8.1
html5lib==0.9999999
httplib2==0.11.3
idna==2.6
isort==4.3.4
jws==0.1.3
lazy-object-proxy==1.3.1
Markdown==2.6.11
mccabe==0.6.1
msgpack-python==0.5.6
numpy==1.14.3
oauth2client==3.0.0
protobuf==3.5.2.post1
pyasn1==0.4.3
pyasn1-modules==0.2.1
pycryptodome==3.4.3
pylint==1.9.1
python-jwt==2.0.1
pytz==2018.4
ratelim==0.1.6
requests==2.11.1
requests-toolbelt==0.7.0
reverse-geocoder==1.5.1
rsa==3.4.2
scipy==1.1.0
six==1.11.0
tensorboard==1.8.0
tensorflow==1.8.0
termcolor==1.1.0
urllib3==1.22
Werkzeug==0.14.1
whitenoise==3.3.1
wrapt==1.10.11
Pyrebase==3.0.27
psycopg2
django-cors-headers
- What you expected to happen vs. what actually happened
This is my LongPollingConsumer where insidehandleI am storing thechannel_namein a database then doing the usual as documented here.
class LongPollConsumer(AsyncHttpConsumer):
async def handle(self, body):
self.room_name = self.scope['url_route']['kwargs']['uuid']
# self.room_group_name = 'upvote_'
# await self.send_response(200, b"Hello", headers=[
# (b"Content-Type", b"application/json"),
# ])
store_channel(self.room_name, self.channel_name)
await self.send_headers(status=200, headers=[
(b"Content-Type", b"application/json"),
])
print('consumer room_name', self.room_group_name)
# await self.channel_layer.group_add(
# self.room_group_name,
# self.channel_name
# )
# Headers are only sent after the first body event.
# Set "more_body" to tell the interface server to not
# finish the response yet:
await self.send_body(body=b"Response", more_body=True)
async def upvote_message(self, event):
delete_channel(self.room_name)
print(event['message'])
# Send JSON and finish the response:
# async_to_sync(self.channel_layer.group_discard)(
# self.room_group_name,
# self.channel_name
# )
await self.send_body(body=json.dumps(event).encode("utf-8"))
handle is invoked as it should be. Then from my views.py, I am retrieving list of channels from the database and dispatching the handler(upvote_message) with an event message
channel_layer = get_channel_layer()
channels = retrieve_channels(uuid)
for channel in channels.keys():
print('dispatching to channel', channel)
async_to_sync(channel_layer.send)(
channel, {
"type": "upvote.message",
"message": {
'actionType': 'UPVOTES_LONG_POLL_RESPONSE',
'data': {}
}
}
)
Expected behaviour is that for every channel_layer.send, the async method upvote_message inside my LongPollingConsumer should be invoked with appropriate event message and close the respective HTTP connection. But nothing is happening. From views.py, it prints
sending to channel specific..inmemory!KTTXyBUZnIwj
sending to channel specific..inmemory!bafQMBaSCOmu
sending to channel specific..inmemory!zAGgrVeMWNth
sending to channel specific..inmemory!tazNTCBhKvfh
sending to channel specific..inmemory!XuMVhdIjBCAi
and the curl (using curl -X GET http://localhost:8000/lp/upvote/-L_v3R0Xp-BlOeagBuu1/ --verbose) remains stuck at:
* Trying ::1...
* TCP_NODELAY set
* Connection failed
* connect to ::1 port 8000 failed: Connection refused
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /lp/upvote/-L_v3R0Xp-BlOeagBuu1/ HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Transfer-Encoding: chunked
<
then eventually after manually closing connection,
* transfer closed with outstanding read data remaining
* stopped the pause stream!
* Closing connection 0
- How you're running Channels (runserver? daphne/runworker? Nginx/Apache in front?)
python manage.py runserverdevelopment server - Console logs and full tracebacks of any errors
Absolutely no logs generated except and the print statements in the code above.
Django version 2.0.5, using settings 'AppName.settings'
Starting ASGI/Channels version 2.1.6 development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the LongPollConsumer in the issue and the dispatch loop in views.py, then reproduce it with python manage.py runserver and the provided curl command. Trace whether the channel_layer.send calls reach upvote_message; done means each dispatched event invokes that handler and completes the corresponding long-polling response.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- django, python
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100