Test file: GRPCCall.h

pull/3961/head
Jorge Canizales 9 years ago
parent 98e4859e57
commit a6da17eeeb
  1. 236
      src/objective-c/GRPCClient/GRPCCall.h

@ -31,117 +31,145 @@
*
*/
// The gRPC protocol is an RPC protocol on top of HTTP2.
//
// While the most common type of RPC receives only one request message and returns only one response
// message, the protocol also supports RPCs that return multiple individual messages in a streaming
// fashion, RPCs that accept a stream of request messages, or RPCs with both streaming requests and
// responses.
//
// Conceptually, each gRPC call consists of a bidirectional stream of binary messages, with RPCs of
// the "non-streaming type" sending only one message in the corresponding direction (the protocol
// doesn't make any distinction).
//
// Each RPC uses a different HTTP2 stream, and thus multiple simultaneous RPCs can be multiplexed
// transparently on the same TCP connection.
/**
* The gRPC protocol is an RPC protocol on top of HTTP2.
*
* While the most common type of RPC receives only one request message and returns only one response
* message, the protocol also supports RPCs that return multiple individual messages in a streaming
* fashion, RPCs that accept a stream of request messages, or RPCs with both streaming requests and
* responses.
*
* Conceptually, each gRPC call consists of a bidirectional stream of binary messages, with RPCs of
* the "non-streaming type" sending only one message in the corresponding direction (the protocol
* doesn't make any distinction).
*
* Each RPC uses a different HTTP2 stream, and thus multiple simultaneous RPCs can be multiplexed
* transparently on the same TCP connection.
*/
#import <Foundation/Foundation.h>
#import <RxLibrary/GRXWriter.h>
#pragma mark gRPC errors
// Domain of NSError objects produced by gRPC.
/** Domain of NSError objects produced by gRPC. */
extern NSString *const kGRPCErrorDomain;
// gRPC error codes.
// Note that a few of these are never produced by the gRPC libraries, but are of general utility for
// server applications to produce.
/**
* gRPC error codes.
* Note that a few of these are never produced by the gRPC libraries, but are of general utility for
* server applications to produce.
*/
typedef NS_ENUM(NSUInteger, GRPCErrorCode) {
// The operation was cancelled (typically by the caller).
GRPCErrorCodeCancelled = 1,
// Unknown error. Errors raised by APIs that do not return enough error information may be
// converted to this error.
/**
* Unknown error. Errors raised by APIs that do not return enough error information may be
* converted to this error.
*/
GRPCErrorCodeUnknown = 2,
// The client specified an invalid argument. Note that this differs from FAILED_PRECONDITION.
// INVALID_ARGUMENT indicates arguments that are problematic regardless of the state of the
// server (e.g., a malformed file name).
/**
* The client specified an invalid argument. Note that this differs from FAILED_PRECONDITION.
* INVALID_ARGUMENT indicates arguments that are problematic regardless of the state of the
* server (e.g., a malformed file name).
*/
GRPCErrorCodeInvalidArgument = 3,
// Deadline expired before operation could complete. For operations that change the state of the
// server, this error may be returned even if the operation has completed successfully. For
// example, a successful response from the server could have been delayed long enough for the
// deadline to expire.
/**
* Deadline expired before operation could complete. For operations that change the state of the
* server, this error may be returned even if the operation has completed successfully. For
* example, a successful response from the server could have been delayed long enough for the
* deadline to expire.
*/
GRPCErrorCodeDeadlineExceeded = 4,
// Some requested entity (e.g., file or directory) was not found.
/** Some requested entity (e.g., file or directory) was not found. */
GRPCErrorCodeNotFound = 5,
// Some entity that we attempted to create (e.g., file or directory) already exists.
/** Some entity that we attempted to create (e.g., file or directory) already exists. */
GRPCErrorCodeAlreadyExists = 6,
// The caller does not have permission to execute the specified operation. PERMISSION_DENIED isn't
// used for rejections caused by exhausting some resource (RESOURCE_EXHAUSTED is used instead for
// those errors). PERMISSION_DENIED doesn't indicate a failure to identify the caller
// (UNAUTHENTICATED is used instead for those errors).
/**
* The caller does not have permission to execute the specified operation. PERMISSION_DENIED isn't
* used for rejections caused by exhausting some resource (RESOURCE_EXHAUSTED is used instead for
* those errors). PERMISSION_DENIED doesn't indicate a failure to identify the caller
* (UNAUTHENTICATED is used instead for those errors).
*/
GRPCErrorCodePermissionDenied = 7,
// The request does not have valid authentication credentials for the operation (e.g. the caller's
// identity can't be verified).
/**
* The request does not have valid authentication credentials for the operation (e.g. the caller's
* identity can't be verified).
*/
GRPCErrorCodeUnauthenticated = 16,
// Some resource has been exhausted, perhaps a per-user quota.
/** Some resource has been exhausted, perhaps a per-user quota. */
GRPCErrorCodeResourceExhausted = 8,
// The RPC was rejected because the server is not in a state required for the procedure's
// execution. For example, a directory to be deleted may be non-empty, etc.
// The client should not retry until the server state has been explicitly fixed (e.g. by
// performing another RPC). The details depend on the service being called, and should be found in
// the NSError's userInfo.
/**
* The RPC was rejected because the server is not in a state required for the procedure's
* execution. For example, a directory to be deleted may be non-empty, etc.
* The client should not retry until the server state has been explicitly fixed (e.g. by
* performing another RPC). The details depend on the service being called, and should be found in
* the NSError's userInfo.
*/
GRPCErrorCodeFailedPrecondition = 9,
// The RPC was aborted, typically due to a concurrency issue like sequencer check failures,
// transaction aborts, etc. The client should retry at a higher-level (e.g., restarting a read-
// modify-write sequence).
/**
* The RPC was aborted, typically due to a concurrency issue like sequencer check failures,
* transaction aborts, etc. The client should retry at a higher-level (e.g., restarting a read-
* modify-write sequence).
*/
GRPCErrorCodeAborted = 10,
// The RPC was attempted past the valid range. E.g., enumerating past the end of a list.
// Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed if the system state
// changes. For example, an RPC to get elements of a list will generate INVALID_ARGUMENT if asked
// to return the element at a negative index, but it will generate OUT_OF_RANGE if asked to return
// the element at an index past the current size of the list.
/**
* The RPC was attempted past the valid range. E.g., enumerating past the end of a list.
* Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed if the system state
* changes. For example, an RPC to get elements of a list will generate INVALID_ARGUMENT if asked
* to return the element at a negative index, but it will generate OUT_OF_RANGE if asked to return
* the element at an index past the current size of the list.
*/
GRPCErrorCodeOutOfRange = 11,
// The procedure is not implemented or not supported/enabled in this server.
/** The procedure is not implemented or not supported/enabled in this server. */
GRPCErrorCodeUnimplemented = 12,
// Internal error. Means some invariant expected by the server application or the gRPC library has
// been broken.
/**
* Internal error. Means some invariant expected by the server application or the gRPC library has
* been broken.
*/
GRPCErrorCodeInternal = 13,
// The server is currently unavailable. This is most likely a transient condition and may be
// corrected by retrying with a backoff.
/**
* The server is currently unavailable. This is most likely a transient condition and may be
* corrected by retrying with a backoff.
*/
GRPCErrorCodeUnavailable = 14,
// Unrecoverable data loss or corruption.
/** Unrecoverable data loss or corruption. */
GRPCErrorCodeDataLoss = 15,
};
// Keys used in |NSError|'s |userInfo| dictionary to store the response headers and trailers sent by
// the server.
/**
* Keys used in |NSError|'s |userInfo| dictionary to store the response headers and trailers sent by
* the server.
*/
extern id const kGRPCHeadersKey;
extern id const kGRPCTrailersKey;
#pragma mark GRPCCall
// The container of the request headers of an RPC conforms to this protocol, which is a subset of
// NSMutableDictionary's interface. It will become a NSMutableDictionary later on.
// The keys of this container are the header names, which per the HTTP standard are case-
// insensitive. They are stored in lowercase (which is how HTTP/2 mandates them on the wire), and
// can only consist of ASCII characters.
// A header value is a NSString object (with only ASCII characters), unless the header name has the
// suffix "-bin", in which case the value has to be a NSData object.
/**
* The container of the request headers of an RPC conforms to this protocol, which is a subset of
* NSMutableDictionary's interface. It will become a NSMutableDictionary later on.
* The keys of this container are the header names, which per the HTTP standard are case-
* insensitive. They are stored in lowercase (which is how HTTP/2 mandates them on the wire), and
* can only consist of ASCII characters.
* A header value is a NSString object (with only ASCII characters), unless the header name has the
* suffix "-bin", in which case the value has to be a NSData object.
*/
@protocol GRPCRequestHeaders <NSObject>
@property(nonatomic, readonly) NSUInteger count;
@ -154,54 +182,64 @@ extern id const kGRPCTrailersKey;
@end
// Represents a single gRPC remote call.
/** Represents a single gRPC remote call. */
@interface GRPCCall : GRXWriter
// These HTTP headers will be passed to the server as part of this call. Each HTTP header is a
// name-value pair with string names and either string or binary values.
//
// The passed dictionary has to use NSString keys, corresponding to the header names. The value
// associated to each can be a NSString object or a NSData object. E.g.:
//
// call.requestHeaders = @{@"authorization": @"Bearer ..."};
//
// call.requestHeaders[@"my-header-bin"] = someData;
//
// After the call is started, trying to modify this property is an error.
//
// The property is initialized to an empty NSMutableDictionary.
/**
* These HTTP headers will be passed to the server as part of this call. Each HTTP header is a
* name-value pair with string names and either string or binary values.
*
* The passed dictionary has to use NSString keys, corresponding to the header names. The value
* associated to each can be a NSString object or a NSData object. E.g.:
*
* call.requestHeaders = @{@"authorization": @"Bearer ..."};
*
* call.requestHeaders[@"my-header-bin"] = someData;
*
* After the call is started, trying to modify this property is an error.
*
* The property is initialized to an empty NSMutableDictionary.
*/
@property(atomic, readonly) id<GRPCRequestHeaders> requestHeaders;
// This dictionary is populated with the HTTP headers received from the server. This happens before
// any response message is received from the server. It has the same structure as the request
// headers dictionary: Keys are NSString header names; names ending with the suffix "-bin" have a
// NSData value; the others have a NSString value.
//
// The value of this property is nil until all response headers are received, and will change before
// any of -writeValue: or -writesFinishedWithError: are sent to the writeable.
/**
* This dictionary is populated with the HTTP headers received from the server. This happens before
* any response message is received from the server. It has the same structure as the request
* headers dictionary: Keys are NSString header names; names ending with the suffix "-bin" have a
* NSData value; the others have a NSString value.
*
* The value of this property is nil until all response headers are received, and will change before
* any of -writeValue: or -writesFinishedWithError: are sent to the writeable.
*/
@property(atomic, readonly) NSDictionary *responseHeaders;
// Same as responseHeaders, but populated with the HTTP trailers received from the server before the
// call finishes.
//
// The value of this property is nil until all response trailers are received, and will change
// before -writesFinishedWithError: is sent to the writeable.
/**
* Same as responseHeaders, but populated with the HTTP trailers received from the server before the
* call finishes.
*
* The value of this property is nil until all response trailers are received, and will change
* before -writesFinishedWithError: is sent to the writeable.
*/
@property(atomic, readonly) NSDictionary *responseTrailers;
// The request writer has to write NSData objects into the provided Writeable. The server will
// receive each of those separately and in order as distinct messages.
// A gRPC call might not complete until the request writer finishes. On the other hand, the request
// finishing doesn't necessarily make the call to finish, as the server might continue sending
// messages to the response side of the call indefinitely (depending on the semantics of the
// specific remote method called).
// To finish a call right away, invoke cancel.
/**
* The request writer has to write NSData objects into the provided Writeable. The server will
* receive each of those separately and in order as distinct messages.
* A gRPC call might not complete until the request writer finishes. On the other hand, the request
* finishing doesn't necessarily make the call to finish, as the server might continue sending
* messages to the response side of the call indefinitely (depending on the semantics of the
* specific remote method called).
* To finish a call right away, invoke cancel.
*/
- (instancetype)initWithHost:(NSString *)host
path:(NSString *)path
requestsWriter:(GRXWriter *)requestsWriter NS_DESIGNATED_INITIALIZER;
// Finishes the request side of this call, notifies the server that the RPC should be cancelled, and
// finishes the response side of the call with an error of code CANCELED.
/**
* Finishes the request side of this call, notifies the server that the RPC should be cancelled, and
* finishes the response side of the call with an error of code CANCELED.
*/
- (void)cancel;
// TODO(jcanizales): Let specify a deadline. As a category of GRXWriter?
/** TODO(jcanizales): Let specify a deadline. As a category of GRXWriter? */
@end

Loading…
Cancel
Save