@@ -106,3 +106,72 @@ controls who gets it.
106106Bucketing is deterministic and stable: the same user always receives the same variant for
107107a given experiment key. You can see your current variant assignments in
108108** Settings → Developer Tools → Features & Experiments** .
109+
110+ ## SW session resync configuration
111+
112+ Sable can automatically resync the Matrix session token held by the service worker in the
113+ background. This keeps push notifications and background sync working even after long idle
114+ periods where a browser or OS may have killed the service worker.
115+
116+ Add a ` sessionSync ` block to ` config.json ` to configure the behaviour:
117+
118+ ``` json
119+ {
120+ "sessionSync" : {
121+ "phase1ForegroundResync" : true ,
122+ "phase2VisibleHeartbeat" : false ,
123+ "phase3AdaptiveBackoffJitter" : false ,
124+ "foregroundDebounceMs" : 1500 ,
125+ "heartbeatIntervalMs" : 600000 ,
126+ "resumeHeartbeatSuppressMs" : 60000 ,
127+ "heartbeatMaxBackoffMs" : 1800000
128+ }
129+ }
130+ ```
131+
132+ | Field | Type | Default | Description |
133+ | ---| ---| ---| ---|
134+ | ` phase1ForegroundResync ` | boolean | ` false ` | Push session token to the SW when the app returns to the foreground (debounced) |
135+ | ` phase2VisibleHeartbeat ` | boolean | ` false ` | Periodically push the session token while the app is visible |
136+ | ` phase3AdaptiveBackoffJitter ` | boolean | ` false ` | Back off exponentially with jitter when heartbeat pushes fail |
137+ | ` foregroundDebounceMs ` | number | ` 1500 ` | Milliseconds to debounce foreground resync events |
138+ | ` heartbeatIntervalMs ` | number | ` 600000 ` | Milliseconds between heartbeat pushes (default: 10 min) |
139+ | ` resumeHeartbeatSuppressMs ` | number | ` 60000 ` | Suppress heartbeat for this many ms immediately after a foreground resync |
140+ | ` heartbeatMaxBackoffMs ` | number | ` 1800000 ` | Maximum backoff interval under phase 3 (default: 30 min) |
141+
142+ Each phase builds on the previous one. A typical starting deployment enables only
143+ ` phase1ForegroundResync ` ; phases 2 and 3 add more aggressive keep-alive behaviour
144+ suitable for users who leave the app open in a background tab.
145+
146+ ### Controlled rollout with experiments
147+
148+ To roll out session sync gradually, combine the ` sessionSync ` block with an
149+ ` experiments.sessionSyncStrategy ` entry:
150+
151+ ``` json
152+ {
153+ "sessionSync" : {
154+ "phase1ForegroundResync" : false ,
155+ "phase2VisibleHeartbeat" : false ,
156+ "phase3AdaptiveBackoffJitter" : false
157+ },
158+ "experiments" : {
159+ "sessionSyncStrategy" : {
160+ "enabled" : true ,
161+ "rolloutPercentage" : 20 ,
162+ "controlVariant" : " control" ,
163+ "variants" : [" session-sync-heartbeat" , " session-sync-adaptive" ]
164+ }
165+ }
166+ }
167+ ```
168+
169+ When this experiment is active, users bucketed into ` session-sync-heartbeat ` get phases 1
170+ and 2; users bucketed into ` session-sync-adaptive ` get all three phases; users outside the
171+ rollout percentage fall back to the raw ` sessionSync ` flags. For a true gradual rollout,
172+ set the ` sessionSync ` phase flags to ` false ` (or omit them) so that only experiment
173+ participants get session sync. Set ` rolloutPercentage: 0 ` or ` enabled: false ` to disable
174+ the experiment and fall back to the raw ` sessionSync ` flags for everyone.
175+
176+ See [ Feature flag and experiment configuration] ( #feature-flag-and-experiment-configuration )
177+ for the full experiments schema.
0 commit comments