File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 33 neither succeeds nor fails within 10 seconds, the SDK will consider itself
44 "offline", causing getDocument() calls to resolve with cached results, rather
55 than continuing to wait.
6+ - [ fixed] Fixed a potential race condition after calling ` enableNetwork() ` that
7+ could result in a "Mutation batchIDs must be acknowledged in order" assertion
8+ crash.
69
710# v0.10.3
811- [ fixed] Fixed a regression in the 4.10.0 Firebase iOS SDK release that
Original file line number Diff line number Diff line change @@ -217,6 +217,22 @@ - (void)testNextMutationBatchAfterBatchID {
217217 XCTAssertNil (notFound);
218218}
219219
220+ - (void )testNextMutationBatchAfterBatchIDSkipsAcknowledgedBatches {
221+ if ([self isTestBaseClass ]) return ;
222+
223+ NSMutableArray <FSTMutationBatch *> *batches = [self createBatches: 3 ];
224+ XCTAssertEqualObjects ([self .mutationQueue nextMutationBatchAfterBatchID: kFSTBatchIDUnknown ],
225+ batches[0 ]);
226+
227+ [self acknowledgeBatch: batches[0 ]];
228+ XCTAssertEqualObjects ([self .mutationQueue nextMutationBatchAfterBatchID: kFSTBatchIDUnknown ],
229+ batches[1 ]);
230+ XCTAssertEqualObjects ([self .mutationQueue nextMutationBatchAfterBatchID: batches[0 ].batchID],
231+ batches[1 ]);
232+ XCTAssertEqualObjects ([self .mutationQueue nextMutationBatchAfterBatchID: batches[1 ].batchID],
233+ batches[2 ]);
234+ }
235+
220236- (void )testAllMutationBatchesThroughBatchID {
221237 if ([self isTestBaseClass ]) return ;
222238
Original file line number Diff line number Diff line change 34073407 }
34083408 ]
34093409 },
3410+ "Held writes are not re-sent after disable/enable network." : {
3411+ "describeName" : " Writes:" ,
3412+ "itName" : " Held writes are not re-sent after disable/enable network." ,
3413+ "tags" : [],
3414+ "config" : {
3415+ "useGarbageCollection" : true
3416+ },
3417+ "steps" : [
3418+ {
3419+ "userListen" : [
3420+ 2 ,
3421+ {
3422+ "path" : " collection" ,
3423+ "filters" : [],
3424+ "orderBys" : []
3425+ }
3426+ ],
3427+ "stateExpect" : {
3428+ "activeTargets" : {
3429+ "2" : {
3430+ "query" : {
3431+ "path" : " collection" ,
3432+ "filters" : [],
3433+ "orderBys" : []
3434+ },
3435+ "resumeToken" : " "
3436+ }
3437+ }
3438+ }
3439+ },
3440+ {
3441+ "watchAck" : [
3442+ 2
3443+ ]
3444+ },
3445+ {
3446+ "watchEntity" : {
3447+ "docs" : [],
3448+ "targets" : [
3449+ 2
3450+ ]
3451+ }
3452+ },
3453+ {
3454+ "watchCurrent" : [
3455+ [
3456+ 2
3457+ ],
3458+ " resume-token-500"
3459+ ],
3460+ "watchSnapshot" : 500 ,
3461+ "expect" : [
3462+ {
3463+ "query" : {
3464+ "path" : " collection" ,
3465+ "filters" : [],
3466+ "orderBys" : []
3467+ },
3468+ "errorCode" : 0 ,
3469+ "fromCache" : false ,
3470+ "hasPendingWrites" : false
3471+ }
3472+ ]
3473+ },
3474+ {
3475+ "userSet" : [
3476+ " collection/a" ,
3477+ {
3478+ "v" : 1
3479+ }
3480+ ],
3481+ "expect" : [
3482+ {
3483+ "query" : {
3484+ "path" : " collection" ,
3485+ "filters" : [],
3486+ "orderBys" : []
3487+ },
3488+ "added" : [
3489+ [
3490+ " collection/a" ,
3491+ 0 ,
3492+ {
3493+ "v" : 1
3494+ },
3495+ " local"
3496+ ]
3497+ ],
3498+ "errorCode" : 0 ,
3499+ "fromCache" : false ,
3500+ "hasPendingWrites" : true
3501+ }
3502+ ]
3503+ },
3504+ {
3505+ "writeAck" : {
3506+ "version" : 1000 ,
3507+ "expectUserCallback" : true
3508+ },
3509+ "stateExpect" : {
3510+ "writeStreamRequestCount" : 2
3511+ }
3512+ },
3513+ {
3514+ "enableNetwork" : false ,
3515+ "stateExpect" : {
3516+ "activeTargets" : {},
3517+ "limboDocs" : [],
3518+ "writeStreamRequestCount" : 3
3519+ },
3520+ "expect" : [
3521+ {
3522+ "query" : {
3523+ "path" : " collection" ,
3524+ "filters" : [],
3525+ "orderBys" : []
3526+ },
3527+ "errorCode" : 0 ,
3528+ "fromCache" : true ,
3529+ "hasPendingWrites" : true
3530+ }
3531+ ]
3532+ },
3533+ {
3534+ "enableNetwork" : true ,
3535+ "stateExpect" : {
3536+ "activeTargets" : {
3537+ "2" : {
3538+ "query" : {
3539+ "path" : " collection" ,
3540+ "filters" : [],
3541+ "orderBys" : []
3542+ },
3543+ "resumeToken" : " resume-token-500"
3544+ }
3545+ },
3546+ "writeStreamRequestCount" : 3
3547+ }
3548+ },
3549+ {
3550+ "watchAck" : [
3551+ 2
3552+ ]
3553+ },
3554+ {
3555+ "watchEntity" : {
3556+ "docs" : [
3557+ [
3558+ " collection/a" ,
3559+ 1000 ,
3560+ {
3561+ "v" : 1
3562+ }
3563+ ]
3564+ ],
3565+ "targets" : [
3566+ 2
3567+ ]
3568+ }
3569+ },
3570+ {
3571+ "watchCurrent" : [
3572+ [
3573+ 2
3574+ ],
3575+ " resume-token-2000"
3576+ ],
3577+ "watchSnapshot" : 2000 ,
3578+ "expect" : [
3579+ {
3580+ "query" : {
3581+ "path" : " collection" ,
3582+ "filters" : [],
3583+ "orderBys" : []
3584+ },
3585+ "metadata" : [
3586+ [
3587+ " collection/a" ,
3588+ 1000 ,
3589+ {
3590+ "v" : 1
3591+ }
3592+ ]
3593+ ],
3594+ "errorCode" : 0 ,
3595+ "fromCache" : false ,
3596+ "hasPendingWrites" : false
3597+ }
3598+ ]
3599+ }
3600+ ]
3601+ },
34103602 "Held writes are released when there are no queries left." : {
34113603 "describeName" : " Writes:" ,
34123604 "itName" : " Held writes are released when there are no queries left." ,
Original file line number Diff line number Diff line change @@ -315,7 +315,12 @@ - (nullable FSTMutationBatch *)lookupMutationBatch:(FSTBatchID)batchID {
315315}
316316
317317- (nullable FSTMutationBatch *)nextMutationBatchAfterBatchID : (FSTBatchID)batchID {
318- std::string key = [self mutationKeyForBatchID: batchID + 1 ];
318+ // All batches with batchID <= self.metadata.lastAcknowledgedBatchId have been acknowledged so
319+ // the first unacknowledged batch after batchID will have a batchID larger than both of these
320+ // values.
321+ FSTBatchID nextBatchID = MAX (batchID, self.metadata .lastAcknowledgedBatchId ) + 1 ;
322+
323+ std::string key = [self mutationKeyForBatchID: nextBatchID];
319324 std::unique_ptr<Iterator> it (_db->NewIterator (StandardReadOptions ()));
320325 it->Seek (key);
321326
@@ -336,7 +341,7 @@ - (nullable FSTMutationBatch *)nextMutationBatchAfterBatchID:(FSTBatchID)batchID
336341 return nil ;
337342 }
338343
339- FSTAssert (rowKey.batchID > batchID , @" Should have found mutation after %d " , batchID );
344+ FSTAssert (rowKey.batchID >= nextBatchID , @" Should have found mutation after %d " , nextBatchID );
340345 return [self decodedMutationBatch: it->value ()];
341346}
342347
Original file line number Diff line number Diff line change @@ -192,10 +192,10 @@ - (nullable FSTMutationBatch *)nextMutationBatchAfterBatchID:(FSTBatchID)batchID
192192
193193 // All batches with batchID <= self.highestAcknowledgedBatchID have been acknowledged so the
194194 // first unacknowledged batch after batchID will have a batchID larger than both of these values.
195- batchID = MAX (batchID + 1 , self.highestAcknowledgedBatchID );
195+ FSTBatchID nextBatchID = MAX (batchID, self.highestAcknowledgedBatchID ) + 1 ;
196196
197197 // The requested batchID may still be out of range so normalize it to the start of the queue.
198- NSInteger rawIndex = [self indexOfBatchID: batchID ];
198+ NSInteger rawIndex = [self indexOfBatchID: nextBatchID ];
199199 NSUInteger index = rawIndex < 0 ? 0 : (NSUInteger )rawIndex;
200200
201201 // Finally return the first non-tombstone batch.
You can’t perform that action at this time.
0 commit comments