Skip to content

Design patterns #18

@Netzeband

Description

@Netzeband

I just want to discuss a little bit about design patterns for the server signals.

Leptos promotes a software design, which is very modular. You have different components, which are normally isolated from each other and which are combined to get a full application. The signal system pays in into this modular design, since every component can have its own private signals and there is no global instance managing those signals. Another element to that are server-functions, little pieces of code, which are running on the server, but they are closely implemented together with the components.

The wasm side of the server signals fits perfectly to this vision: It is easy to create server signals for every component, so that the functionality is isolated from other components. But the backend side (axum for example) is breaking this design pattern. Since the websocket is shared for all server signals and there can only be one handler for it. This means, that this single handler has to manage all server signals, regardless in which component they are used. Which is in contract to the modular design of the leptos components.

So how to solve this? How to disangle the server signals on backend from each other to keep the backend implementation for all server signals close to the component, where they are used?

I'm currently thinking of the following design on backend:

  • There is a single handler, which is a little bit like a wrapper around the set of handlers for different server signals
  • Inside the handler the websocket is put into an Arc<Mutex<...>>
  • There is a set of server signal specific handlers, which are all awaitable
    • Every handler gets a clone of the Arc<Mutex<Websocket>> object
    • When a signal update should be updated, we lock the mutex and get a dereferenced mutable object from the websocket to send the update
  • There is a join operation to join the futures of all handlers and the joined future is then awaited

This solution is far more complicated than implementing just some server functions for a component. If, for example, a server signal should be updated from a server function, we need to connect the server function with the handler over something like a message queue. But in the end it allows to implement a dedicated handler for the server signals used by a single component and to register this handler on backend side for the usage inside the wrapper around all handlers.

What are your design patterns around server signals?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions