feat(session-sync): phased SW resync with experiment-ready config#573
feat(session-sync): phased SW resync with experiment-ready config#573Just-Insane wants to merge 7 commits intoSableClient:devfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds session re-sync phase controls (foreground + visible heartbeat with optional adaptive backoff/jitter) and introduces an experiment/config override pipeline so behavior can be rolled out via environment-scoped config.json overrides at build time.
Changes:
- Extend client config schema with
sessionSynctoggles andexperiments, plus helper APIs to deterministically bucket users into variants. - Update app visibility handling to optionally push the active session to the service worker on foreground/focus and on a visible heartbeat loop.
- Add a CI/build-time
config.jsonoverride injector and wire it into GitHub Actions (preview/production environments), plus update defaultconfig.json.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/app/pages/client/ClientRoot.tsx | Passes activeSession into useAppVisibility so SW session sync can include full session identity. |
| src/app/hooks/useClientConfig.ts | Adds sessionSync/experiments config shape and experiment variant selection helpers. |
| src/app/hooks/useAppVisibility.ts | Implements phased SW session pushes (foreground/focus + heartbeat + optional adaptive backoff/jitter). |
| scripts/inject-client-config.js | New build-time script to deep-merge env overrides into config.json. |
| knip.json | Adds the new script as a Knip entry. |
| config.json | Adds default experiments and sessionSync config blocks. |
| .github/workflows/cloudflare-web-preview.yml | Exposes env-scoped config override vars to preview deploy workflow. |
| .github/workflows/cloudflare-web-deploy.yml | Exposes env-scoped config override vars to plan/apply workflows (preview + production). |
| .github/actions/setup/action.yml | Runs the config override injector as part of build setup. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Addressing the three Copilot review comments from this PR:
Added an
Added a
|
a1445fe to
fa6d468
Compare
Add sessionSync config block documentation to the installation guide, including all timing fields, the three phase flags, and how to combine with experiments.sessionSyncStrategy for a controlled rollout. Corresponds to SableClient/Sable#573
Add sessionSync config block documentation to the installation guide, including all timing fields, the three phase flags, and how to combine with experiments.sessionSyncStrategy for a controlled rollout. Corresponds to SableClient/Sable#573
Add scripts/inject-client-config.js which reads HOMESERVER_LIST, ELEMENT_CALL_URL, EXPERIMENTS and other config keys from the GH Actions environment and merges them into config.json at build time. CI workflows pass these through via env; the setup action prints an injected-config summary in the job summary. knip.json updated to include the new script as an entry point.
…ntages useClientConfig.ts gains getExperimentVariant() which deterministically buckets a userId into a variant using a hash of userId+experimentName, then checks it against rolloutPercentage. Experiment defaults shape is typed so all callers get compile-time checking of known experiment names.
ExperimentsPanel shows every experiment name, current variant, rollout percentage, and whether the user is enrolled — readable without opening the console. DevelopTools.tsx wires it into the developer settings tab.
Three opt-in phases controlled by sessionSync flags in client config: - phase1ForegroundResync: resync session on app foreground - phase2VisibleHeartbeat: periodic heartbeat while app is visible - phase3AdaptiveBackoffJitter: exponential backoff with jitter Phase flags are automatically set from the sessionSyncStrategy experiment variant so rollout can be controlled via injected client config. Wired into ClientRoot via useAppVisibility.
9c568d8 to
09e1a89
Compare
Add sessionSync config block documentation to the installation guide, including all timing fields, the three phase flags, and how to combine with experiments.sessionSyncStrategy for a controlled rollout. Corresponds to SableClient/Sable#573
📝 Docs PR: SableClient/docs#9 — merge that when merging this.
PR dependency (stacked)
This branch is stacked on #572 — it has been rebased onto
feat/feature-flag-env-varswith no duplicate commits. Only the two session-sync–specific commits are unique to this PR. Please review/merge #572 first, then review this PR for session-sync behavior.Description
Adds phased service-worker session re-sync controls, gated behind an experiment flag with direct-config fallback.
Fixes #
Type of change
Checklist:
AI disclosure:
The phased session-sync hooks/flags and config integration were partially AI assisted; I verified branch behavior and safe defaults.
Feature Flags / Environment Setup
Set these GitHub Environment variables:
CLIENT_CONFIG_OVERRIDES_JSONCLIENT_CONFIG_OVERRIDES_STRICT(optional)How it works
Phase flags are derived in
useAppVisibilityfrom thesessionSyncStrategyexperiment:control(default)session-sync-heartbeatsession-sync-adaptiveUsers not in the experiment fall back to the
sessionSync.phase*booleans, which can be used for direct-config overrides (e.g. preview/staging where you want all users to get the feature without experiment bucketing).sessionSync config field reference
phase1ForegroundResyncfalsephase2VisibleHeartbeatfalsephase3AdaptiveBackoffJitterfalsephase2VisibleHeartbeatistrue.foregroundDebounceMs1500heartbeatIntervalMs600000resumeHeartbeatSuppressMs60000heartbeatMaxBackoffMs1800000Recommended initial values
preview— enable for all users directly (no bucketing):{ "sessionSync": { "phase1ForegroundResync": true, "phase2VisibleHeartbeat": true, "phase3AdaptiveBackoffJitter": true } }production— gradual rollout via experiment:{ "experiments": { "sessionSyncStrategy": { "enabled": true, "rolloutPercentage": 20, "controlVariant": "control", "variants": ["session-sync-heartbeat", "session-sync-adaptive"] } } }No environment variable setup is required for deployment to succeed; missing overrides are treated as no-op and checked-in defaults are used.