crossbario / crossbario/autobahn-python
Undefined behavior for using WAMP features not agreed during feature negotiation
Nobody has claimed this yet.
- 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
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 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