Skip to content
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

Events via WebSocket #48

Open
5 of 8 tasks
Tracked by #29
bitfl0wer opened this issue Sep 15, 2024 · 0 comments
Open
5 of 8 tasks
Tracked by #29

Events via WebSocket #48

bitfl0wer opened this issue Sep 15, 2024 · 0 comments

Comments

@bitfl0wer
Copy link
Member

bitfl0wer commented Sep 15, 2024

To make Events via WebSockets as efficient as possible, we strive to reduce database operations by using a caching system that immediately tells us, which event is supposed to be sent to which client.

Splitting up the problem

Tackling this problem is best with a bit of divide and conquer, meaning: Instead of tackling the entire problem as a whole, we should divide it into smaller parts first, then tackle those smaller parts.

If we think about it, ~95% of events are emitted in the context of a Guild. Whether it is new messages, guild member updates or changes to channels and channel state (voicechat joins/leaves) - all of these can be traced back to a Guild. However, Guilds are not a fine enough denominator when it comes to determining whether a user should receive an event or not. Think of the case where Guild moderators have a moderator-only channel - it would be bad if the MessageCreate events in that channel were sent to everyone on that Guild.

One level "below" Guilds are Roles. Every user has at least the @\everyone role, and roles with their assigned permissions determine which channels a user can and cannot see.

But there are two slight problems:

  1. Using only roles to determine event-eligibility would make channel/category permission overrides for individual users useless.
  2. The other ~5% of our Gateway traffic are caused by DMs, Group DMs and Inter-User relationships. Roles do not work here either

As such, the second "bin" with which we determine event eligibility should be individual user IDs.

The end result

In the end, we have two "bins" of eligible subscribers for events:

  • Every user who has a specific Role ID assigned to them
  • Other, individual users who are also supposed to receive the event

Using a mathematical set like HashSet<T>, we can deduplicate, so that one user doesn't receive an event twice, then send the event to all recipients.

Tracking tasks

  • Create a way to send events to GatewayUsers from the HTTP API
  • Keep track of which users are currently connected to the Gateway
    • Register users when they connect to the gateway
    • Register users creating new accounts
    • Reliably unregister users when they disconnect (or are disconnected) from the gateway
    • Handle users deactivating or deleting their account
    • Handle cases where a user got removed from the database but is still loaded in memory
  • Add all of a users' roles' IDs to a Role ID -> User ID mapping
  • ...todo
@bitfl0wer bitfl0wer mentioned this issue Sep 15, 2024
17 tasks
@bitfl0wer bitfl0wer reopened this Oct 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant