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

Design patterns #18

Open
Netzeband opened this issue Oct 31, 2024 · 2 comments
Open

Design patterns #18

Netzeband opened this issue Oct 31, 2024 · 2 comments

Comments

@Netzeband
Copy link
Contributor

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?

@tqwewe
Copy link
Owner

tqwewe commented Nov 25, 2024

Hi sorry for the late response.

I agree with your issue, in that it would be ideal for server signal code to be in same area as components. Ideally, there would be a solution pretty much mimicking server functions in leptos, where a macro is provided, and you annotate a function with this macro and write your websocket code in there.

I wrote a basic example in this issue: #6

The only reason this hasn't been implemented is simply because of the extra work involved in this, and I haven't had the time or need to go this far yet. However this would be a great API design for this library, and would contribute to solving client writable signals too.

@Netzeband
Copy link
Contributor Author

Yes you are right, this would be a really nice API. It would be cool to see something like that in future.

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

2 participants