aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/objective-c/GRPCClient
diff options
context:
space:
mode:
Diffstat (limited to 'src/objective-c/GRPCClient')
-rw-r--r--src/objective-c/GRPCClient/GRPCCall.h20
-rw-r--r--src/objective-c/GRPCClient/GRPCCall.m33
-rw-r--r--src/objective-c/GRPCClient/private/GRPCChannel.h4
-rw-r--r--src/objective-c/GRPCClient/private/GRPCHost.m4
-rw-r--r--src/objective-c/GRPCClient/private/GRPCWrappedCall.h4
-rw-r--r--src/objective-c/GRPCClient/private/GRPCWrappedCall.m12
6 files changed, 66 insertions, 11 deletions
diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h
index b9e741dfa8..7645bb1d34 100644
--- a/src/objective-c/GRPCClient/GRPCCall.h
+++ b/src/objective-c/GRPCClient/GRPCCall.h
@@ -155,6 +155,18 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) {
};
/**
+ * Safety remark of a gRPC method as defined in RFC 2616 Section 9.1
+ */
+typedef NS_ENUM(NSUInteger, GRPCCallSafety) {
+ /** Signal that there is no guarantees on how the call affects the server state. */
+ GRPCCallSafetyDefault = 0,
+ /** Signal that the call is idempotent. gRPC is free to use PUT verb. */
+ GRPCCallSafetyIdempotentRequest = 1,
+ /** Signal that the call is cacheable and will not affect server state. gRPC is free to use GET verb. */
+ GRPCCallSafetyCacheableRequest = 2,
+};
+
+/**
* Keys used in |NSError|'s |userInfo| dictionary to store the response headers and trailers sent by
* the server.
*/
@@ -233,6 +245,14 @@ extern id const kGRPCTrailersKey;
*/
- (void)cancel;
+/**
+ * Set the call flag for a specific host path.
+ *
+ * Host parameter should not contain the scheme (http:// or https://), only the name or IP addr
+ * and the port number, for example @"localhost:5050".
+ */
++ (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path;
+
// TODO(jcanizales): Let specify a deadline. As a category of GRXWriter?
@end
diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m
index b5d8309787..43204345f5 100644
--- a/src/objective-c/GRPCClient/GRPCCall.m
+++ b/src/objective-c/GRPCClient/GRPCCall.m
@@ -47,6 +47,7 @@
NSString * const kGRPCHeadersKey = @"io.grpc.HeadersKey";
NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey";
+static NSMutableDictionary *callFlags;
@interface GRPCCall () <GRXWriteable>
// Make them read-write.
@@ -106,6 +107,29 @@ NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey";
// TODO(jcanizales): If grpc_init is idempotent, this should be changed from load to initialize.
+ (void)load {
grpc_init();
+ callFlags = [NSMutableDictionary dictionary];
+}
+
++ (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path {
+ NSString *hostAndPath = [NSString stringWithFormat:@"%@/%@", host, path];
+ switch (callSafety) {
+ case GRPCCallSafetyDefault:
+ callFlags[hostAndPath] = @0;
+ break;
+ case GRPCCallSafetyIdempotentRequest:
+ callFlags[hostAndPath] = @GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST;
+ break;
+ case GRPCCallSafetyCacheableRequest:
+ callFlags[hostAndPath] = @GRPC_INITIAL_METADATA_CACHEABLE_REQUEST;
+ break;
+ default:
+ break;
+ }
+}
+
++ (uint32_t)callFlagsForHost:(NSString *)host path:(NSString *)path {
+ NSString *hostAndPath = [NSString stringWithFormat:@"%@/%@", host, path];
+ return [callFlags[hostAndPath] intValue];
}
- (instancetype)init {
@@ -213,13 +237,9 @@ NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey";
// 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.
- //
- // TODO(jcanizales): No canonical code is appropriate for this situation
- // (because it's just a client problem). Use another domain and an
- // appropriately-documented code.
[weakSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
- code:GRPCErrorCodeInternal
- userInfo:nil]];
+ code:GRPCErrorCodeResourceExhausted
+ userInfo:@{NSLocalizedDescriptionKey: @"Client does not have enough memory to hold the server response."}]];
[weakSelf cancelCall];
return;
}
@@ -235,6 +255,7 @@ NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey";
- (void)sendHeaders:(NSDictionary *)headers {
// TODO(jcanizales): Add error handlers for async failures
[_wrappedCall startBatchWithOperations:@[[[GRPCOpSendMetadata alloc] initWithMetadata:headers
+ flags:[GRPCCall callFlagsForHost:_host path:_path]
handler:nil]]];
}
diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h
index 40e78a92d6..5bada2dd50 100644
--- a/src/objective-c/GRPCClient/private/GRPCChannel.h
+++ b/src/objective-c/GRPCClient/private/GRPCChannel.h
@@ -59,8 +59,8 @@ struct grpc_channel_credentials;
* Creates a secure channel to the specified @c host using Cronet as a transport mechanism.
*/
#ifdef GRPC_COMPILE_WITH_CRONET
-+ (nullable GRPCChannel *)secureCronetChannelWithHost:(NSString *)host
- channelArgs:(NSDictionary *)channelArgs;
++ (nullable GRPCChannel *)secureCronetChannelWithHost:(nonnull NSString *)host
+ channelArgs:(nonnull NSDictionary *)channelArgs;
#endif
/**
* Creates a secure channel to the specified @c host using the specified @c credentials and
diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m
index 9cd9593d17..f8634b448e 100644
--- a/src/objective-c/GRPCClient/private/GRPCHost.m
+++ b/src/objective-c/GRPCClient/private/GRPCHost.m
@@ -217,8 +217,10 @@ static NSMutableDictionary *kHostCache;
}
if (_responseSizeLimitOverride) {
- args[@GRPC_ARG_MAX_MESSAGE_LENGTH] = _responseSizeLimitOverride;
+ args[@GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH] = _responseSizeLimitOverride;
}
+ // Use 10000ms initial backoff time for correct behavior on bad/slow networks
+ args[@GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS] = @10000;
return args;
}
diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h
index e37ed1b59f..52233c8242 100644
--- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h
+++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h
@@ -45,6 +45,10 @@
@interface GRPCOpSendMetadata : GRPCOperation
- (instancetype)initWithMetadata:(NSDictionary *)metadata
+ handler:(void(^)())handler;
+
+- (instancetype)initWithMetadata:(NSDictionary *)metadata
+ flags:(uint32_t)flags
handler:(void(^)())handler NS_DESIGNATED_INITIALIZER;
@end
diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
index 1339429660..627b6aa86d 100644
--- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
+++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
@@ -64,16 +64,24 @@
@implementation GRPCOpSendMetadata
- (instancetype)init {
- return [self initWithMetadata:nil handler:nil];
+ return [self initWithMetadata:nil flags:0 handler:nil];
}
-- (instancetype)initWithMetadata:(NSDictionary *)metadata handler:(void (^)())handler {
+- (instancetype)initWithMetadata:(NSDictionary *)metadata
+ handler:(void (^)())handler {
+ return [self initWithMetadata:metadata flags:0 handler:handler];
+}
+
+- (instancetype)initWithMetadata:(NSDictionary *)metadata
+ flags:(uint32_t)flags
+ handler:(void (^)())handler {
if (self = [super init]) {
_op.op = GRPC_OP_SEND_INITIAL_METADATA;
_op.data.send_initial_metadata.count = metadata.count;
_op.data.send_initial_metadata.metadata = metadata.grpc_metadataArray;
_op.data.send_initial_metadata.maybe_compression_level.is_set = false;
_op.data.send_initial_metadata.maybe_compression_level.level = 0;
+ _op.flags = flags;
_handler = handler;
}
return self;