-
Notifications
You must be signed in to change notification settings - Fork 71
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
Change websocket cleanup performance from O(n^2) to O(n). #429
base: master
Are you sure you want to change the base?
Change websocket cleanup performance from O(n^2) to O(n). #429
Conversation
Move subscription tracking to a dict keyed by the underlying websocket object. Changes the cleanup from two nested for loops (the 2nd being the unsubscribe_from method), to a single loop with (the common case) deleting a single key from a dict.
lgtm! we can ship this once @saikonen approves |
@savingoyal @saikonen is there any update here, anything I can do to help get this upstreamed? thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
overall changes look good. had one minor note on the filter part.
linter step is failing due to unrelated reasons, this is fixed in master
now if you want to rebase
# This is primarily useful when calling `unsubscribe_from` during the cleanup | ||
# loop in the event handler. | ||
for k in list(self._subscriptions.keys()): | ||
for sub in self._subscriptions[k]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note to self: no KeyError possible due to self._subscriptions being a defaultdict(list)
self.subscriptions = list( | ||
filter(lambda s: uuid != s.uuid or ws != s.ws, self.subscriptions)) | ||
self._subscriptions[ws] = list( | ||
filter(lambda s: uuid != s.uuid or ws != s.ws, self._subscriptions[ws])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the ws != s.ws
check necessary anymore as the subscription is keyed per websocket?
Move subscription tracking to a dict keyed by the underlying websocket object.
Changes the cleanup from two nested for loops (the 2nd being the unsubscribe_from method), to a single loop with (the common case) deleting a single key from a dict.
We found that with a sufficient number of disconnected clients, and long gaps between database activity, the cleanup could end up taking multiple hours. This would cause the python web service to become unresponsive.