diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index bc6a47d469c..49f5bfcc18b 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -33,19 +33,19 @@ #import -struct grpc_channel; +#include -// Each separate instance of this class represents at least one TCP -// connection to the provided host. To create a grpc_call, pass the -// value of the unmanagedChannel property to grpc_channel_create_call. -// Release this object when the call is finished. +// Each separate instance of this class represents at least one TCP connection to the provided host. +// To create a grpc_call to that host, use |unmanagedCallWithPath|. Release this object when the +// call is finished. @interface GRPCChannel : NSObject -@property(nonatomic, readonly) struct grpc_channel *unmanagedChannel; // Convenience constructor to allow for reuse of connections. + (instancetype)channelToHost:(NSString *)host; - (instancetype)initWithHost:(NSString *)host NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithChannel:(grpc_channel *)unmanagedChannel + hostName:(NSString *)hostName NS_DESIGNATED_INITIALIZER; -- (instancetype)initWithChannel:(struct grpc_channel *)unmanagedChannel NS_DESIGNATED_INITIALIZER; +- (grpc_call *)unmanagedCallWithPath:(NSString *)path; @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index af4326332f3..44f64e704a4 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -35,10 +35,15 @@ #include +#import "GRPCCompletionQueue.h" #import "GRPCSecureChannel.h" #import "GRPCUnsecuredChannel.h" -@implementation GRPCChannel +@implementation GRPCChannel { + grpc_channel *_unmanagedChannel; + NSString *_hostName; + GRPCCompletionQueue *_queue; +} + (instancetype)channelToHost:(NSString *)host { // TODO(mlumish): Investigate whether a cache with strong links is a good idea @@ -81,13 +86,32 @@ return nil; // silence warning. } -- (instancetype)initWithChannel:(struct grpc_channel *)unmanagedChannel { +- (instancetype)initWithChannel:(struct grpc_channel *)unmanagedChannel + hostName:(NSString *)hostName { + if (!unmanagedChannel || !hostName) { + [NSException raise:NSInvalidArgumentException + format:@"Neither unmanagedChannel nor hostName can be nil."]; + } if ((self = [super init])) { _unmanagedChannel = unmanagedChannel; + _hostName = hostName; + // In case sharing the queue creates contention, we can change it to one per grpc_call. + _queue = [GRPCCompletionQueue completionQueue]; + if (!_queue) { + return nil; + } } return self; } +- (grpc_call *)unmanagedCallWithPath:(NSString *)path { + return grpc_channel_create_call(_unmanagedChannel, + _queue.unmanagedQueue, + path.UTF8String, + _hostName.UTF8String, + gpr_inf_future(GPR_CLOCK_REALTIME)); +} + - (void)dealloc { // _unmanagedChannel is NULL when deallocating an object of the base class (because the // initializer returns a different object). diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannel.m b/src/objective-c/GRPCClient/private/GRPCSecureChannel.m index 43a8bd539ed..2dbbd520878 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannel.m @@ -54,7 +54,8 @@ }); return (self = [super initWithChannel:grpc_secure_channel_create(kCredentials, host.UTF8String, - NULL)]); + NULL) + hostName:host]); } @end diff --git a/src/objective-c/GRPCClient/private/GRPCUnsecuredChannel.m b/src/objective-c/GRPCClient/private/GRPCUnsecuredChannel.m index 8518f78c5b2..4941cbc3dd1 100644 --- a/src/objective-c/GRPCClient/private/GRPCUnsecuredChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCUnsecuredChannel.m @@ -38,7 +38,8 @@ @implementation GRPCUnsecuredChannel - (instancetype)initWithHost:(NSString *)host { - return (self = [super initWithChannel:grpc_insecure_channel_create(host.UTF8String, NULL)]); + return (self = [super initWithChannel:grpc_insecure_channel_create(host.UTF8String, NULL) + hostName:host]); } @end diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 4681994bb22..db062336aaf 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -39,7 +39,6 @@ #include #import "GRPCChannel.h" -#import "GRPCCompletionQueue.h" #import "NSDictionary+GRPC.h" #import "NSData+GRPC.h" #import "NSError+GRPC.h" @@ -227,7 +226,6 @@ @implementation GRPCWrappedCall{ GRPCChannel *_channel; grpc_call *_call; - GRPCCompletionQueue *_queue; } - (instancetype)init { @@ -240,26 +238,15 @@ [NSException raise:NSInvalidArgumentException format:@"path and host cannot be nil."]; } - + if (self = [super init]) { static dispatch_once_t initialization; dispatch_once(&initialization, ^{ grpc_init(); }); - - _queue = [GRPCCompletionQueue completionQueue]; - if (!_queue) { - return nil; - } + _channel = [GRPCChannel channelToHost:host]; - if (!_channel) { - return nil; - } - _call = grpc_channel_create_call(_channel.unmanagedChannel, - _queue.unmanagedQueue, - path.UTF8String, - host.UTF8String, - gpr_inf_future(GPR_CLOCK_REALTIME)); + _call = [_channel unmanagedCallWithPath:path]; if (_call == NULL) { return nil; } @@ -308,4 +295,4 @@ grpc_call_destroy(_call); } -@end \ No newline at end of file +@end