File tree Expand file tree Collapse file tree 2 files changed +43
-2
lines changed Expand file tree Collapse file tree 2 files changed +43
-2
lines changed Original file line number Diff line number Diff line change @@ -355,6 +355,8 @@ class ActiveSubscription {
355
355
}
356
356
357
357
class SyncStreamSubscriptionHandle implements SyncStreamSubscription {
358
+ private active : boolean = false ;
359
+
358
360
constructor ( readonly subscription : ActiveSubscription ) {
359
361
subscription . refcount ++ ;
360
362
_finalizer ?. register ( this , subscription ) ;
@@ -373,8 +375,11 @@ class SyncStreamSubscriptionHandle implements SyncStreamSubscription {
373
375
}
374
376
375
377
unsubscribe ( ) : void {
376
- _finalizer ?. unregister ( this ) ;
377
- this . subscription . decrementRefCount ( ) ;
378
+ if ( this . active ) {
379
+ this . active = false ;
380
+ _finalizer ?. unregister ( this ) ;
381
+ this . subscription . decrementRefCount ( ) ;
382
+ }
378
383
}
379
384
}
380
385
Original file line number Diff line number Diff line change @@ -146,4 +146,40 @@ describe('Sync streams', () => {
146
146
let status = await statusPromise ;
147
147
expect ( status . forStream ( subscription ) ) . not . toBeNull ( ) ;
148
148
} ) ;
149
+
150
+ mockSyncServiceTest ( 'unsubscribing multiple times has no effect' , async ( { syncService } ) => {
151
+ const database = await syncService . createDatabase ( ) ;
152
+ const a = await database . syncStream ( 'a' ) . subscribe ( ) ;
153
+ const aAgain = await database . syncStream ( 'a' ) . subscribe ( ) ;
154
+ a . unsubscribe ( ) ;
155
+ a . unsubscribe ( ) ;
156
+
157
+ // Pretend the streams are expired - they should still be requested because the core extension extends the lifetime
158
+ // of streams currently referenced before connecting.
159
+ await database . execute ( 'UPDATE ps_stream_subscriptions SET expires_at = unixepoch() - 1000' ) ;
160
+ await database . connect ( new TestConnector ( ) , defaultOptions ) ;
161
+
162
+ expect ( syncService . connectedListeners [ 0 ] ) . toMatchObject ( {
163
+ streams : {
164
+ include_defaults : true ,
165
+ subscriptions : [ { } ]
166
+ }
167
+ } ) ;
168
+ aAgain . unsubscribe ( ) ;
169
+ } ) ;
170
+
171
+ mockSyncServiceTest ( 'unsubscribeAll' , async ( { syncService } ) => {
172
+ const database = await syncService . createDatabase ( ) ;
173
+ const a = await database . syncStream ( 'a' ) . subscribe ( ) ;
174
+ database . syncStream ( 'a' ) . unsubscribeAll ( ) ;
175
+
176
+ await database . connect ( new TestConnector ( ) , defaultOptions ) ;
177
+ expect ( syncService . connectedListeners [ 0 ] ) . toMatchObject ( {
178
+ streams : {
179
+ include_defaults : true ,
180
+ subscriptions : [ ]
181
+ }
182
+ } ) ;
183
+ a . unsubscribe ( ) ;
184
+ } ) ;
149
185
} ) ;
You can’t perform that action at this time.
0 commit comments