Skip to content

Commit

Permalink
Merge pull request grpc#6378 from jcanizales/let-invalidate-channels
Browse files Browse the repository at this point in the history
Add a maybe-temporary way for apps to clear the channel cache
  • Loading branch information
jtattermusch authored Jun 30, 2016
2 parents 8ecf5f5 + 75fe9ba commit a5596db
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 56 deletions.
5 changes: 5 additions & 0 deletions src/objective-c/GRPCClient/GRPCCall+ChannelArg.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
*/
#import "GRPCCall.h"

#include <AvailabilityMacros.h>

/**
* Methods to configure GRPC channel options.
*/
Expand All @@ -43,4 +45,7 @@
*/
+ (void)setUserAgentPrefix:(NSString *)userAgentPrefix forHost:(NSString *)host;

+ (void)closeOpenConnections DEPRECATED_MSG_ATTRIBUTE("The API for this feature is experimental, "
"and might be removed or modified at any "
"time.");
@end
4 changes: 4 additions & 0 deletions src/objective-c/GRPCClient/GRPCCall+ChannelArg.m
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,8 @@ + (void)setUserAgentPrefix:(NSString *)userAgentPrefix forHost:(NSString *)host
hostConfig.userAgentPrefix = userAgentPrefix;
}

+ (void)closeOpenConnections {
[GRPCHost flushChannelCache];
}

@end
2 changes: 2 additions & 0 deletions src/objective-c/GRPCClient/private/GRPCHost.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ struct grpc_channel_credentials;

@interface GRPCHost : NSObject

+ (void)flushChannelCache;

@property(nonatomic, readonly) NSString *address;
@property(nonatomic, copy, nullable) NSString *userAgentPrefix;
@property(nonatomic, nullable) struct grpc_channel_credentials *channelCreds;
Expand Down
21 changes: 16 additions & 5 deletions src/objective-c/GRPCClient/private/GRPCHost.m
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
// templates/src/core/surface/version.c.template .
#define GRPC_OBJC_VERSION_STRING @"0.13.0"

static NSMutableDictionary *kHostCache;

@implementation GRPCHost {
// TODO(mlumish): Investigate whether caching channels with strong links is a good idea.
GRPCChannel *_channel;
Expand Down Expand Up @@ -82,26 +84,35 @@ - (nullable instancetype)initWithAddress:(NSString *)address {
}

// Look up the GRPCHost in the cache.
static NSMutableDictionary *hostCache;
static dispatch_once_t cacheInitialization;
dispatch_once(&cacheInitialization, ^{
hostCache = [NSMutableDictionary dictionary];
kHostCache = [NSMutableDictionary dictionary];
});
@synchronized(hostCache) {
GRPCHost *cachedHost = hostCache[address];
@synchronized(kHostCache) {
GRPCHost *cachedHost = kHostCache[address];
if (cachedHost) {
return cachedHost;
}

if ((self = [super init])) {
_address = address;
_secure = YES;
hostCache[address] = self;
kHostCache[address] = self;
}
}
return self;
}

+ (void)flushChannelCache {
@synchronized(kHostCache) {
[kHostCache enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key,
GRPCHost * _Nonnull host,
BOOL * _Nonnull stop) {
[host disconnect];
}];
}
}

- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path
completionQueue:(GRPCCompletionQueue *)queue {
GRPCChannel *channel;
Expand Down
25 changes: 25 additions & 0 deletions src/objective-c/tests/InteropTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <grpc/status.h>

#import <Cronet/Cronet.h>
#import <GRPCClient/GRPCCall+ChannelArg.h>
#import <GRPCClient/GRPCCall+Tests.h>
#import <GRPCClient/GRPCCall+Cronet.h>
#import <ProtoRPC/ProtoRPC.h>
Expand Down Expand Up @@ -337,4 +338,28 @@ - (void)testCancelAfterFirstResponseRPC {
[self waitForExpectationsWithTimeout:8 handler:nil];
}

- (void)testRPCAfterClosingOpenConnections {
XCTAssertNotNil(self.class.host);
__weak XCTestExpectation *expectation =
[self expectationWithDescription:@"RPC after closing connection"];

RMTEmpty *request = [RMTEmpty message];

[_service emptyCallWithRequest:request handler:^(RMTEmpty *response, NSError *error) {
XCTAssertNil(error, @"First RPC finished with unexpected error: %@", error);

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[GRPCCall closeOpenConnections];
#pragma clang diagnostic pop

[_service emptyCallWithRequest:request handler:^(RMTEmpty *response, NSError *error) {
XCTAssertNil(error, @"Second RPC finished with unexpected error: %@", error);
[expectation fulfill];
}];
}];

[self waitForExpectationsWithTimeout:4 handler:nil];
}

@end
Loading

0 comments on commit a5596db

Please sign in to comment.