closeio / closeio/socketshark

on_unsubscribe: asyncio.CancelledError when http_post()

Open
#59 0 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
128
Forks
12
Avg merge
3d 16h
Merged PRs (30d)
6

Description

Hello, first of all, thanks for this magnificent library.

We have found an issue during the 'authorization_renewal_period'.

Summary

When the authorisation expires and, then, the authorisation is not valid, an on_unsuscribe event should be sent but our hook handler (our server) is not able to receive the request.

What we saw in the code

When the event of unsuscribing is happening and tries to send an http_post to the hook, there is an exception which is not handled: asyncio.CancelledError

What we did to fix it

We added a catch exception code block:

except asyncio.CancelledError:
    log.exception('Task was cancelled')

What was the behaviour after the fix

In the first try to run the function, it throws an exception and the try-catch block avoids finishing the execution
As it has a retry functionality, in the second try, the http post is sent to the hook and the client correctly receives the message indicating the unsubscription.

Where we saw it

How to replicate the issue:

  • Set a websocket config with and authorizer and authorization_renewal_period

E.g.

    'myservice': {
        'require_authentication': True,
        'authorizer': 'myhost/websocket/authorize/',
        'authorization_renewal_period': 10,
        'on_subscribe': 'myhost/websocket/on_subscribe/',
        'on_unsubscribe': 'myhost/websocket/on_unsubscribe/',
    }

  • Run the server
  • Run a websocket client, connect and authorise your client. The authorisation should eventually expire.
{
    "event": "auth",
    "method": "ticket",
    "ticket": "ticketxxx"
}

  • Subscribe the client to the service
{
    "event": "subscribe",
    "subscription": "myservice",
}

  • Wait until your subscription expires.

  • Then, when the authorization expires.

  • The authorization_renewal_period process should catch this expiration and start its process.

  • Socketshark tries to send:

{"pid": xx, "url": "http://myhost/websocket/on_unsubscribe/", "data": {"subscription": "myservice", ...}, "event": "http request", "level": "debug", "logger": "socketshark", "timestamp": "2020-12-18T13:09:58.012525Z"}

but as I mentioned before, myhost never receives the request due to the asyncio.CancelledError not handled.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at socketshark/utils.py line 95 and trace the call from socketshark/subscription.py line 390. Reproduce the issue with an authorizer, authorization_renewal_period, and on_unsubscribe hook, then observe the request when authorization expires. Done means the on_unsubscribe hook receives its HTTP request during this renewal path without an unhandled cancellation stopping delivery.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.