-
Notifications
You must be signed in to change notification settings - Fork 181
Description
Hello. I'm aware this topic has been raised many times here already, and I have read all of those issues with no success. Indeed, in most cases those issues have comments from people saying the proposed solution didn't work for them either. I am running my app in React.StrictMode, which causes each component to mount/unmount/remount to help identify unexpected side-effects and so on. In my case this is causing two fetchEventSource requests to be fired, which is expected. What's unexpected, is that using an AbortController does not close the first connection on unmount. This is my hook:
const useStreamTradingNotifications = () => {
const [ abortController, setAbortController ] = useState(new AbortController());
useEffect(() => {
console.log("useEffect called");
const stream = async () => {
await fetchEventSource("http://127.0.0.1:8000/v1/notifications", {
signal: abortController.signal,
onmessage(msg) {
if (abortController.signal.aborted){
console.log("still getting messages from aborted signal")
}
console.log(`event: ${msg.event}`)
if (msg.event == "update") {
console.log(JSON.parse(msg.data))
}
},
});
};
stream();
return () => {
console.log("abort called")
abortController.abort();
setAbortController(new AbortController());
}
}, []);
};When I run my app, I see the following logs:

As you can see:
useEffectis called twice, as the component is mounted/unmounted/remounted [expected]abortController.abortis called when the first component unmounts [expected]- Subsequently I receive two of each message (the logs above are truncated, and just includes the first duplicate). For one of the two streams, I can confirm that the messages are being received on an already-aborted connection (
still getting messages from aborted signal).
Furthermore, in my backend logs, when I close a browser window with an active connection I see a log like:
[2024-07-09T11:13:37.409247Z][sse_starlette.sse][DEBUG] Got event: http.disconnect. Stop streaming.
But I never see this message as the result of AbortController.abort being called. I have tried assigning a new instance of AbortController after abort (as suggested here), which had no affect. I have tried doing a similar thing with setState (as mentioned here) which made the problem much worse (kept creating connections until the browser crashed). I tried to use useRef to manage the controller (suggested here, which also doesn't work.
The fact that I can see abort being called, but never see a http.disconnect on the backend, convinces me this must be a bug. But if anybody has a suspicion that I've screwed something up I'd really appreciate their suggestion.
Many thanks