diff options
author | Muxi Yan <muxi@users.noreply.github.com> | 2018-02-28 16:04:29 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-28 16:04:29 -0800 |
commit | c6c5ce923ca5233566dbba2550dc2876c5c2c4ef (patch) | |
tree | ac28cbf77b59f422bea9f4de8585887aff654cc3 /src/objective-c/GRPCClient/GRPCCall.m | |
parent | baf1a412624d20d1c11f60ddd66d47e58b3e3f35 (diff) |
Revert "Refactor connectivity monitor on iOS"
Diffstat (limited to 'src/objective-c/GRPCClient/GRPCCall.m')
-rw-r--r-- | src/objective-c/GRPCClient/GRPCCall.m | 136 |
1 files changed, 50 insertions, 86 deletions
diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 02492607cd..ac4596da25 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -108,9 +108,6 @@ static NSString * const kBearerPrefix = @"Bearer "; // The dispatch queue to be used for enqueuing responses to user. Defaulted to the main dispatch // queue dispatch_queue_t _responseQueue; - - // Whether the call is finished. If it is, should not call finishWithError again. - BOOL _finished; } @synthesize state = _state; @@ -209,8 +206,6 @@ static NSString * const kBearerPrefix = @"Bearer "; } else { [_responseWriteable enqueueSuccessfulCompletion]; } - - [GRPCConnectivityMonitor unregisterObserver:self]; } - (void)cancelCall { @@ -219,10 +214,9 @@ static NSString * const kBearerPrefix = @"Bearer "; } - (void)cancel { - [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{NSLocalizedDescriptionKey: @"Canceled by app"}]]; - + [self finishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{NSLocalizedDescriptionKey: @"Canceled by app"}]]; if (!self.isWaitingForToken) { [self cancelCall]; } else { @@ -230,19 +224,6 @@ static NSString * const kBearerPrefix = @"Bearer "; } } -- (void)maybeFinishWithError:(NSError *)errorOrNil { - BOOL toFinish = NO; - @synchronized(self) { - if (_finished == NO) { - _finished = YES; - toFinish = YES; - } - } - if (toFinish == YES) { - [self finishWithError:errorOrNil]; - } -} - - (void)dealloc { __block GRPCWrappedCall *wrappedCall = _wrappedCall; dispatch_async(_callQueue, ^{ @@ -269,13 +250,11 @@ static NSString * const kBearerPrefix = @"Bearer "; if (self.state == GRXWriterStatePaused) { return; } + __weak GRPCCall *weakSelf = self; + __weak GRXConcurrentWriteable *weakWriteable = _responseWriteable; dispatch_async(_callQueue, ^{ - __weak GRPCCall *weakSelf = self; - __weak GRXConcurrentWriteable *weakWriteable = self->_responseWriteable; - [self startReadWithHandler:^(grpc_byte_buffer *message) { - __strong GRPCCall *strongSelf = weakSelf; - __strong GRXConcurrentWriteable *strongWriteable = weakWriteable; + [weakSelf startReadWithHandler:^(grpc_byte_buffer *message) { if (message == NULL) { // No more messages from the server return; @@ -287,14 +266,14 @@ static NSString * const kBearerPrefix = @"Bearer "; // don't want to throw, because the app shouldn't crash for a behavior // that's on the hands of any server to have. Instead we finish and ask // the server to cancel. - [strongSelf maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeResourceExhausted - userInfo:@{NSLocalizedDescriptionKey: @"Client does not have enough memory to hold the server response."}]]; - [strongSelf cancelCall]; + [weakSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeResourceExhausted + userInfo:@{NSLocalizedDescriptionKey: @"Client does not have enough memory to hold the server response."}]]; + [weakSelf cancelCall]; return; } - [strongWriteable enqueueValue:data completionHandler:^{ - [strongSelf startNextRead]; + [weakWriteable enqueueValue:data completionHandler:^{ + [weakSelf startNextRead]; }]; }]; }); @@ -354,17 +333,12 @@ static NSString * const kBearerPrefix = @"Bearer "; _requestWriter.state = GRXWriterStatePaused; } + __weak GRPCCall *weakSelf = self; dispatch_async(_callQueue, ^{ - __weak GRPCCall *weakSelf = self; - [self writeMessage:value withErrorHandler:^{ - __strong GRPCCall *strongSelf = weakSelf; - if (strongSelf != nil) { - [strongSelf maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeInternal - userInfo:nil]]; - // Wrapped call must be canceled when error is reported to upper layers - [strongSelf cancelCall]; - } + [weakSelf writeMessage:value withErrorHandler:^{ + [weakSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeInternal + userInfo:nil]]; }]; }); } @@ -386,15 +360,12 @@ static NSString * const kBearerPrefix = @"Bearer "; if (errorOrNil) { [self cancel]; } else { + __weak GRPCCall *weakSelf = self; dispatch_async(_callQueue, ^{ - __weak GRPCCall *weakSelf = self; - [self finishRequestWithErrorHandler:^{ - __strong GRPCCall *strongSelf = weakSelf; - [strongSelf maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeInternal - userInfo:nil]]; - // Wrapped call must be canceled when error is reported to upper layers - [strongSelf cancelCall]; + [weakSelf finishRequestWithErrorHandler:^{ + [weakSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeInternal + userInfo:nil]]; }]; }); } @@ -416,37 +387,30 @@ static NSString * const kBearerPrefix = @"Bearer "; } - (void)invokeCall { - __weak GRPCCall *weakSelf = self; [self invokeCallWithHeadersHandler:^(NSDictionary *headers) { // Response headers received. - __strong GRPCCall *strongSelf = weakSelf; - if (strongSelf) { - strongSelf.responseHeaders = headers; - [strongSelf startNextRead]; - } + self.responseHeaders = headers; + [self startNextRead]; } completionHandler:^(NSError *error, NSDictionary *trailers) { - __strong GRPCCall *strongSelf = weakSelf; - if (strongSelf) { - strongSelf.responseTrailers = trailers; + self.responseTrailers = trailers; - if (error) { - NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; - if (error.userInfo) { - [userInfo addEntriesFromDictionary:error.userInfo]; - } - userInfo[kGRPCTrailersKey] = strongSelf.responseTrailers; - // TODO(jcanizales): The C gRPC library doesn't guarantee that the headers block will be - // called before this one, so an error might end up with trailers but no headers. We - // shouldn't call finishWithError until ater both blocks are called. It is also when this is - // done that we can provide a merged view of response headers and trailers in a thread-safe - // way. - if (strongSelf.responseHeaders) { - userInfo[kGRPCHeadersKey] = strongSelf.responseHeaders; - } - error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]; + if (error) { + NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; + if (error.userInfo) { + [userInfo addEntriesFromDictionary:error.userInfo]; + } + userInfo[kGRPCTrailersKey] = self.responseTrailers; + // TODO(jcanizales): The C gRPC library doesn't guarantee that the headers block will be + // called before this one, so an error might end up with trailers but no headers. We + // shouldn't call finishWithError until ater both blocks are called. It is also when this is + // done that we can provide a merged view of response headers and trailers in a thread-safe + // way. + if (self.responseHeaders) { + userInfo[kGRPCHeadersKey] = self.responseHeaders; } - [strongSelf maybeFinishWithError:error]; + error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]; } + [self finishWithError:error]; }]; // Now that the RPC has been initiated, request writes can start. @synchronized(_requestWriter) { @@ -475,8 +439,16 @@ static NSString * const kBearerPrefix = @"Bearer "; // TODO(jcanizales): Check this on init. [NSException raise:NSInvalidArgumentException format:@"host of %@ is nil", _host]; } - [GRPCConnectivityMonitor registerObserver:self - selector:@selector(connectivityChanged:)]; + _connectivityMonitor = [GRPCConnectivityMonitor monitorWithHost:host]; + __weak typeof(self) weakSelf = self; + void (^handler)(void) = ^{ + typeof(self) strongSelf = weakSelf; + [strongSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeUnavailable + userInfo:@{ NSLocalizedDescriptionKey : @"Connectivity lost." }]]; + }; + [_connectivityMonitor handleLossWithHandler:handler + wifiStatusChangeHandler:nil]; } - (void)startWithWriteable:(id<GRXWriteable>)writeable { @@ -540,12 +512,4 @@ static NSString * const kBearerPrefix = @"Bearer "; } } -- (void)connectivityChanged:(NSNotification *)note { - [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeUnavailable - userInfo:@{ NSLocalizedDescriptionKey : @"Connectivity lost." }]]; - // Cancel underlying call upon this notification - [self cancelCall]; -} - @end |