hilla icon indicating copy to clipboard operation
hilla copied to clipboard

Add method to Signal's to expose subsciber counts

Open petersj-ess opened this issue 9 months ago • 1 comments

Describe your motivation

I would like to be able to run a scheduled routine to update a Signals value periodically but only when a client is actually subscribed to the Signal.

Describe the solution you'd like

From what I can see it looks like we would just need to add a getSubscriberCount() method to Signal.java that would just return the size of the Set that contains the subscriber Flux's

Describe alternatives you've considered

No response

Additional context

No response

petersj-ess avatar Feb 12 '25 17:02 petersj-ess

It seems like you are pushing out updates from the server. This is not a use case that we're targeting right now even though we expect to do so at some point in the future. Right now, we're focusing on "collaboration" cases where the updates originate from clients. As you might have noticed, there's not even any API in Signal.java for directly publishing updates from the server even though it can be achieved by abusing some low-level APIs.

getSubscriberCount() might not be the most efficient approach since there might in some cases be thousands of instances to check for each iteration. It would be better if there would be some way of getting an event whenever a signal gets its first subscriber or loses its last subscriber. In a world with signals everywhere, this might be most natural in the form of a signal that has the subscriber count as its value so that you can create a signal effect to receive updates when it changes. I'm also thinking that this "meta" API that isn't directly related to the signal's value should maybe be "hidden" in a helper class somewhere rather than polluting that main Signal class API.

Flux might be a better tool for your use case at least until we have built out the case to better support server-originated updates. You can make your client-side Flux subscriber relay the received updates to a regular client-side signal to keep the same reactive programming model for the UI logic. You can often achieve a quite signal-like experience with the help of Sinks.many().replay().limit(1) on the server since that automatically buffers the latest message and sends it as an initial update to all new subscribers. You can then use sink.currentSubscriberCount() to achieve exactly what you described. Alternatively, you can use EndpointSubscription to define a callback that is run whenever someone subscribes or unsubscribes.

Legioth avatar Feb 13 '25 07:02 Legioth