mirror of
https://github.com/zulip/zulip.git
synced 2025-11-03 05:23:35 +00:00
apply_event: Fix broken deepcopy attempt for subs.
When we were getting an apply_event call for
a subscription/add event, we were trying not to
mutate the event itself, but this clumsy code
was still mutating the actual event:
# Avoid letting 'subscribers' entries end up in the list
for i, sub in enumerate(event['subscriptions']):
event['subscriptions'][i] = \
copy.deepcopy(event['subscriptions'][i])
del event['subscriptions'][i]['subscribers']
This is only a theoretical bug.
The only person who receives a subscription/add
event is the current user.
And it wouldn't have affected the current user,
since the apply_event was correctly updating the
state, and we wouldn't actually deliver the event
to the client (because the whole point of apply_event
is to prevent us from having to piggyback the
super-recent events on to our payload or put
them into the event queue and possibly race).
The new code just cleanly makes a copy of each
sub, if necessary, as we add them to state["subscriptions"].
And I updated the event schemas to reflect that
subscribers is always present in subscription/add
event.
Long term we should probably avoid sending subscribers
on this event when the clients don't set something
like include_subscribers. That's a fairly complicated
fix that involves passing in flags to ClientDescriptor.
Alternatively, we could just say that our policy is
that we never send subscribers there, but we instead
use peer_add events. See issue #17089 for more
details.
This commit is contained in:
@@ -703,17 +703,18 @@ def apply_event(
|
||||
state['realm_email_auth_enabled'] = value['Email']
|
||||
elif event['type'] == "subscription":
|
||||
if event["op"] == "add":
|
||||
if not include_subscribers:
|
||||
# Avoid letting 'subscribers' entries end up in the list
|
||||
for i, sub in enumerate(event['subscriptions']):
|
||||
event['subscriptions'][i] = copy.deepcopy(event['subscriptions'][i])
|
||||
del event['subscriptions'][i]['subscribers']
|
||||
|
||||
added_stream_ids = {sub["stream_id"] for sub in event["subscriptions"]}
|
||||
was_added = lambda s: s["stream_id"] in added_stream_ids
|
||||
|
||||
existing_stream_ids = {sub["stream_id"] for sub in state["subscriptions"]}
|
||||
|
||||
# add the new subscriptions
|
||||
state['subscriptions'] += event['subscriptions']
|
||||
for sub in event["subscriptions"]:
|
||||
if sub["stream_id"] not in existing_stream_ids:
|
||||
if "subscribers" in sub and not include_subscribers:
|
||||
sub = copy.deepcopy(sub)
|
||||
del sub["subscribers"]
|
||||
state["subscriptions"].append(sub)
|
||||
|
||||
# remove them from unsubscribed if they had been there
|
||||
state['unsubscribed'] = [s for s in state['unsubscribed'] if not was_added(s)]
|
||||
|
||||
Reference in New Issue
Block a user