aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/objective-c/GRPCClient/GRPCCall.m
diff options
context:
space:
mode:
authorGravatar Muxi Yan <muxi@users.noreply.github.com>2018-02-28 16:04:29 -0800
committerGravatar GitHub <noreply@github.com>2018-02-28 16:04:29 -0800
commitc6c5ce923ca5233566dbba2550dc2876c5c2c4ef (patch)
treeac28cbf77b59f422bea9f4de8585887aff654cc3 /src/objective-c/GRPCClient/GRPCCall.m
parentbaf1a412624d20d1c11f60ddd66d47e58b3e3f35 (diff)
Revert "Refactor connectivity monitor on iOS"
Diffstat (limited to 'src/objective-c/GRPCClient/GRPCCall.m')
-rw-r--r--src/objective-c/GRPCClient/GRPCCall.m136
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