Intents/events system #5

Open
opened 2025-08-08 17:52:38 -04:00 by glitchy · 0 comments
Owner

Intents/events system

yes i used chatgpt for this cry about it im sleepy rn i wont get this done instantly

To improve client-server synchronization and reduce desynchronization issues, we should implement an intents/events system. This system allows clients to explicitly declare which types of events they want to receive updates about (intents), and the server will push relevant asynchronous event notifications as they occur.

This approach replaces or supplements polling-based mechanisms like LSSUBS and ensures clients stay up-to-date with minimal network overhead.


Proposed Protocol Additions

Intents declaration

Clients declare their interest in specific event types:


SUBEVENT \<event\_type>

Example:


SUBEVENT channel

The server confirms intent subscription:


CONFIRM SUBEVENT \<event\_type>

Event notifications

Server asynchronously sends events to subscribed clients:


EVENT \<event\_type> <action> \<resource\_identifier> \[\<additional\_data\_as\_json>]

Examples:


EVENT channel CREATE example
EVENT channel DELETE example
EVENT user JOIN general {"username":"glitchy"}

Intent removal (optional)

Clients may unsubscribe from event notifications:


UNSUBEVENT \<event\_type>

Server confirms:


CONFIRM UNSUBEVENT \<event\_type>


Implementation Notes

  • Maintain a per-client set of subscribed intents on the server.
  • Upon relevant state changes (e.g., channel creation, user join/part), broadcast events only to clients with matching intents.
  • Design event payloads to include minimal necessary data to update client state.
  • Handle edge cases like client reconnects: consider replaying missed events or providing snapshots.
  • Integrate intent handling into existing message handling framework with proper error handling for unknown or malformed intents.
  • Add relevant tests covering subscription management and event delivery.

Example Server-side pseudocode

async def handle_subevent(ctx):
    if not ctx.args:
        await ctx.error(ErrorCode.BADARGS, "SUBEVENT requires event type argument")
        return

    event_type = ctx.args[0]
    if event_type not in SUPPORTED_EVENT_TYPES:
        await ctx.error(ErrorCode.BADARGS, f"Unsupported event type: {event_type}")
        return

    ctx.client.intents.add(event_type)
    await ctx.send(f"CONFIRM SUBEVENT {event_type}")
async def broadcast_event(event_type, action, resource_id, data=None):
    for client in global_state.clients:
        if event_type in client.intents:
            payload = json.dumps(data) if data else ""
            await client.websocket.send(f"EVENT {event_type} {action} {resource_id} {payload}")

Client-side considerations

  • Upon connecting, client declares intents of interest.
  • Listen for EVENT messages and update UI/state accordingly.
  • Optionally handle unsubscribing from intents when no longer needed.

Benefits

  • Reduces unnecessary polling.
  • Keeps clients in near real-time sync.
  • More scalable for larger user bases and complex state changes.

References

  • Existing LSSUBS command for channel subscriptions.
  • Common patterns in modern protocols like Discord Gateway or Matrix Events. See d*scord's websocket gateway.
# Intents/events system ## yes i used chatgpt for this cry about it im sleepy rn i wont get this done instantly To improve client-server synchronization and reduce desynchronization issues, we should implement an intents/events system. This system allows clients to explicitly declare which types of events they want to receive updates about (intents), and the server will push relevant asynchronous event notifications as they occur. This approach replaces or supplements polling-based mechanisms like `LSSUBS` and ensures clients stay up-to-date with minimal network overhead. --- ## Proposed Protocol Additions ### Intents declaration Clients declare their interest in specific event types: ``` SUBEVENT \<event\_type> ``` Example: ``` SUBEVENT channel ``` The server confirms intent subscription: ``` CONFIRM SUBEVENT \<event\_type> ``` ### Event notifications Server asynchronously sends events to subscribed clients: ``` EVENT \<event\_type> <action> \<resource\_identifier> \[\<additional\_data\_as\_json>] ``` Examples: ``` EVENT channel CREATE example EVENT channel DELETE example EVENT user JOIN general {"username":"glitchy"} ``` ### Intent removal (optional) Clients may unsubscribe from event notifications: ``` UNSUBEVENT \<event\_type> ``` Server confirms: ``` CONFIRM UNSUBEVENT \<event\_type> ```` --- ## Implementation Notes - Maintain a per-client set of subscribed intents on the server. - Upon relevant state changes (e.g., channel creation, user join/part), broadcast events only to clients with matching intents. - Design event payloads to include minimal necessary data to update client state. - Handle edge cases like client reconnects: consider replaying missed events or providing snapshots. - Integrate intent handling into existing message handling framework with proper error handling for unknown or malformed intents. - Add relevant tests covering subscription management and event delivery. --- ## Example Server-side pseudocode ```python async def handle_subevent(ctx): if not ctx.args: await ctx.error(ErrorCode.BADARGS, "SUBEVENT requires event type argument") return event_type = ctx.args[0] if event_type not in SUPPORTED_EVENT_TYPES: await ctx.error(ErrorCode.BADARGS, f"Unsupported event type: {event_type}") return ctx.client.intents.add(event_type) await ctx.send(f"CONFIRM SUBEVENT {event_type}") ```` ```python async def broadcast_event(event_type, action, resource_id, data=None): for client in global_state.clients: if event_type in client.intents: payload = json.dumps(data) if data else "" await client.websocket.send(f"EVENT {event_type} {action} {resource_id} {payload}") ``` --- ## Client-side considerations * Upon connecting, client declares intents of interest. * Listen for `EVENT` messages and update UI/state accordingly. * Optionally handle unsubscribing from intents when no longer needed. --- ## Benefits * Reduces unnecessary polling. * Keeps clients in near real-time sync. * More scalable for larger user bases and complex state changes. --- ## References * Existing [LSSUBS](https://git.amcalledglitchy.dev/glitchy/wschat/src/commit/ec965d526e8b18be25c00fb92cf60b0ecb3895bc/cogs/lssubs.py) command for channel subscriptions. * Common patterns in modern protocols like Discord Gateway or Matrix Events. See d*scord's websocket gateway.
glitchy added this to the v1 milestone 2025-08-08 17:52:38 -04:00
glitchy self-assigned this 2025-08-08 17:52:38 -04:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: glitchy/wschat#5
No description provided.