@@ -64,6 +64,18 @@ @implementation FOutstandingPut
64
64
65
65
@end
66
66
67
+ @interface FOutstandingGet : NSObject
68
+
69
+ @property (nonatomic , strong ) NSDictionary *request;
70
+ @property (nonatomic , copy ) fbt_void_nsstring_id_nsstring onCompleteBlock;
71
+ @property (nonatomic ) BOOL sent;
72
+
73
+ @end
74
+
75
+ @implementation FOutstandingGet
76
+
77
+ @end
78
+
67
79
typedef enum {
68
80
ConnectionStateDisconnected,
69
81
ConnectionStateGettingToken,
@@ -92,9 +104,11 @@ - (void)sendOnDisconnectAction:(NSString *)action
92
104
@property (nonatomic , strong ) FConnection *realtime;
93
105
@property (nonatomic , strong ) NSMutableDictionary *listens;
94
106
@property (nonatomic , strong ) NSMutableDictionary *outstandingPuts;
107
+ @property (nonatomic , strong ) NSMutableDictionary *outstandingGets;
95
108
@property (nonatomic , strong ) NSMutableArray *onDisconnectQueue;
96
109
@property (nonatomic , strong ) FRepoInfo *repoInfo;
97
110
@property (nonatomic , strong ) FAtomicNumber *putCounter;
111
+ @property (nonatomic , strong ) FAtomicNumber *getCounter;
98
112
@property (nonatomic , strong ) FAtomicNumber *requestNumber;
99
113
@property (nonatomic , strong ) NSMutableDictionary *requestCBHash;
100
114
@property (nonatomic , strong ) FIRDatabaseConfig *config;
@@ -128,8 +142,10 @@ - (id)initWithRepoInfo:(FRepoInfo *)repoInfo
128
142
129
143
self.listens = [[NSMutableDictionary alloc ] init ];
130
144
self.outstandingPuts = [[NSMutableDictionary alloc ] init ];
145
+ self.outstandingGets = [[NSMutableDictionary alloc ] init ];
131
146
self.onDisconnectQueue = [[NSMutableArray alloc ] init ];
132
147
self.putCounter = [[FAtomicNumber alloc ] init ];
148
+ self.getCounter = [[FAtomicNumber alloc ] init ];
133
149
self.requestNumber = [[FAtomicNumber alloc ] init ];
134
150
self.requestCBHash = [[NSMutableDictionary alloc ] init ];
135
151
self.unackedListensCount = 0 ;
@@ -309,6 +325,10 @@ - (BOOL)canSendWrites {
309
325
return self->connectionState == ConnectionStateConnected;
310
326
}
311
327
328
+ - (BOOL )canSendReads {
329
+ return self->connectionState == ConnectionStateConnected;
330
+ }
331
+
312
332
#pragma mark -
313
333
#pragma mark FConnection delegate methods
314
334
@@ -707,6 +727,43 @@ - (void)sendPut:(NSNumber *)index {
707
727
}];
708
728
}
709
729
730
+ - (void )sendGet : (NSNumber *)index {
731
+ NSAssert ([self canSendReads ],
732
+ @" sendGet called when not able to send reads" );
733
+ FOutstandingGet *get = self.outstandingGets [index];
734
+ NSAssert (get != nil , @" sendGet found no outstanding get at index %@ " ,
735
+ index);
736
+ if ([get sent ]) {
737
+ return ;
738
+ }
739
+ get.sent = YES ;
740
+ [self sendAction: kFWPRequestActionGet
741
+ body: get.request
742
+ sensitive: NO
743
+ callback: ^(NSDictionary *data) {
744
+ FOutstandingGet *currentGet = self.outstandingGets [index];
745
+ if (currentGet == get) {
746
+ [self .outstandingGets removeObjectForKey: index];
747
+ NSString *status =
748
+ [data objectForKey: kFWPResponseForActionStatus ];
749
+ id resultData = [data objectForKey: kFWPResponseForActionData ];
750
+ if (resultData == (id )[NSNull null ]) {
751
+ resultData = nil ;
752
+ }
753
+ if ([status isEqualToString: kFWPResponseForActionStatusOk ]) {
754
+ get.onCompleteBlock (status, resultData, nil );
755
+ return ;
756
+ }
757
+ get.onCompleteBlock (status, nil , resultData);
758
+ } else {
759
+ FFLog (@" I-RDB034045" ,
760
+ @" Ignoring on complete for get %@ because it was "
761
+ @" already removed" ,
762
+ index);
763
+ }
764
+ }];
765
+ }
766
+
710
767
- (void )sendUnlisten : (FPath *)path
711
768
queryParams : (FQueryParams *)queryParams
712
769
tagId : (NSNumber *)tagId {
@@ -759,6 +816,46 @@ - (void)putInternal:(id)data
759
816
}
760
817
}
761
818
819
+ - (void )getDataAtPath : (NSString *)pathString
820
+ withParams : (NSDictionary *)queryWireProtocolParams
821
+ withCallback : (fbt_void_nsstring_id_nsstring)onComplete {
822
+ NSMutableDictionary *request = [NSMutableDictionary
823
+ dictionaryWithObjectsAndKeys: pathString, kFWPRequestPath ,
824
+ queryWireProtocolParams,
825
+ kFWPRequestQueries , nil ];
826
+ FOutstandingGet *get = [[FOutstandingGet alloc ] init ];
827
+ get.request = request;
828
+ get.onCompleteBlock = onComplete;
829
+ get.sent = NO ;
830
+
831
+ NSNumber *index = [self .getCounter getAndIncrement ];
832
+ self.outstandingGets [index] = get;
833
+
834
+ if (![self connected ]) {
835
+ dispatch_after (dispatch_time (DISPATCH_TIME_NOW,
836
+ kPersistentConnectionGetConnectTimeout ),
837
+ self.dispatchQueue , ^{
838
+ FOutstandingGet *get = self.outstandingGets [index];
839
+ if ([get sent ]) {
840
+ return ;
841
+ }
842
+ FFLog (@" I-RDB034045" ,
843
+ @" get %@ timed out waiting for a connection" ,
844
+ index);
845
+ get.sent = YES ;
846
+ [self .outstandingGets removeObjectForKey: index];
847
+ get.onCompleteBlock (kFWPResponseForActionStatusFailed ,
848
+ nil , kPersistentConnectionOffline );
849
+ });
850
+ return ;
851
+ }
852
+
853
+ if ([self canSendReads ]) {
854
+ FFLog (@" I-RDB034024" , @" Sending get: %@ " , index);
855
+ [self sendGet: index];
856
+ }
857
+ }
858
+
762
859
- (void )sendListen : (FOutstandingQuery *)listenSpec {
763
860
FQuerySpec *query = listenSpec.query ;
764
861
FFLog (@" I-RDB034026" , @" Listen for %@ " , query);
@@ -998,17 +1095,30 @@ - (void)restoreState {
998
1095
[self sendListen: outstandingListen];
999
1096
}];
1000
1097
1001
- NSArray *keys = [[self .outstandingPuts allKeys ]
1098
+ NSArray *putKeys = [[self .outstandingPuts allKeys ]
1002
1099
sortedArrayUsingSelector: @selector (compare: )];
1003
- for (int i = 0 ; i < [keys count ]; i++) {
1004
- if ([self .outstandingPuts objectForKey: [keys objectAtIndex: i]] != nil ) {
1100
+ for (int i = 0 ; i < [putKeys count ]; i++) {
1101
+ if ([self .outstandingPuts objectForKey: [putKeys objectAtIndex: i]] !=
1102
+ nil ) {
1005
1103
FFLog (@" I-RDB034037" , @" Restoring put: %d " , i);
1006
- [self sendPut: [keys objectAtIndex: i]];
1104
+ [self sendPut: [putKeys objectAtIndex: i]];
1007
1105
} else {
1008
1106
FFLog (@" I-RDB034038" , @" Restoring put: skipped nil: %d " , i);
1009
1107
}
1010
1108
}
1011
1109
1110
+ NSArray *getKeys = [[self .outstandingGets allKeys ]
1111
+ sortedArrayUsingSelector: @selector (compare: )];
1112
+ for (int i = 0 ; i < [getKeys count ]; i++) {
1113
+ if ([self .outstandingGets objectForKey: [getKeys objectAtIndex: i]] !=
1114
+ nil ) {
1115
+ FFLog (@" I-RDB034037" , @" Restoring get: %d " , i);
1116
+ [self sendGet: [getKeys objectAtIndex: i]];
1117
+ } else {
1118
+ FFLog (@" I-RDB034038" , @" Restoring get: skipped nil: %d " , i);
1119
+ }
1120
+ }
1121
+
1012
1122
for (FTupleOnDisconnect *tuple in self.onDisconnectQueue ) {
1013
1123
[self sendOnDisconnectAction: tuple.action
1014
1124
forPath: tuple.pathString
0 commit comments