Debounce terminal SSE subscription reconnects
This commit is contained in:
@@ -4,6 +4,7 @@ import { useEffect, useSyncExternalStore } from "react";
|
||||
import { resolveBackendApiUrl } from "@/lib/backend-api";
|
||||
|
||||
const V1_EVENT_TYPE = "city_observation_patch.v1";
|
||||
const SSE_SUBSCRIPTION_RECONNECT_DELAY_MS = 150;
|
||||
|
||||
export type CityPatch = {
|
||||
type?: string;
|
||||
@@ -38,6 +39,7 @@ const subscribedCities = new Map<string, number>();
|
||||
|
||||
let eventSource: EventSource | null = null;
|
||||
let reconnectTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
let subscriptionReconnectTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
let reconnectAttempt = 0;
|
||||
let patchVersion = 0;
|
||||
let resyncVersion = 0;
|
||||
@@ -74,6 +76,12 @@ function clearReconnectTimer() {
|
||||
reconnectTimer = null;
|
||||
}
|
||||
|
||||
function clearSubscriptionReconnectTimer() {
|
||||
if (!subscriptionReconnectTimer) return;
|
||||
clearTimeout(subscriptionReconnectTimer);
|
||||
subscriptionReconnectTimer = null;
|
||||
}
|
||||
|
||||
function buildSseUrl(baseUrl: string) {
|
||||
const params = new URLSearchParams();
|
||||
const cities = subscribedCityList();
|
||||
@@ -113,6 +121,7 @@ function closeEventSource() {
|
||||
function reconnectNow() {
|
||||
if (typeof window === "undefined") return;
|
||||
clearReconnectTimer();
|
||||
clearSubscriptionReconnectTimer();
|
||||
closeEventSource();
|
||||
connectSsePatches();
|
||||
}
|
||||
@@ -159,6 +168,7 @@ function connectSsePatches() {
|
||||
|
||||
function ensureSsePatchConnection() {
|
||||
if (subscribedCities.size === 0) {
|
||||
clearSubscriptionReconnectTimer();
|
||||
closeEventSource();
|
||||
clearReconnectTimer();
|
||||
return;
|
||||
@@ -167,6 +177,19 @@ function ensureSsePatchConnection() {
|
||||
reconnectNow();
|
||||
}
|
||||
|
||||
function scheduleSubscriptionReconnect() {
|
||||
if (typeof window === "undefined") return;
|
||||
if (subscribedCities.size === 0) {
|
||||
ensureSsePatchConnection();
|
||||
return;
|
||||
}
|
||||
clearSubscriptionReconnectTimer();
|
||||
subscriptionReconnectTimer = setTimeout(() => {
|
||||
subscriptionReconnectTimer = null;
|
||||
ensureSsePatchConnection();
|
||||
}, SSE_SUBSCRIPTION_RECONNECT_DELAY_MS);
|
||||
}
|
||||
|
||||
function registerCitySubscription(city: string) {
|
||||
const cityKey = normalizeCityKey(city);
|
||||
if (!cityKey) return () => {};
|
||||
@@ -174,7 +197,7 @@ function registerCitySubscription(city: string) {
|
||||
const previousCount = subscribedCities.get(cityKey) ?? 0;
|
||||
subscribedCities.set(cityKey, previousCount + 1);
|
||||
if (previousCount === 0) {
|
||||
ensureSsePatchConnection();
|
||||
scheduleSubscriptionReconnect();
|
||||
}
|
||||
|
||||
return () => {
|
||||
@@ -184,7 +207,7 @@ function registerCitySubscription(city: string) {
|
||||
} else {
|
||||
subscribedCities.set(cityKey, nextCount);
|
||||
}
|
||||
ensureSsePatchConnection();
|
||||
scheduleSubscriptionReconnect();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user