Skip to content

Commit a0d2a4d

Browse files
committed
feat(webapp): make the default realtime backend configurable
1 parent a3dca98 commit a0d2a4d

3 files changed

Lines changed: 13 additions & 5 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
area: webapp
3+
type: improvement
4+
---
5+
6+
Add a `REALTIME_BACKEND_DEFAULT` env var to choose the default realtime backend (`electric`, `native`, or `shadow`) for environments whose org has no per-org override. Defaults to `electric`, so existing behavior is unchanged.

apps/webapp/app/env.server.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,8 @@ const EnvironmentSchema = z
374374

375375
// Master switch for the native realtime backend; off = Electric serves everything, publishes no-op.
376376
REALTIME_BACKEND_NATIVE_ENABLED: z.string().default("0"),
377+
// Default backend when an org has no `realtimeBackend` override and no global flag row is set.
378+
REALTIME_BACKEND_DEFAULT: z.enum(["electric", "native", "shadow"]).default("electric"),
377379
// Live long-poll backstop hold (ms); matches Electric's ~20s cadence.
378380
REALTIME_BACKEND_NATIVE_LIVE_POLL_TIMEOUT_MS: z.coerce.number().int().default(20_000),
379381
// Jitter ratio on the live-poll hold (0.15 = ±15%) to avoid synchronized refetch herds.

apps/webapp/app/services/realtime/resolveRealtimeStreamClient.server.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import { getShadowRealtimeClient } from "./shadowRealtimeClientInstance.server";
1313

1414
type RealtimeBackend = "electric" | "native" | "shadow";
1515

16-
// Two gates, both defaulting to the Electric path: the env master switch, then the
17-
// per-org `realtimeBackend` feature flag (cached so long-polls don't hit the DB per request).
16+
// Two gates: the env master switch, then the per-org `realtimeBackend` feature flag (cached so
17+
// long-polls don't hit the DB per request), falling back to REALTIME_BACKEND_DEFAULT.
1818
const nativeBackendEnabled = env.REALTIME_BACKEND_NATIVE_ENABLED === "1";
1919

2020
const flag = singleton("realtimeBackendFlag", () => makeFlag($replica));
@@ -61,7 +61,7 @@ async function getRealtimeBackend(
6161
return cached;
6262
}
6363

64-
let backend: RealtimeBackend = "electric";
64+
let backend: RealtimeBackend = env.REALTIME_BACKEND_DEFAULT;
6565

6666
try {
6767
const overrides =
@@ -76,7 +76,7 @@ async function getRealtimeBackend(
7676

7777
backend = await flag({
7878
key: FEATURE_FLAG.realtimeBackend,
79-
defaultValue: "electric",
79+
defaultValue: env.REALTIME_BACKEND_DEFAULT,
8080
overrides: (overrides as Record<string, unknown>) ?? {},
8181
});
8282
} catch (error) {
@@ -85,7 +85,7 @@ async function getRealtimeBackend(
8585
organizationId,
8686
error,
8787
});
88-
backend = "electric";
88+
backend = env.REALTIME_BACKEND_DEFAULT;
8989
}
9090

9191
backendCache.set(organizationId, backend);

0 commit comments

Comments
 (0)