crossbario / crossbario/autobahn-python

Undefined behavior for using WAMP features not agreed during feature negotiation

Open
#1,605 9 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug needs-discussion wamp
Dominant language
Python
Stars
2.5k
Forks
768
PR merge metrics
No merged PRs in 30d

Description

I have a client talking to a WAMP Basic Profile server (ran by a third party). This doesn't support call cancellation so I think a call made like this:

# ...
    async def call_endpoint(self, endpoint):
        try:
            resp = await self.call(endpoint, timeout=ENDPOINT_CALL_TIMEOUT_SECONDS * 1000)
        except Exception as e:  # TODO: Tighten this exception
            print(f"Error calling {endpoint}: {e}")
            raise

would ignore the timeout option and carry on running past the timeout?

I didn't actually notice the timeout option on the call method on my first pass so just wrapped it in asyncio.wait_for with a timeout like this:

# ...
    async def call_endpoint(self, endpoint):
        try:
            resp = await asyncio.wait_for(self.call(endpoint), timeout=ENDPOINT_CALL_TIMEOUT_SECONDS)
        except (asyncio.TimeoutError) as e:
            print(f"Timeout calling {endpoint}: {e}")
        except Exception as e:  # TODO: Tighten this exception
            print(f"Error calling {endpoint}: {e}")
            raise

But that's throwing the occasional bad_protocol error. I didn't know what the exact issue is but our third party gave me access to the server logs which showed a 49 error code relating to the cancel call and it does always align with being thrown on the call after a 20s timed out call.

What's the best way to handle timeouts in this situation? I don't want to catch the bad_protocol exception as is in case the client or server changes in a way that this hides another issue. Can I at least see why the bad_protocol exception is being thrown in the exception somehow? I also don't want to allow the client to block indefinitely on the server because we previously saw consistent failures where the client just hangs forever waiting for a response from the server that never arrives.

Should Autobahn be detecting this lack of support for call cancellation and just silently dropping the task if cancelled in this way? Or throw another exception in some way that can be handled?

I noticed https://github.com/crossbario/autobahn-python/issues/1127 but while I think there's maybe some similarity in the reply in that issue I don't really see the similarity in the opening post.

Contributor guide

Open the contributing guide

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 by tracing the Python call timeout path alongside asyncio.wait_for and the WAMP Cancel message, then compare the feature-negotiation behavior with issue 1127. Determine how an unsupported cancellation produces bad_protocol and define the expected client behavior for timed-out calls against servers without cancellation support.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api, networking
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.