-
-
Notifications
You must be signed in to change notification settings - Fork 640
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Only delete page content if the number of connections is zero #4285
base: main
Are you sure you want to change the base?
Conversation
Something in this PR seems to slow down our pytests. Usually the ~500 tests run in around 15 minutes per machine. Now they timeout after 30 minutes. |
If I had to guess I would say that |
That's a good explanation, @chriswi93! So it is better to sleep in a background task because they are gracefully canceled during teardown. Apart from that we noticed a theoretical flaw of the connection counter. The delay could end right in between a "normal reconnect" when the disconnect happened and the counter
To overcome this problem, we can get back to using a background task for the content deletion, which is canceled (❌) by subsequent handshakes:
|
Good point! I think we are quite close 🙂 But it turns out that it introduces a breaking change I was not aware of and I think many applications built on top of NiceGUI would be affected in the same way: I would suggest two options to fix this:
if self._num_connections == 0:
... And document that there is an intended inconsistency: A connect handler might be called many times for a single client, but disconnect handler is only called once per client just before resources are cleaned up.
|
@chriswi93 You're right, calling disconnect handlers more than once can break user code. Even though you can argue that it was a bug and should be fixed, the impact is quite severe. Besides your option 1 (keep inconsistent behavior like before) and option 2 (consistent behavior but breaking change), I see another option 3 that calls both handlers only once. It would also be a breaking change, but maybe less critical.
But it's hard to tell if there are users relying on a connect handler being called on reconnect. |
@falkoschindler Yes, that would be another way to make it consistent. All three options are valid in my opinion. |
Ok, I'm about to keep the current behavior of multiple connects and a single disconnect (option 1). We can improve consistency with a breaking change in version 3.0, but should fix this bug first. However, I noticed another aspect we didn't think about: On the shared auto-index client there are multiple open connections. Currently we call multiple connects and a single disconnect like on regular pages. But the So I thought we could use a
Because we need to add socket IDs to On Air messages anyway (see #4218), I suggest to do that first and use them for the connection dictionary. |
Yes, I think it's a good idea to postpone the breaking change to a major release.
As far as I can see you share a single Client instance and all the elements among many users and tabs. So all users share the same client id. However, I think the socket id won't resolve the issue due to the following reason: I would assume that a new socket id is assigned to every new socket connection and I guess this also applies to a connection that is the result of a reconnect. For non shared clientsIf my assumption is true, the counter in For shared auto-index clientIf all users share the same client id, information is lost since we can no longer use the client id to identify an individual user tab. Therefore we don't know when all connections for an individual user tab are actually closed and as a result it is hard to find out when the disconnect handlers should be called. I don't know if tab id is something that you could use instead for the shared auto-index page. Otherwise, it might be a good idea to add a unique id that makes it possible to identify a unique user tab across reconnects and regardless of whether it is a shared client or not. If this would involve too many changes, it might be sufficient for now to just ignore the # for self.shared = True: asyncio.sleep(...) is also not required
if self.shared or self._num_connections == 0:
... Instead of: if self._num_connections[socket_id] == 0:
... Then for a shared client the disconnect handlers would be called after each disconnect event. However, it should be noted that an application built on top of the auto-index feature can not allocate/deallocate resources for a single user tab which could be an intended limitation. Therefore, in my opinion it is consistent to say that the behavior of how disconnect handlers are called is different for a shared client. |
This PR tries to solve #4253 with a new
_num_connections
counter. On handshake the counter is increased, on disconnect it is decreased. On disconnect, after awaiting the reconnect timeout, the page content is only deleted if the number of connections is zero.Possible scenarios:
While working on the handshake and disconnect implementation, I noticed an inconsistency with
app.on_connect
andapp.on_disconnect
: While connect handlers are called on reconnect, disconnect handlers are not. In this PR I changed it so that both handlers are called during reconnection. We should clarify if this is the desired behavior.