Should use current signal state on SSE reconnect
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
@jmstevers do you know if this has already been addressed for V1?
Seeing this on 1.0.0-RC.5 also.
Thanks. I’ve raised in issue in the dev repo to address it.
Also, only the client request is resent, the full script on say, the initiating :data-init isn't re-executed. [email protected]
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.
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?
Not a bug, no.
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.
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')">
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
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.
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>
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 I meant that if a request fails, you can reinitiate it manually, which will send the current signals.
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.
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.
@andersmurphy is looking into changing the behaviour so that current signals are sent.
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.