Open faerics opened 4 years ago
Updated a Docker image to the latest tag, now crossbar and autobahn are both 19.10.1
.
the bug still persists with the same logs.
Hello there, I made some investigation and can confirm this is a bug in the implementation. The description on what's actually happening is below. TL;DR the bug is localised, I propose some ways to make a fix below and ready to become a new contributor.
Before we start, I should say that I have no experience in twisted, so some decisions I discover during reading of the codebase lead to questions. I make them in italic below.
on_unsubscribe
event is published in a deferred way (in the next cycle of the event loop), see here. Why? For me it's OK because we do not want router.detach
to wait for the message will be actually sent but it leads to bugs...autobahn.WampRawSocketProtocol
calls self._session.onClose
when transport connection is lost or closed cleanly.RouterSession.onClose
calls self.onLeave
then calls self._router.detach(self)
and then.. wipes the sesion id (see here)! Why? What is the semantic sence of a session which don't have an id? Yes, it is detached, but it may be needed later...onClose
was called, and when we actually send on_unsubscribe
event... we don't have it.Point 4 leads us to a bug: _when a client loses a transport connection, or closes a tansport cleanly, or even closes a WAMP session normally(!) wamp.subscription.on_unsubscribe
fires with None
instead of session id which unsubscribed ._
When no one closes the session there is no call to session onClose
before publishing the event, and all works fine.
Here are some ways I can propose, From the most concrete to the most general one:
_pending_session_id
field. Why is it needed and why is it wiped the same way?_RouterSession.close
fully asyncronous, meaning: wipe the session id after the detaching is finished and events are published. We could publish the event in onLeave
, why not? I see this may be a bad idea because sending meta events are definetely part of detaching... Router.detach
fully syncronous, meaning: send all the meta events before the detach is finished,@oberstet, looking forward to discussing the issue. Hope you answer my questions.
A similar (maybe exact the same) problem was raised in #1234, but no reaction for 2 years. The issue seems to be qiute important.
Version
The Bug
When a client being subscribed to a topic (let;s name it
com.example.topic1
if needed) disconnects from the router (e.g network error) theon_unsubscribe
event fires, but no session id is present. In other words, a backend has no chance to know who has unsubscribed, which may be critical.This behavior don't look as a desired one. Expected behavior: the session id of a disconnected client passed as an argument of an event.
Steps to reproduce
wamp.subscription.on_subscribe
andwamp.subscription.on_unsubscribe
events and has enough permissions to receive themcom.example.topic1
.on_subscribe
event fires with both arguments set properly.on_unsubscribe
event fires withNone
instead of a session id.Logs
Here are the logs from the point when step 4 occurs at
trace
level. We can definetely see that the router sendsNone
as the first argument (UPD: line 13 of the snippet).