subscriber events: Change schema for peer_add/peer_remove.

We now can send an implied matrix of user/stream tuples
for peer_add and peer_remove events.

The client code basically does this:

    for stream_id in event['stream_ids']:
        for user_id in event['user_ids']:
            update_sub(stream_id, user_id)

We used to send individual events, which gets real
expensive when you are creating new streams. For
the case of copy-to-stream case, we should see
events go from U to 1, where U is the number of users
added.

Note that we don't yet fully optimize the potential
of this schema.  For adding a new user with lots
of default streams, we still send S peer_add events.

And if you subscribe a bunch of users to a bunch of
private streams, we only go from U * S to S; we can't
optimize it down to one event easily.
This commit is contained in:
Steve Howell
2020-10-22 12:14:02 +00:00
committed by Tim Abbott
parent efa8dd3a47
commit 7ff3859136
8 changed files with 144 additions and 137 deletions

View File

@@ -717,23 +717,21 @@ def apply_event(state: Dict[str, Any],
if sub['name'].lower() == event['name'].lower():
sub[event['property']] = event['value']
elif event['op'] == 'peer_add':
stream_id = event['stream_id']
user_id = event['user_id']
for sub in state['subscriptions']:
if (sub['stream_id'] == stream_id and
user_id not in sub['subscribers']):
sub['subscribers'].append(user_id)
for sub in state['never_subscribed']:
if (sub['stream_id'] == stream_id and
user_id not in sub['subscribers']):
sub['subscribers'].append(user_id)
stream_ids = set(event["stream_ids"])
user_ids = set(event["user_ids"])
for sub_dict in [state["subscriptions"], state["never_subscribed"]]:
for sub in sub_dict:
if sub["stream_id"] in stream_ids:
subscribers = set(sub["subscribers"]) | user_ids
sub["subscribers"] = sorted(list(subscribers))
elif event['op'] == 'peer_remove':
stream_id = event['stream_id']
user_id = event['user_id']
for sub in state['subscriptions']:
if (sub['stream_id'] == stream_id and
user_id in sub['subscribers']):
sub['subscribers'].remove(user_id)
stream_ids = set(event["stream_ids"])
user_ids = set(event["user_ids"])
for sub_dict in [state["subscriptions"]]:
for sub in sub_dict:
if sub["stream_id"] in stream_ids:
subscribers = set(sub["subscribers"]) - user_ids
sub["subscribers"] = sorted(list(subscribers))
elif event['type'] == "presence":
if slim_presence:
user_key = str(event['user_id'])