datastar icon indicating copy to clipboard operation
datastar copied to clipboard

Should use current signal state on SSE reconnect

Open wilaak opened this issue 7 months ago • 17 comments

Bug Report

When SSE automatically reconnects the signals are being sent as they were when the call first happened, rather than the current state of the signals.

Datastar Version

v1.0.0-beta.11

wilaak avatar May 19 '25 19:05 wilaak

@jmstevers do you know if this has already been addressed for V1?

bencroker avatar May 27 '25 16:05 bencroker

Seeing this on 1.0.0-RC.5 also.

aiba avatar Aug 20 '25 22:08 aiba

Thanks. I’ve raised in issue in the dev repo to address it.

bencroker avatar Aug 21 '25 07:08 bencroker

Also, only the client request is resent, the full script on say, the initiating :data-init isn't re-executed. [email protected]

milelo avatar Oct 30 '25 09:10 milelo

Also, only the client request is resent, the full script on say, the initiating :data-init isn't re-executed.

@milelo correct, only the fetch request is retried.

bencroker avatar Oct 30 '25 12:10 bencroker

Also, only the client request is resent, the full script on say, the initiating :data-init isn't re-executed.

@milelo correct, only the fetch request is retried.

@bencroker I assume this is considered a bug and will be fixed?

milelo avatar Oct 30 '25 13:10 milelo

Not a bug, no.

bencroker avatar Oct 30 '25 14:10 bencroker

Not a bug, no.

Ok thanks @bencroker. We could do with some good documentation covering this behaviour. I've spent a lot of time trying to debug problems because I didn't understand the behaviour in this area. First with sse disconnecting when I switched away from the view (it turned out this is intended when visibility changes) then problems with how to reconnect and handle broadcasting and now with the behaviour of signals and the script when reconnecting which eventually led me to this.

milelo avatar Oct 30 '25 16:10 milelo

I’m doing my best, @milelo. The openWhenHidden option has always been documented, and I recently published a how-to guide on the topic. I agree that there are many things that could be better documented, but we’re a small team working in our spare time.

We’re still evaluating whether SSE request retrying should send the initial signal values or current signal values.

As for the entire data-init expression being re-executed on request failure, that is purely your assumption, and not a desirable outcome. For example, it would be very unusual if $count was incremented on every retry of the fetch request.

<div data-init="$count++; @get('/endpoint')">

bencroker avatar Oct 30 '25 20:10 bencroker

Thanks Ben @bencroker, My apologies, don't get me wrong, I love what your doing and I think your all doing a fantastic job. This wasn't meant as criticism I was just pointing out some pain points as a new user, trying to figure out how to get this advanced alien tech to achieve the end results I have in mind. I can see that the many sdks that need to be supported present a documentation problem. As a user, I'm poor at being able to digest documentation in any detail without first having some practical experience. In the case of the sse disconnect, I didn't understand why it was happening but when I did the reasons made sense so I didn't want to inhibit it. Thanks but I hadn't seen your how-to-guide. I'm not sure of what is the best way of tracking changes, if anything, I'm just stumbling on them atm. Maybe the solution to many of these getting started issues would be a well commented app that illustrates many of these basic principals, translated into all the different server side languages. I started one myself for my own benefit, it needs updating for breaking changes and as my understanding evolves. Just saying :) fyi: https://discord.com/channels/1296224603642925098/1425817664164466769

milelo avatar Oct 31 '25 09:10 milelo

Regarding sending the signal-values, I'm trying to get the current value from sessionStorage back to the server that needs to be available at reconnect time. If it isn't made available in a signal here I don't know how to get it without another round-trip. Maybe the reconnect should be an explicit :data-on:reconnect with an error if it isn't defined to make the behaviour more explicit.

milelo avatar Oct 31 '25 11:10 milelo

I think it’s important to note the wording – the fetch request is “retried”. This implies, to me at least, that the initial signal state is what should be sent for each attempt.

We are nevertheless still discussing how we should handle this internally.

@milelo there already is an event that allow you to manually take action when a request fails, as per the docs:

<div data-on:datastar-fetch="
    evt.detail.type === 'error' && console.log('Fetch error encountered')
"></div>

bencroker avatar Oct 31 '25 21:10 bencroker

I think it’s important to note the wording – the fetch request is “retried”. This implies, to me at least, that the initial signal state is what should be sent for each attempt.

We are nevertheless still discussing how we should handle this internally.

@milelo there already is an event that allow you to manually take action when a request fails, as per the docs:

Thanks but I don't understand how it is relevant to the problem I'm trying to address. In the hope that I can get some help solving this I'll develop a test case and post it on the d*-clojure Discord.

milelo avatar Nov 05 '25 09:11 milelo

@milelo I meant that if a request fails, you can reinitiate it manually, which will send the current signals.

bencroker avatar Nov 05 '25 10:11 bencroker

For what it's worth, for how I'm using datastar, it would be really nice if SSE reconnect would send current signal values, not initial signal values. The way I think about it, "reconnect" is different than "retry". If I have a 5-minute SSE connection that involves a bunch of interactions that change signal values, and then the SSE gets disrupted for whatever reason and needs to reconnect, then I wouldn't think about that as a "failed" request that needs to be retried, but rather a request that got interrupted and needs to be resumed, and I would think that it's reasonable to resume with the latest state.

Maybe I'm missing some deeper datastar concepts, but I do keep running into issues where it would be nice for the client to tell the server what its current state is upon reconnect.

aiba avatar Nov 07 '25 20:11 aiba

I have encountered the same challenge, for now I'm managing reconnects externally.

A non breaking solution could be making this behavior configurable:

  • "original" by default: sending the original request (old signals), since its semantically correct.
  • "current": to send the current signals.

This would play nice, as it is a non braking change.

alvarolm avatar Nov 10 '25 15:11 alvarolm

@andersmurphy is looking into changing the behaviour so that current signals are sent.

bencroker avatar Nov 10 '25 15:11 bencroker

A handy trick from @andersmurphy, if you just need this issue addressed to preserve: "what's the last thing my /sse endpoint sent?" when the /sse connection reconnects.

You can encode the state you would store in signals into the id of the server sent event. On reconnect, you'll get your id back as the Last Event ID.

cablehead avatar Nov 28 '25 20:11 cablehead