@@ -924,7 +924,7 @@ describeSpec('Limbo Documents:', [], () => {
924
924
) ;
925
925
926
926
specTest (
927
- 'Enqueued limbo resolutions should be removed when query listen stops' ,
927
+ 'A limbo resolution for a document should be removed from the queue when the last query listen stops' ,
928
928
[ ] ,
929
929
( ) => {
930
930
const doc1 = doc ( 'collection1/doc' , 1000 , { key : 1 } ) ;
@@ -934,38 +934,136 @@ describeSpec('Limbo Documents:', [], () => {
934
934
const doc2 = doc ( 'collection2/doc' , 1000 , { key : 2 } ) ;
935
935
const query2 = query ( 'collection2' ) ;
936
936
const filteredQuery2 = query ( 'collection2' , filter ( 'key' , '==' , 2 ) ) ;
937
+ const filteredQuery3 = query ( 'collection2' , filter ( 'key' , '>=' , 2 ) ) ;
937
938
938
939
return (
939
940
spec ( )
940
941
. withGCEnabled ( false )
941
942
. withMaxConcurrentLimboResolutions ( 1 )
942
943
943
944
// Max out the number of active limbo resolutions.
944
- . userListens ( filteredQuery1 )
945
- . watchAcksFull ( filteredQuery1 , 1000 , doc1 )
946
- . expectEvents ( filteredQuery1 , { added : [ doc1 ] } )
947
- . userUnlistens ( filteredQuery1 )
948
945
. userListens ( query1 )
949
- . expectEvents ( query1 , { added : [ doc1 ] , fromCache : true } )
950
- . watchAcksFull ( query1 , 1001 )
946
+ . watchAcksFull ( query1 , 1000 , doc1 )
947
+ . expectEvents ( query1 , { added : [ doc1 ] } )
948
+ . userUnlistens ( query1 )
949
+ . userListens ( filteredQuery1 )
950
+ . expectEvents ( filteredQuery1 , { added : [ doc1 ] , fromCache : true } )
951
+ . watchAcksFull ( filteredQuery1 , 1001 )
951
952
. expectLimboDocs ( doc1 . key )
952
953
953
- // Enqueue a limbo resolution from another query.
954
+ // Enqueue a limbo resolution for doc2.
955
+ . userListens ( query2 )
956
+ . watchAcksFull ( query2 , 1002 , doc2 )
957
+ . expectEvents ( query2 , { added : [ doc2 ] } )
958
+ . userUnlistens ( query2 )
954
959
. userListens ( filteredQuery2 )
955
- . watchAcksFull ( filteredQuery2 , 1002 , doc2 )
956
- . expectEvents ( filteredQuery2 , { added : [ doc2 ] } )
960
+ . expectEvents ( filteredQuery2 , { added : [ doc2 ] , fromCache : true } )
961
+ . watchAcksFull ( filteredQuery2 , 1003 )
962
+ . expectLimboDocs ( doc1 . key )
963
+ . expectEnqueuedLimboDocs ( doc2 . key )
964
+
965
+ // Start another query that puts doc2 into limbo again.
966
+ . userListens ( filteredQuery3 )
967
+ . expectEvents ( filteredQuery3 , { added : [ doc2 ] , fromCache : true } )
968
+ . watchAcksFull ( filteredQuery3 , 1004 )
969
+ . expectLimboDocs ( doc1 . key )
970
+ . expectEnqueuedLimboDocs ( doc2 . key )
971
+
972
+ // Stop one of the queries that enqueued a limbo resolution for doc2;
973
+ // verify that doc2 is not removed from the limbo resolution queue.
974
+ . userUnlistens ( filteredQuery3 )
975
+ . expectLimboDocs ( doc1 . key )
976
+ . expectEnqueuedLimboDocs ( doc2 . key )
977
+
978
+ // Stop the other query that enqueued a limbo resolution for doc2;
979
+ // verify that doc2 *is* removed from the limbo resolution queue.
957
980
. userUnlistens ( filteredQuery2 )
981
+ . expectLimboDocs ( doc1 . key )
982
+ . expectEnqueuedLimboDocs ( )
983
+ ) ;
984
+ }
985
+ ) ;
986
+
987
+ specTest (
988
+ 'A limbo resolution for a document should not be started if one is already active' ,
989
+ [ ] ,
990
+ ( ) => {
991
+ const doc1 = doc ( 'collection/doc' , 1000 , { key : 1 } ) ;
992
+ const query1 = query ( 'collection' ) ;
993
+ const filteredQuery1 = query ( 'collection' , filter ( 'key' , '==' , 1 ) ) ;
994
+ const filteredQuery2 = query ( 'collection' , filter ( 'key' , '>=' , 1 ) ) ;
995
+
996
+ return (
997
+ spec ( )
998
+ . withGCEnabled ( false )
999
+
1000
+ // Start a limbo resolution listen for a document.
1001
+ . userListens ( query1 )
1002
+ . watchAcksFull ( query1 , 1000 , doc1 )
1003
+ . expectEvents ( query1 , { added : [ doc1 ] } )
1004
+ . userUnlistens ( query1 )
1005
+ . userListens ( filteredQuery1 )
1006
+ . expectEvents ( filteredQuery1 , { added : [ doc1 ] , fromCache : true } )
1007
+ . watchAcksFull ( filteredQuery1 , 1001 )
1008
+ . expectLimboDocs ( doc1 . key )
1009
+ . expectEnqueuedLimboDocs ( )
1010
+
1011
+ // Put the same document into limbo in a different query.
1012
+ . userListens ( filteredQuery2 )
1013
+ . expectEvents ( filteredQuery2 , { added : [ doc1 ] , fromCache : true } )
1014
+ . watchAcksFull ( filteredQuery2 , 1002 )
1015
+ . expectLimboDocs ( doc1 . key )
1016
+ . expectEnqueuedLimboDocs ( )
1017
+ ) ;
1018
+ }
1019
+ ) ;
1020
+
1021
+ specTest (
1022
+ 'A limbo resolution for a document should not be enqueued if one is already enqueued' ,
1023
+ [ ] ,
1024
+ ( ) => {
1025
+ const doc1 = doc ( 'collection1/doc1' , 1000 , { key : 1 } ) ;
1026
+ const query1 = query ( 'collection1' ) ;
1027
+ const filteredQuery1 = query ( 'collection1' , filter ( 'key' , '==' , 1 ) ) ;
1028
+ const doc2 = doc ( 'collection2/doc2' , 1000 , { key : 2 } ) ;
1029
+ const query2 = query ( 'collection2' ) ;
1030
+ const filteredQuery2 = query ( 'collection2' , filter ( 'key' , '==' , 2 ) ) ;
1031
+ const filteredQuery3 = query ( 'collection2' , filter ( 'key' , '>=' , 2 ) ) ;
1032
+
1033
+ return (
1034
+ spec ( )
1035
+ . withGCEnabled ( false )
1036
+ . withMaxConcurrentLimboResolutions ( 1 )
1037
+
1038
+ // Max out the number of active limbo resolutions.
1039
+ . userListens ( query1 )
1040
+ . watchAcksFull ( query1 , 1000 , doc1 )
1041
+ . expectEvents ( query1 , { added : [ doc1 ] } )
1042
+ . userUnlistens ( query1 )
1043
+ . userListens ( filteredQuery1 )
1044
+ . expectEvents ( filteredQuery1 , { added : [ doc1 ] , fromCache : true } )
1045
+ . watchAcksFull ( filteredQuery1 , 1001 )
1046
+ . expectLimboDocs ( doc1 . key )
1047
+
1048
+ // Start a limbo resolution listen for a different document.
958
1049
. userListens ( query2 )
959
- . expectEvents ( query2 , { added : [ doc2 ] , fromCache : true } )
960
- . watchAcksFull ( query2 , 1003 )
1050
+ . watchAcksFull ( query2 , 1002 , doc2 )
1051
+ . expectEvents ( query2 , { added : [ doc2 ] } )
1052
+ . userUnlistens ( query2 )
1053
+ . userListens ( filteredQuery2 )
1054
+ . expectEvents ( filteredQuery2 , { added : [ doc2 ] , fromCache : true } )
1055
+ . watchAcksFull ( filteredQuery2 , 1003 )
961
1056
. expectLimboDocs ( doc1 . key )
962
1057
. expectEnqueuedLimboDocs ( doc2 . key )
963
1058
964
- // Stop the other query and ensure that the enqueued limbo resolution
965
- // is removed.
966
- . userUnlistens ( query2 )
1059
+ // Put the the "different" document into limbo in a different query
1060
+ // and verify that it's not added to the limbo resolution queue a
1061
+ // second time.
1062
+ . userListens ( filteredQuery3 )
1063
+ . expectEvents ( filteredQuery3 , { added : [ doc2 ] , fromCache : true } )
1064
+ . watchAcksFull ( filteredQuery3 , 1004 )
967
1065
. expectLimboDocs ( doc1 . key )
968
- . expectEnqueuedLimboDocs ( )
1066
+ . expectEnqueuedLimboDocs ( doc2 . key )
969
1067
) ;
970
1068
}
971
1069
) ;
0 commit comments