From 0c0ebc57e26ffc0579fda10cce65976d8ad06e0f Mon Sep 17 00:00:00 2001 From: Muxi Yan <mxyan@google.com> Date: Thu, 19 Oct 2017 18:41:01 -0700 Subject: [PATCH 01/10] Fix gRPC ObjC void function definition --- src/objective-c/GRPCClient/GRPCCall.m | 6 +++--- .../GRPCClient/private/GRPCConnectivityMonitor.h | 4 ++-- .../GRPCClient/private/GRPCConnectivityMonitor.m | 4 ++-- src/objective-c/GRPCClient/private/GRPCHost.m | 2 +- .../GRPCClient/private/GRPCWrappedCall.h | 10 +++++----- .../GRPCClient/private/GRPCWrappedCall.m | 14 +++++++------- src/objective-c/RxLibrary/GRXConcurrentWriteable.h | 2 +- src/objective-c/RxLibrary/GRXConcurrentWriteable.m | 2 +- src/objective-c/RxLibrary/GRXImmediateWriter.h | 2 +- src/objective-c/RxLibrary/GRXImmediateWriter.m | 2 +- src/objective-c/RxLibrary/GRXWriter+Immediate.h | 2 +- src/objective-c/RxLibrary/GRXWriter+Immediate.m | 2 +- src/objective-c/RxLibrary/NSEnumerator+GRXUtil.h | 2 +- src/objective-c/RxLibrary/NSEnumerator+GRXUtil.m | 2 +- .../RxLibrary/private/GRXNSBlockEnumerator.h | 2 +- .../RxLibrary/private/GRXNSBlockEnumerator.m | 4 ++-- 16 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index d6c3a3c165a..eb02c21a7aa 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -296,7 +296,7 @@ static NSString * const kBearerPrefix = @"Bearer "; // network queue if the write didn't succeed. // If the call is a unary call, parameter \a errorHandler will be ignored and // the error handler of GRPCOpSendClose will be executed in case of error. -- (void)writeMessage:(NSData *)message withErrorHandler:(void (^)())errorHandler { +- (void)writeMessage:(NSData *)message withErrorHandler:(void (^)(void))errorHandler { __weak GRPCCall *weakSelf = self; void(^resumingHandler)(void) = ^{ @@ -342,7 +342,7 @@ static NSString * const kBearerPrefix = @"Bearer "; // Only called from the call queue. The error handler will be called from the // network queue if the requests stream couldn't be closed successfully. -- (void)finishRequestWithErrorHandler:(void (^)())errorHandler { +- (void)finishRequestWithErrorHandler:(void (^)(void))errorHandler { if (!_unaryCall) { [_wrappedCall startBatchWithOperations:@[[[GRPCOpSendClose alloc] init]] errorHandler:errorHandler]; @@ -438,7 +438,7 @@ static NSString * const kBearerPrefix = @"Bearer "; } _connectivityMonitor = [GRPCConnectivityMonitor monitorWithHost:host]; __weak typeof(self) weakSelf = self; - void (^handler)() = ^{ + void (^handler)(void) = ^{ typeof(self) strongSelf = weakSelf; [strongSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeUnavailable diff --git a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h index 8d3c45ee501..cb55e46d70e 100644 --- a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h +++ b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h @@ -57,6 +57,6 @@ * Only one handler is active at a time, so if this method is called again before the previous * handler has been called, it might never be called at all (or yes, if it has already been queued). */ -- (void)handleLossWithHandler:(nullable void (^)())lossHandler - wifiStatusChangeHandler:(nullable void (^)())wifiStatusChangeHandler; +- (void)handleLossWithHandler:(nullable void (^)(void))lossHandler + wifiStatusChangeHandler:(nullable void (^)(void))wifiStatusChangeHandler; @end diff --git a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m index b3226385005..c8e10dd75f1 100644 --- a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m +++ b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m @@ -136,8 +136,8 @@ static void PassFlagsToContextInfoBlock(SCNetworkReachabilityRef target, return returnValue; } -- (void)handleLossWithHandler:(nullable void (^)())lossHandler - wifiStatusChangeHandler:(nullable void (^)())wifiStatusChangeHandler { +- (void)handleLossWithHandler:(nullable void (^)(void))lossHandler + wifiStatusChangeHandler:(nullable void (^)(void))wifiStatusChangeHandler { __weak typeof(self) weakSelf = self; [self startListeningWithHandler:^(GRPCReachabilityFlags *flags) { typeof(self) strongSelf = weakSelf; diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index f73e9cbc507..a0f41187400 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -93,7 +93,7 @@ static GRPCConnectivityMonitor *connectivityMonitor = nil; if (!connectivityMonitor) { connectivityMonitor = [GRPCConnectivityMonitor monitorWithHost:hostURL.host]; - void (^handler)() = ^{ + void (^handler)(void) = ^{ [GRPCHost flushChannelCache]; }; [connectivityMonitor handleLossWithHandler:handler diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h index 1cd9da8f3ea..f569895e7c2 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h @@ -30,24 +30,24 @@ @interface GRPCOpSendMetadata : GRPCOperation - (instancetype)initWithMetadata:(NSDictionary *)metadata - handler:(void(^)())handler; + handler:(void(^)(void))handler; - (instancetype)initWithMetadata:(NSDictionary *)metadata flags:(uint32_t)flags - handler:(void(^)())handler NS_DESIGNATED_INITIALIZER; + handler:(void(^)(void))handler NS_DESIGNATED_INITIALIZER; @end @interface GRPCOpSendMessage : GRPCOperation - (instancetype)initWithMessage:(NSData *)message - handler:(void(^)())handler NS_DESIGNATED_INITIALIZER; + handler:(void(^)(void))handler NS_DESIGNATED_INITIALIZER; @end @interface GRPCOpSendClose : GRPCOperation -- (instancetype)initWithHandler:(void(^)())handler NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithHandler:(void(^)(void))handler NS_DESIGNATED_INITIALIZER; @end @@ -79,7 +79,7 @@ path:(NSString *)path timeout:(NSTimeInterval)timeout NS_DESIGNATED_INITIALIZER; -- (void)startBatchWithOperations:(NSArray *)ops errorHandler:(void(^)())errorHandler; +- (void)startBatchWithOperations:(NSArray *)ops errorHandler:(void(^)(void))errorHandler; - (void)startBatchWithOperations:(NSArray *)ops; diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index b0b1223b64c..d26d13475d3 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -36,12 +36,12 @@ // Most operation subclasses don't set any flags in the grpc_op, and rely on the flag member being // initialized to zero. grpc_op _op; - void(^_handler)(); + void(^_handler)(void); } - (void)finish { if (_handler) { - void(^handler)() = _handler; + void(^handler)(void) = _handler; _handler = nil; handler(); } @@ -55,13 +55,13 @@ } - (instancetype)initWithMetadata:(NSDictionary *)metadata - handler:(void (^)())handler { + handler:(void (^)(void))handler { return [self initWithMetadata:metadata flags:0 handler:handler]; } - (instancetype)initWithMetadata:(NSDictionary *)metadata flags:(uint32_t)flags - handler:(void (^)())handler { + handler:(void (^)(void))handler { if (self = [super init]) { _op.op = GRPC_OP_SEND_INITIAL_METADATA; _op.data.send_initial_metadata.count = metadata.count; @@ -92,7 +92,7 @@ return [self initWithMessage:nil handler:nil]; } -- (instancetype)initWithMessage:(NSData *)message handler:(void (^)())handler { +- (instancetype)initWithMessage:(NSData *)message handler:(void (^)(void))handler { if (!message) { [NSException raise:NSInvalidArgumentException format:@"message cannot be nil"]; } @@ -116,7 +116,7 @@ return [self initWithHandler:nil]; } -- (instancetype)initWithHandler:(void (^)())handler { +- (instancetype)initWithHandler:(void (^)(void))handler { if (self = [super init]) { _op.op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; _handler = handler; @@ -271,7 +271,7 @@ [self startBatchWithOperations:operations errorHandler:nil]; } -- (void)startBatchWithOperations:(NSArray *)operations errorHandler:(void (^)())errorHandler { +- (void)startBatchWithOperations:(NSArray *)operations errorHandler:(void (^)(void))errorHandler { // Keep logs of op batches when we are running tests. Disabled when in production for improved // performance. #ifdef GRPC_TEST_OBJC diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h index cec45fae715..f16a3d052ad 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h @@ -46,7 +46,7 @@ * Enqueues writeValue: to be sent to the writeable in the main thread. * The passed handler is invoked from the main thread after writeValue: returns. */ -- (void)enqueueValue:(id)value completionHandler:(void (^)())handler; +- (void)enqueueValue:(id)value completionHandler:(void (^)(void))handler; /** * Enqueues writesFinishedWithError:nil to be sent to the writeable in the main thread. After that diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m index bbfe491783b..37bc975f874 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m @@ -50,7 +50,7 @@ dispatchQueue:dispatch_get_main_queue()]; } -- (void)enqueueValue:(id)value completionHandler:(void (^)())handler { +- (void)enqueueValue:(id)value completionHandler:(void (^)(void))handler { dispatch_async(_writeableQueue, ^{ // We're racing a possible cancellation performed by another thread. To turn all already- // enqueued messages into noops, cancellation nillifies the writeable property. If we get it diff --git a/src/objective-c/RxLibrary/GRXImmediateWriter.h b/src/objective-c/RxLibrary/GRXImmediateWriter.h index bdcf5d59374..f88e46b1698 100644 --- a/src/objective-c/RxLibrary/GRXImmediateWriter.h +++ b/src/objective-c/RxLibrary/GRXImmediateWriter.h @@ -46,7 +46,7 @@ * Returns a writer that pushes to its writeable the successive values returned by the passed * block. When the block first returns nil, it is released. */ -+ (GRXWriter *)writerWithValueSupplier:(id (^)())block; ++ (GRXWriter *)writerWithValueSupplier:(id (^)(void))block; /** * Returns a writer that iterates over the values of the passed container and pushes them to diff --git a/src/objective-c/RxLibrary/GRXImmediateWriter.m b/src/objective-c/RxLibrary/GRXImmediateWriter.m index d8c6975801c..c5d6d1310ae 100644 --- a/src/objective-c/RxLibrary/GRXImmediateWriter.m +++ b/src/objective-c/RxLibrary/GRXImmediateWriter.m @@ -52,7 +52,7 @@ return [self writerWithEnumerator:enumerator error:nil]; } -+ (GRXWriter *)writerWithValueSupplier:(id (^)())block { ++ (GRXWriter *)writerWithValueSupplier:(id (^)(void))block { return [self writerWithEnumerator:[NSEnumerator grx_enumeratorWithValueSupplier:block]]; } diff --git a/src/objective-c/RxLibrary/GRXWriter+Immediate.h b/src/objective-c/RxLibrary/GRXWriter+Immediate.h index 292a35f61fd..d7935deaa22 100644 --- a/src/objective-c/RxLibrary/GRXWriter+Immediate.h +++ b/src/objective-c/RxLibrary/GRXWriter+Immediate.h @@ -30,7 +30,7 @@ * Returns a writer that pushes to its writeable the successive values returned by the passed * block. When the block first returns nil, it is released. */ -+ (instancetype)writerWithValueSupplier:(id (^)())block; ++ (instancetype)writerWithValueSupplier:(id (^)(void))block; /** * Returns a writer that iterates over the values of the passed container and pushes them to diff --git a/src/objective-c/RxLibrary/GRXWriter+Immediate.m b/src/objective-c/RxLibrary/GRXWriter+Immediate.m index 43aa9c54375..a36a56764d2 100644 --- a/src/objective-c/RxLibrary/GRXWriter+Immediate.m +++ b/src/objective-c/RxLibrary/GRXWriter+Immediate.m @@ -27,7 +27,7 @@ return [GRXImmediateWriter writerWithEnumerator:enumerator]; } -+ (instancetype)writerWithValueSupplier:(id (^)())block { ++ (instancetype)writerWithValueSupplier:(id (^)(void))block { return [GRXImmediateWriter writerWithValueSupplier:block]; } diff --git a/src/objective-c/RxLibrary/NSEnumerator+GRXUtil.h b/src/objective-c/RxLibrary/NSEnumerator+GRXUtil.h index 8c72f7858d8..38dbaaf9a4d 100644 --- a/src/objective-c/RxLibrary/NSEnumerator+GRXUtil.h +++ b/src/objective-c/RxLibrary/NSEnumerator+GRXUtil.h @@ -38,5 +38,5 @@ * Returns a NSEnumerator instance that delegates the invocations of nextObject to the passed block. * When the block first returns nil, it is released. */ -+ (NSEnumerator *)grx_enumeratorWithValueSupplier:(id (^)())block; ++ (NSEnumerator *)grx_enumeratorWithValueSupplier:(id (^)(void))block; @end diff --git a/src/objective-c/RxLibrary/NSEnumerator+GRXUtil.m b/src/objective-c/RxLibrary/NSEnumerator+GRXUtil.m index 309e25ede54..7d8191d0f7a 100644 --- a/src/objective-c/RxLibrary/NSEnumerator+GRXUtil.m +++ b/src/objective-c/RxLibrary/NSEnumerator+GRXUtil.m @@ -33,7 +33,7 @@ return [[GRXNSScalarEnumerator alloc] initWithValue:value]; } -+ (NSEnumerator *)grx_enumeratorWithValueSupplier:(id (^)())block { ++ (NSEnumerator *)grx_enumeratorWithValueSupplier:(id (^)(void))block { return [[GRXNSBlockEnumerator alloc] initWithValueSupplier:block]; } @end diff --git a/src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.h b/src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.h index c45338acdd7..c3317b2d049 100644 --- a/src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.h +++ b/src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.h @@ -27,5 +27,5 @@ * The first time the passed block returns nil, the enumeration will end and the block will be * released. */ -- (instancetype)initWithValueSupplier:(id (^)())block; +- (instancetype)initWithValueSupplier:(id (^)(void))block; @end diff --git a/src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.m b/src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.m index 7e7cc572b85..eddfd266802 100644 --- a/src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.m +++ b/src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.m @@ -19,14 +19,14 @@ #import "GRXNSBlockEnumerator.h" @implementation GRXNSBlockEnumerator { - id (^_block)(); + id (^_block)(void); } - (instancetype)init { return [self initWithValueSupplier:nil]; } -- (instancetype)initWithValueSupplier:(id (^)())block { +- (instancetype)initWithValueSupplier:(id (^)(void))block { if ((self = [super init])) { _block = block; } From 739ff08a7f4686306ef8d5b72c2a89b12305e275 Mon Sep 17 00:00:00 2001 From: Muxi Yan <mxyan@google.com> Date: Fri, 20 Oct 2017 14:49:58 -0700 Subject: [PATCH 02/10] Fix gRPC Core API void function definition --- include/grpc/grpc_security.h | 2 +- include/grpc/support/alloc.h | 2 +- include/grpc/support/log.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 95b14479354..2aede6ee5d4 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -185,7 +185,7 @@ GRPCAPI grpc_call_credentials *grpc_composite_call_credentials_create( GRPCAPI grpc_call_credentials *grpc_google_compute_engine_credentials_create( void *reserved); -GRPCAPI gpr_timespec grpc_max_auth_token_lifetime(); +GRPCAPI gpr_timespec grpc_max_auth_token_lifetime(void); /** Creates a JWT credentials object. May return NULL if the input is invalid. - json_key is the JSON key string containing the client's private key. diff --git a/include/grpc/support/alloc.h b/include/grpc/support/alloc.h index 4b59e137f25..5a01c159763 100644 --- a/include/grpc/support/alloc.h +++ b/include/grpc/support/alloc.h @@ -58,7 +58,7 @@ GPRAPI void gpr_free_aligned(void *ptr); GPRAPI void gpr_set_allocation_functions(gpr_allocation_functions functions); /** Return the family of allocation functions currently in effect. */ -GPRAPI gpr_allocation_functions gpr_get_allocation_functions(); +GPRAPI gpr_allocation_functions gpr_get_allocation_functions(void); #ifdef __cplusplus } diff --git a/include/grpc/support/log.h b/include/grpc/support/log.h index a22fb6a6e26..7190399aca1 100644 --- a/include/grpc/support/log.h +++ b/include/grpc/support/log.h @@ -68,7 +68,7 @@ GPRAPI void gpr_log_message(const char *file, int line, /** Set global log verbosity */ GPRAPI void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print); -GPRAPI void gpr_log_verbosity_init(); +GPRAPI void gpr_log_verbosity_init(void); /** Log overrides: applications can use this API to intercept logging calls and use their own implementations */ From d4e296b36b7379aae98cfe5aa72700e47b7bbb71 Mon Sep 17 00:00:00 2001 From: Vijay Pai <vpai@google.com> Date: Wed, 8 Nov 2017 14:13:44 -0800 Subject: [PATCH 03/10] Transport explainer --- doc/core/transport_explainer.md | 197 +++++++++++++++++++++++++++ tools/doxygen/Doxyfile.core | 1 + tools/doxygen/Doxyfile.core.internal | 1 + 3 files changed, 199 insertions(+) create mode 100644 doc/core/transport_explainer.md diff --git a/doc/core/transport_explainer.md b/doc/core/transport_explainer.md new file mode 100644 index 00000000000..f48fa0f3b1f --- /dev/null +++ b/doc/core/transport_explainer.md @@ -0,0 +1,197 @@ +# Transport Explainer + +@vjpai + +## Existing Transports + +[gRPC +transports](https://github.com/grpc/grpc/tree/master/src/core/ext/transport) +plug in below the core API (one level below the C++ or other wrapped-language +API). You can write your transport in C or C++ though; currently (Nov 2017) all +the transports are nominally written in C++ though they are idiomatically C. The +existing transports are: + +* [HTTP/2](https://github.com/grpc/grpc/tree/master/src/core/ext/transport/chttp2) +* [Cronet](https://github.com/grpc/grpc/tree/master/src/core/ext/transport/cronet) +* [In-process](https://github.com/grpc/grpc/tree/master/src/core/ext/transport/inproc) + +Among these, the in-process is likely the easiest to understand, though arguably +also the least similar to a "real" sockets-based transport since it is only used +in a single process. + +## Transport stream ops + +In the gRPC core implementation, a fundamental struct is the +`grpc_transport_stream_op_batch` which represents a collection of stream +operations sent to a transport. (Note that in gRPC, _stream_ and _RPC_ are used +synonymously since all RPCs are actually streams internally.) The ops in a batch +can include: + +* send\_initial\_metadata + - Client: initate an RPC + - Server: supply response headers +* recv\_initial\_metadata + - Client: get response headers + - Server: accept an RPC +* send\_message (zero or more) : send a data buffer +* recv\_message (zero or more) : receive a data buffer +* send\_trailing\_metadata + - Client: half-close indicating that no more messages will be coming + - Server: full-close providing final status for the RPC +* recv\_trailing\_metadata: get final status for the RPC + - Server extra: This op shouldn't actually be considered complete until the + server has also sent trailing metadata to provide the other side with final + status +* cancel\_stream: Attempt to cancel an RPC +* collect\_stats: Get stats + +The fundamental responsibility of the transport is to transform between this +internal format and an actual wire format, so the processing of these operations +is largely transport-specific. + +One or more of these ops are grouped into a batch. Applications can start all of +a call's ops in a single batch, or they can split them up into multiple +batches. Results of each batch are returned asynchronously via a completion +queue. + +Internally, we use callbacks to indicate completion. The surface layer creates a +callback when starting a new batch and sends it down the filter stack along with +the batch. The transport must invoke this callback when the batch is complete, +and then the surface layer returns an event to the application via the +completion queue. Each batch can have up to 3 callbacks: + +* recv\_initial\_metadata\_ready (called by the transport when the + recv\_initial\_metadata op is complete) +* recv\_message\_ready (called by the transport when the recv_message op is + complete) +* on\_complete (called by the transport when the entire batch is complete) + +## Timelines of transport stream op batches + +The transport's job is to sequence and interpret various possible interleavings +of the basic stream ops. For example, a sample timeline of batches would be: + +1. Client send\_initial\_metadata: Initiate an RPC with a path (method) and authority +1. Server recv\_initial\_metadata: accept an RPC +1. Client send\_message: Supply the input proto for the RPC +1. Server recv\_message: Get the input proto from the RPC +1. Client send\_trailing\_metadata: This is a half-close indicating that the + client will not be sending any more messages +1. Server recv\_trailing\_metadata: The server sees this from the client and + knows that it will not get any more messages. This won't complete yet though, + as described above. +1. Server send\_initial\_metadata, send\_message, send\_trailing\_metadata: A + batch can contain multiple ops, and this batch provides the RPC response + headers, response content, and status. Note that sending the trailing + metadata will also complete the server's receive of trailing metadata. +1. Client recv\_initial\_metadata: The number of ops in one side of the batch + has no relation with the number of ops on the other side of the batch. In + this case, the client is just collecting the response headers. +1. Client recv\_message, recv\_trailing\_metadata: Get the data response and + status + + +There are other possible sample timelines. For example, for client-side streaming, a "typical" sequence would be: + +1. Server: recv\_initial\_metadata + - At API-level, that would be the server requesting an RPC +1. Server: recv\_trailing\_metadata + - This is for when the server wants to know the final completion of the RPC + through an `AsyncNotifyWhenDone` API in C++ +1. Client: send\_initial\_metadata, recv\_message, recv\_trailing\_metadata + - At API-level, that's a client invoking a client-side streaming call. The + send\_initial\_metadata is the call invocation, the recv\_message colects + the final response from the server, and the recv\_trailing\_metadata gets + the `grpc::Status` value that will be returned from the call +1. Client: send\_message / Server: recv\_message + - Repeat the above step numerous times; these correspond to a client issuing + `Write` in a loop and a server doing `Read` in a loop until `Read` fails +1. Client: send\_trailing\_metadata / Server: recv\_message that indicates doneness (NULL) + - These correspond to a client issuing `WritesDone` which causes the server's + `Read` to fail +1. Server: send\_message, send\_trailing\_metadata + - These correpond to the server doing `Finish` + +The sends on one side will call their own callbacks when complete, and they will +in turn trigger actions that cause the other side's recv operations to +complete. In some transports, a send can sometimes complete before the recv on +the other side (e.g., in HTTP/2 if there is sufficient flow-control buffer space +available) + +## Other transport duties + +In addition to these basic stream ops, the transport must handle cancellations +of a stream at any time and pass their effects to the other side. For example, +in HTTP/2, this triggers a `RST_STREAM` being sent on the wire. The transport +must perform operations like pings and statistics that are used to shape +transport-level characteristics like flow control (see, for example, their use +in the HTTP/2 transport). + +## Putting things together with detail: Sending Metadata + +* API layer: `map<string, string>` that is specific to this RPC +* Core surface layer: array of `{slice, slice}` pairs where each slice + references an underlying string +* [Core transport + layer](https://github.com/grpc/grpc/tree/master/src/core/lib/transport): list + of `{slice, slice}` pairs that includes the above plus possibly some general + metadata (e.g., Method and Authority for initial metadata) +* [Specific transport + layer](https://github.com/grpc/grpc/tree/master/src/core/ext/transport): + - Either send it to the other side using transport-specific API (e.g., Cronet) + - Or have it sent through the [iomgr/endpoint + layer](https://github.com/grpc/grpc/tree/master/src/core/lib/iomgr) (e.g., + HTTP/2) + - Or just manipulate pointers to get it from one side to the other (e.g., + In-process) + +## Requirements for any transport + +Each transport implements several operations in a vtbl (may change to actual +virtual functions as transport moves to idiomatic C++). + +The most important and common one is `perform_stream_op`. This function +processes a single stream op batch on a specific stream that is associated with +a specific transport: + +* Gets the 6 ops/cancel passed down from the surface +* Pass metadata from one side to the other as described above +* Transform messages between slice buffer structure and stream of bytes to pass + to other side + - May require insertion of extra bytes (e.g., per-message headers in HTTP/2) +* React to metadata to preserve expected orderings (*) +* Schedule invocation of completion callbacks + +There are other functions in the vtbl as well. + +* `perform_transport_op` + - Configure the transport instance for the connectivity state change notifier + or the server-side accept callback + - Disconnect transport or set up a goaway for later streams +* `init_stream` + - Starts a stream from the client-side + - (*) Server-side of the transport must call `accept_stream_cb` when a new + stream is available + * Triggers request-matcher +* `destroy_stream`, `destroy_transport` + - Free up data related to a stream or transport +* `set_pollset`, `set_pollset_set`, `get_endpoint` + - Map each specific instance of the transport to FDs being used by iomgr (for + HTTP/2) + - Get a pointer to the endpoint structure that actually moves the data + (wrapper around a socket for HTTP/2) + +## Book-keeping responsibilities of the transport layer + +A given transport must keep all of its transport and streams ref-counted. This +is essential to make sure that no struct disappears before it is done being +used. + +A transport must also preserve relevant orders for the different categories of +ops on a stream, as described above. A transport must also make sure that all +relevant batch operations have completed before scheduling the `on_complete` +closure for a batch. Further examples include the idea that the server logic +expects to not complete recv\_trailing\_metadata until after it actually sends +trailing metadata since it would have already found this out by seeing a NULL’ed +recv\_message. This is considered part of the transport's duties in preserving +orders. diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index c8fd2ee48b2..ef5fb90a934 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -774,6 +774,7 @@ doc/connectivity-semantics-and-api.md \ doc/core/grpc-error.md \ doc/core/moving-to-c++.md \ doc/core/pending_api_cleanups.md \ +doc/core/transport_explainer.md \ doc/cpp-style-guide.md \ doc/environment_variables.md \ doc/epoll-polling-engine.md \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index b9844f8b89a..f8835e1047e 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -774,6 +774,7 @@ doc/connectivity-semantics-and-api.md \ doc/core/grpc-error.md \ doc/core/moving-to-c++.md \ doc/core/pending_api_cleanups.md \ +doc/core/transport_explainer.md \ doc/cpp-style-guide.md \ doc/environment_variables.md \ doc/epoll-polling-engine.md \ From 1d5737feb3d1b1fa3f1bbc1d166a0ff04fa7ef3f Mon Sep 17 00:00:00 2001 From: Alex Polcyn <apolcyn@google.com> Date: Fri, 17 Nov 2017 17:03:06 -0800 Subject: [PATCH 04/10] Fix error when a language skips a certain version --- tools/interop_matrix/run_interop_matrix_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py index dce1033add8..4265bc5355a 100755 --- a/tools/interop_matrix/run_interop_matrix_tests.py +++ b/tools/interop_matrix/run_interop_matrix_tests.py @@ -100,7 +100,7 @@ def find_all_images_for_lang(lang): jobset.message('SKIPPED', '%s for %s is not defined' % (args.release, lang), do_newline=True) - return [] + return {} releases = [args.release] # Images tuples keyed by runtime. From 9f4a8eeced218423db60f90a9a307061943e9fb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Bogdanovi=C4=87?= <mamaveb@gmail.com> Date: Thu, 26 Oct 2017 14:34:45 +0200 Subject: [PATCH 05/10] Add HealthChecker helpers for setting statuses --- src/ruby/pb/grpc/health/checker.rb | 14 ++++++++++++ src/ruby/spec/pb/health/checker_spec.rb | 29 +++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/ruby/pb/grpc/health/checker.rb b/src/ruby/pb/grpc/health/checker.rb index f23db39da56..c492455d8ff 100644 --- a/src/ruby/pb/grpc/health/checker.rb +++ b/src/ruby/pb/grpc/health/checker.rb @@ -48,6 +48,20 @@ module Grpc @status_mutex.synchronize { @statuses["#{service}"] = status } end + # Adds given health status for all given services + def set_status_for_services(status, *services) + @status_mutex.synchronize do + services.each { |service| @statuses["#{service}"] = status } + end + end + + # Adds health status for each service given within hash + def add_statuses(service_statuses = {}) + @status_mutex.synchronize do + service_statuses.each_pair { |service, status| @statuses["#{service}"] = status } + end + end + # Clears the status for the given service. def clear_status(service) @status_mutex.synchronize { @statuses.delete("#{service}") } diff --git a/src/ruby/spec/pb/health/checker_spec.rb b/src/ruby/spec/pb/health/checker_spec.rb index 6c9e206c3f1..c79ccfd2e02 100644 --- a/src/ruby/spec/pb/health/checker_spec.rb +++ b/src/ruby/spec/pb/health/checker_spec.rb @@ -99,6 +99,35 @@ describe Grpc::Health::Checker do end end + context 'method `add_statuses`' do + it 'should add status to each service' do + checker = Grpc::Health::Checker.new + checker.add_statuses( + 'service1' => ServingStatus::SERVING, + 'service2' => ServingStatus::NOT_SERVING + ) + service1_health = checker.check(HCReq.new(service: 'service1'), nil) + service2_health = checker.check(HCReq.new(service: 'service2'), nil) + expect(service1_health).to eq(HCResp.new(status: ServingStatus::SERVING)) + expect(service2_health).to eq(HCResp.new(status: ServingStatus::NOT_SERVING)) + end + end + + context 'method `set_status_for_services`' do + it 'should add given status to all given services' do + checker = Grpc::Health::Checker.new + checker.set_status_for_services( + ServingStatus::SERVING, + 'service1', + 'service2' + ) + service1_health = checker.check(HCReq.new(service: 'service1'), nil) + service2_health = checker.check(HCReq.new(service: 'service2'), nil) + expect(service1_health).to eq(HCResp.new(status: ServingStatus::SERVING)) + expect(service2_health).to eq(HCResp.new(status: ServingStatus::SERVING)) + end + end + context 'method `check`' do success_tests.each do |t| it "should fail with NOT_FOUND when #{t[:desc]}" do From 891254292e4a68dd9a3b31f8faf729aaeca8ccc9 Mon Sep 17 00:00:00 2001 From: Vijay Pai <vpai@google.com> Date: Wed, 22 Nov 2017 10:22:28 -0800 Subject: [PATCH 06/10] Remove lockfree stack, again --- BUILD | 14 +- CMakeLists.txt | 30 ---- Makefile | 37 ----- build.yaml | 12 -- config.m4 | 1 - config.w32 | 1 - gRPC-Core.podspec | 3 - grpc.gemspec | 2 - grpc.gyp | 1 - package.xml | 2 - src/core/lib/support/stack_lockfree.cc | 137 ----------------- src/core/lib/support/stack_lockfree.h | 46 ------ src/python/grpcio/grpc_core_dependencies.py | 1 - test/core/support/BUILD | 22 +-- test/core/support/stack_lockfree_test.cc | 140 ------------------ tools/doxygen/Doxyfile.c++.internal | 1 - tools/doxygen/Doxyfile.core.internal | 2 - .../generated/sources_and_headers.json | 18 --- tools/run_tests/generated/tests.json | 24 --- 19 files changed, 12 insertions(+), 482 deletions(-) delete mode 100644 src/core/lib/support/stack_lockfree.cc delete mode 100644 src/core/lib/support/stack_lockfree.h delete mode 100644 test/core/support/stack_lockfree_test.cc diff --git a/BUILD b/BUILD index 25daba8e1e9..efb72d45b93 100644 --- a/BUILD +++ b/BUILD @@ -455,7 +455,6 @@ grpc_cc_library( "src/core/lib/support/log_windows.cc", "src/core/lib/support/mpscq.cc", "src/core/lib/support/murmur_hash.cc", - "src/core/lib/support/stack_lockfree.cc", "src/core/lib/support/string.cc", "src/core/lib/support/string_posix.cc", "src/core/lib/support/string_util_windows.cc", @@ -486,23 +485,22 @@ grpc_cc_library( "src/core/lib/support/atomic_with_atm.h", "src/core/lib/support/atomic_with_std.h", "src/core/lib/support/env.h", - "src/core/lib/support/memory.h", - "src/core/lib/support/vector.h", "src/core/lib/support/manual_constructor.h", + "src/core/lib/support/memory.h", "src/core/lib/support/mpscq.h", "src/core/lib/support/murmur_hash.h", "src/core/lib/support/spinlock.h", - "src/core/lib/support/stack_lockfree.h", "src/core/lib/support/string.h", "src/core/lib/support/string_windows.h", "src/core/lib/support/time_precise.h", "src/core/lib/support/tmpfile.h", + "src/core/lib/support/vector.h", ], language = "c++", public_hdrs = GPR_PUBLIC_HDRS, deps = [ "gpr_codegen", - "@com_google_absl//absl/container:inlined_vector" + "@com_google_absl//absl/container:inlined_vector", ], ) @@ -672,6 +670,7 @@ grpc_cc_library( "src/core/lib/transport/transport_op_string.cc", ], hdrs = [ + "src/core/lib/backoff/backoff.h", "src/core/lib/channel/channel_args.h", "src/core/lib/channel/channel_stack.h", "src/core/lib/channel/channel_stack_builder.h", @@ -690,6 +689,7 @@ grpc_cc_library( "src/core/lib/http/format_request.h", "src/core/lib/http/httpcli.h", "src/core/lib/http/parser.h", + "src/core/lib/iomgr/block_annotate.h", "src/core/lib/iomgr/call_combiner.h", "src/core/lib/iomgr/closure.h", "src/core/lib/iomgr/combiner.h", @@ -734,7 +734,6 @@ grpc_cc_library( "src/core/lib/iomgr/socket_utils_posix.h", "src/core/lib/iomgr/socket_windows.h", "src/core/lib/iomgr/sys_epoll_wrapper.h", - "src/core/lib/iomgr/block_annotate.h", "src/core/lib/iomgr/tcp_client.h", "src/core/lib/iomgr/tcp_client_posix.h", "src/core/lib/iomgr/tcp_posix.h", @@ -790,7 +789,6 @@ grpc_cc_library( "src/core/lib/transport/timeout_encoding.h", "src/core/lib/transport/transport.h", "src/core/lib/transport/transport_impl.h", - "src/core/lib/backoff/backoff.h", ], external_deps = [ "zlib", @@ -1250,8 +1248,8 @@ grpc_cc_library( "src/core/ext/transport/chttp2/transport/bin_decoder.h", "src/core/ext/transport/chttp2/transport/bin_encoder.h", "src/core/ext/transport/chttp2/transport/chttp2_transport.h", - "src/core/ext/transport/chttp2/transport/frame.h", "src/core/ext/transport/chttp2/transport/flow_control.h", + "src/core/ext/transport/chttp2/transport/frame.h", "src/core/ext/transport/chttp2/transport/frame_data.h", "src/core/ext/transport/chttp2/transport/frame_goaway.h", "src/core/ext/transport/chttp2/transport/frame_ping.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 77b60e898ab..81248381e37 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -433,7 +433,6 @@ add_dependencies(buildtests_c gpr_log_test) add_dependencies(buildtests_c gpr_manual_constructor_test) add_dependencies(buildtests_c gpr_mpscq_test) add_dependencies(buildtests_c gpr_spinlock_test) -add_dependencies(buildtests_c gpr_stack_lockfree_test) add_dependencies(buildtests_c gpr_string_test) add_dependencies(buildtests_c gpr_sync_test) add_dependencies(buildtests_c gpr_thd_test) @@ -807,7 +806,6 @@ add_library(gpr src/core/lib/support/log_windows.cc src/core/lib/support/mpscq.cc src/core/lib/support/murmur_hash.cc - src/core/lib/support/stack_lockfree.cc src/core/lib/support/string.cc src/core/lib/support/string_posix.cc src/core/lib/support/string_util_windows.cc @@ -6475,34 +6473,6 @@ target_link_libraries(gpr_spinlock_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) -add_executable(gpr_stack_lockfree_test - test/core/support/stack_lockfree_test.cc -) - - -target_include_directories(gpr_stack_lockfree_test - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include - PRIVATE ${BORINGSSL_ROOT_DIR}/include - PRIVATE ${PROTOBUF_ROOT_DIR}/src - PRIVATE ${BENCHMARK_ROOT_DIR}/include - PRIVATE ${ZLIB_ROOT_DIR} - PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib - PRIVATE ${CARES_INCLUDE_DIR} - PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares - PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/abseil-cpp -) - -target_link_libraries(gpr_stack_lockfree_test - ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util - gpr -) - -endif (gRPC_BUILD_TESTS) -if (gRPC_BUILD_TESTS) - add_executable(gpr_string_test test/core/support/string_test.cc ) diff --git a/Makefile b/Makefile index 25a7933b2fc..36c42523949 100644 --- a/Makefile +++ b/Makefile @@ -994,7 +994,6 @@ gpr_log_test: $(BINDIR)/$(CONFIG)/gpr_log_test gpr_manual_constructor_test: $(BINDIR)/$(CONFIG)/gpr_manual_constructor_test gpr_mpscq_test: $(BINDIR)/$(CONFIG)/gpr_mpscq_test gpr_spinlock_test: $(BINDIR)/$(CONFIG)/gpr_spinlock_test -gpr_stack_lockfree_test: $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test gpr_string_test: $(BINDIR)/$(CONFIG)/gpr_string_test gpr_sync_test: $(BINDIR)/$(CONFIG)/gpr_sync_test gpr_thd_test: $(BINDIR)/$(CONFIG)/gpr_thd_test @@ -1389,7 +1388,6 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/gpr_manual_constructor_test \ $(BINDIR)/$(CONFIG)/gpr_mpscq_test \ $(BINDIR)/$(CONFIG)/gpr_spinlock_test \ - $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test \ $(BINDIR)/$(CONFIG)/gpr_string_test \ $(BINDIR)/$(CONFIG)/gpr_sync_test \ $(BINDIR)/$(CONFIG)/gpr_thd_test \ @@ -1840,8 +1838,6 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/gpr_mpscq_test || ( echo test gpr_mpscq_test failed ; exit 1 ) $(E) "[RUN] Testing gpr_spinlock_test" $(Q) $(BINDIR)/$(CONFIG)/gpr_spinlock_test || ( echo test gpr_spinlock_test failed ; exit 1 ) - $(E) "[RUN] Testing gpr_stack_lockfree_test" - $(Q) $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test || ( echo test gpr_stack_lockfree_test failed ; exit 1 ) $(E) "[RUN] Testing gpr_string_test" $(Q) $(BINDIR)/$(CONFIG)/gpr_string_test || ( echo test gpr_string_test failed ; exit 1 ) $(E) "[RUN] Testing gpr_sync_test" @@ -2836,7 +2832,6 @@ LIBGPR_SRC = \ src/core/lib/support/log_windows.cc \ src/core/lib/support/mpscq.cc \ src/core/lib/support/murmur_hash.cc \ - src/core/lib/support/stack_lockfree.cc \ src/core/lib/support/string.cc \ src/core/lib/support/string_posix.cc \ src/core/lib/support/string_util_windows.cc \ @@ -10258,38 +10253,6 @@ endif endif -GPR_STACK_LOCKFREE_TEST_SRC = \ - test/core/support/stack_lockfree_test.cc \ - -GPR_STACK_LOCKFREE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_STACK_LOCKFREE_TEST_SRC)))) -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL. - -$(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test: openssl_dep_error - -else - - - -$(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test: $(GPR_STACK_LOCKFREE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_STACK_LOCKFREE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test - -endif - -$(OBJDIR)/$(CONFIG)/test/core/support/stack_lockfree_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a - -deps_gpr_stack_lockfree_test: $(GPR_STACK_LOCKFREE_TEST_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(GPR_STACK_LOCKFREE_TEST_OBJS:.o=.dep) -endif -endif - - GPR_STRING_TEST_SRC = \ test/core/support/string_test.cc \ diff --git a/build.yaml b/build.yaml index 16e31eb588f..762b9a27176 100644 --- a/build.yaml +++ b/build.yaml @@ -49,7 +49,6 @@ filegroups: - src/core/lib/support/log_windows.cc - src/core/lib/support/mpscq.cc - src/core/lib/support/murmur_hash.cc - - src/core/lib/support/stack_lockfree.cc - src/core/lib/support/string.cc - src/core/lib/support/string_posix.cc - src/core/lib/support/string_util_windows.cc @@ -115,7 +114,6 @@ filegroups: - src/core/lib/support/mpscq.h - src/core/lib/support/murmur_hash.h - src/core/lib/support/spinlock.h - - src/core/lib/support/stack_lockfree.h - src/core/lib/support/string.h - src/core/lib/support/string_windows.h - src/core/lib/support/time_precise.h @@ -2246,16 +2244,6 @@ targets: - gpr_test_util - gpr uses_polling: false -- name: gpr_stack_lockfree_test - cpu_cost: 7 - build: test - language: c - src: - - test/core/support/stack_lockfree_test.cc - deps: - - gpr_test_util - - gpr - uses_polling: false - name: gpr_string_test build: test language: c diff --git a/config.m4 b/config.m4 index d2f2520feac..520d296d088 100644 --- a/config.m4 +++ b/config.m4 @@ -62,7 +62,6 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/support/log_windows.cc \ src/core/lib/support/mpscq.cc \ src/core/lib/support/murmur_hash.cc \ - src/core/lib/support/stack_lockfree.cc \ src/core/lib/support/string.cc \ src/core/lib/support/string_posix.cc \ src/core/lib/support/string_util_windows.cc \ diff --git a/config.w32 b/config.w32 index 8a713751dcd..5e0b1266fbc 100644 --- a/config.w32 +++ b/config.w32 @@ -39,7 +39,6 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\support\\log_windows.cc " + "src\\core\\lib\\support\\mpscq.cc " + "src\\core\\lib\\support\\murmur_hash.cc " + - "src\\core\\lib\\support\\stack_lockfree.cc " + "src\\core\\lib\\support\\string.cc " + "src\\core\\lib\\support\\string_posix.cc " + "src\\core\\lib\\support\\string_util_windows.cc " + diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 2f97565f1b4..566ba38b0f7 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -198,7 +198,6 @@ Pod::Spec.new do |s| 'src/core/lib/support/mpscq.h', 'src/core/lib/support/murmur_hash.h', 'src/core/lib/support/spinlock.h', - 'src/core/lib/support/stack_lockfree.h', 'src/core/lib/support/string.h', 'src/core/lib/support/string_windows.h', 'src/core/lib/support/time_precise.h', @@ -226,7 +225,6 @@ Pod::Spec.new do |s| 'src/core/lib/support/log_windows.cc', 'src/core/lib/support/mpscq.cc', 'src/core/lib/support/murmur_hash.cc', - 'src/core/lib/support/stack_lockfree.cc', 'src/core/lib/support/string.cc', 'src/core/lib/support/string_posix.cc', 'src/core/lib/support/string_util_windows.cc', @@ -718,7 +716,6 @@ Pod::Spec.new do |s| 'src/core/lib/support/mpscq.h', 'src/core/lib/support/murmur_hash.h', 'src/core/lib/support/spinlock.h', - 'src/core/lib/support/stack_lockfree.h', 'src/core/lib/support/string.h', 'src/core/lib/support/string_windows.h', 'src/core/lib/support/time_precise.h', diff --git a/grpc.gemspec b/grpc.gemspec index 0dd7ceb3506..64bea9238ba 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -95,7 +95,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/support/mpscq.h ) s.files += %w( src/core/lib/support/murmur_hash.h ) s.files += %w( src/core/lib/support/spinlock.h ) - s.files += %w( src/core/lib/support/stack_lockfree.h ) s.files += %w( src/core/lib/support/string.h ) s.files += %w( src/core/lib/support/string_windows.h ) s.files += %w( src/core/lib/support/time_precise.h ) @@ -123,7 +122,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/support/log_windows.cc ) s.files += %w( src/core/lib/support/mpscq.cc ) s.files += %w( src/core/lib/support/murmur_hash.cc ) - s.files += %w( src/core/lib/support/stack_lockfree.cc ) s.files += %w( src/core/lib/support/string.cc ) s.files += %w( src/core/lib/support/string_posix.cc ) s.files += %w( src/core/lib/support/string_util_windows.cc ) diff --git a/grpc.gyp b/grpc.gyp index fb153915ff0..a23d862e20d 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -184,7 +184,6 @@ 'src/core/lib/support/log_windows.cc', 'src/core/lib/support/mpscq.cc', 'src/core/lib/support/murmur_hash.cc', - 'src/core/lib/support/stack_lockfree.cc', 'src/core/lib/support/string.cc', 'src/core/lib/support/string_posix.cc', 'src/core/lib/support/string_util_windows.cc', diff --git a/package.xml b/package.xml index 59d49dd1657..5b4c06647ef 100644 --- a/package.xml +++ b/package.xml @@ -107,7 +107,6 @@ <file baseinstalldir="/" name="src/core/lib/support/mpscq.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/murmur_hash.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/spinlock.h" role="src" /> - <file baseinstalldir="/" name="src/core/lib/support/stack_lockfree.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/string.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/string_windows.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/time_precise.h" role="src" /> @@ -135,7 +134,6 @@ <file baseinstalldir="/" name="src/core/lib/support/log_windows.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/mpscq.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/murmur_hash.cc" role="src" /> - <file baseinstalldir="/" name="src/core/lib/support/stack_lockfree.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/string.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/string_posix.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/string_util_windows.cc" role="src" /> diff --git a/src/core/lib/support/stack_lockfree.cc b/src/core/lib/support/stack_lockfree.cc deleted file mode 100644 index 7a4ede3b92d..00000000000 --- a/src/core/lib/support/stack_lockfree.cc +++ /dev/null @@ -1,137 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "src/core/lib/support/stack_lockfree.h" - -#include <stdlib.h> -#include <string.h> - -#include <grpc/support/alloc.h> -#include <grpc/support/atm.h> -#include <grpc/support/log.h> -#include <grpc/support/port_platform.h> - -/* The lockfree node structure is a single architecture-level - word that allows for an atomic CAS to set it up. */ -struct lockfree_node_contents { - /* next thing to look at. Actual index for head, next index otherwise */ - uint16_t index; -#ifdef GPR_ARCH_64 - uint16_t pad; - uint32_t aba_ctr; -#else -#ifdef GPR_ARCH_32 - uint16_t aba_ctr; -#else -#error Unsupported bit width architecture -#endif -#endif -}; - -/* Use a union to make sure that these are in the same bits as an atm word */ -typedef union lockfree_node { - gpr_atm atm; - struct lockfree_node_contents contents; -} lockfree_node; - -/* make sure that entries aligned to 8-bytes */ -#define ENTRY_ALIGNMENT_BITS 3 -/* reserve this entry as invalid */ -#define INVALID_ENTRY_INDEX ((1 << 16) - 1) - -struct gpr_stack_lockfree { - lockfree_node* entries; - lockfree_node head; /* An atomic entry describing curr head */ -}; - -gpr_stack_lockfree* gpr_stack_lockfree_create(size_t entries) { - gpr_stack_lockfree* stack; - stack = (gpr_stack_lockfree*)gpr_malloc(sizeof(*stack)); - /* Since we only allocate 16 bits to represent an entry number, - * make sure that we are within the desired range */ - /* Reserve the highest entry number as a dummy */ - GPR_ASSERT(entries < INVALID_ENTRY_INDEX); - stack->entries = (lockfree_node*)gpr_malloc_aligned( - entries * sizeof(stack->entries[0]), ENTRY_ALIGNMENT_BITS); - /* Clear out all entries */ - memset(stack->entries, 0, entries * sizeof(stack->entries[0])); - memset(&stack->head, 0, sizeof(stack->head)); - - GPR_ASSERT(sizeof(stack->entries->atm) == sizeof(stack->entries->contents)); - - /* Point the head at reserved dummy entry */ - stack->head.contents.index = INVALID_ENTRY_INDEX; -/* Fill in the pad and aba_ctr to avoid confusing memcheck tools */ -#ifdef GPR_ARCH_64 - stack->head.contents.pad = 0; -#endif - stack->head.contents.aba_ctr = 0; - return stack; -} - -void gpr_stack_lockfree_destroy(gpr_stack_lockfree* stack) { - gpr_free_aligned(stack->entries); - gpr_free(stack); -} - -int gpr_stack_lockfree_push(gpr_stack_lockfree* stack, int entry) { - lockfree_node head; - lockfree_node newhead; - lockfree_node curent; - lockfree_node newent; - - /* First fill in the entry's index and aba ctr for new head */ - newhead.contents.index = (uint16_t)entry; -#ifdef GPR_ARCH_64 - /* Fill in the pad to avoid confusing memcheck tools */ - newhead.contents.pad = 0; -#endif - - /* Also post-increment the aba_ctr */ - curent.atm = gpr_atm_no_barrier_load(&stack->entries[entry].atm); - newhead.contents.aba_ctr = ++curent.contents.aba_ctr; - gpr_atm_no_barrier_store(&stack->entries[entry].atm, curent.atm); - - do { - /* Atomically get the existing head value for use */ - head.atm = gpr_atm_no_barrier_load(&(stack->head.atm)); - /* Point to it */ - newent.atm = gpr_atm_no_barrier_load(&stack->entries[entry].atm); - newent.contents.index = head.contents.index; - gpr_atm_no_barrier_store(&stack->entries[entry].atm, newent.atm); - } while (!gpr_atm_rel_cas(&(stack->head.atm), head.atm, newhead.atm)); - /* Use rel_cas above to make sure that entry index is set properly */ - return head.contents.index == INVALID_ENTRY_INDEX; -} - -int gpr_stack_lockfree_pop(gpr_stack_lockfree* stack) { - lockfree_node head; - lockfree_node newhead; - - do { - head.atm = gpr_atm_acq_load(&(stack->head.atm)); - if (head.contents.index == INVALID_ENTRY_INDEX) { - return -1; - } - newhead.atm = - gpr_atm_no_barrier_load(&(stack->entries[head.contents.index].atm)); - - } while (!gpr_atm_no_barrier_cas(&(stack->head.atm), head.atm, newhead.atm)); - - return head.contents.index; -} diff --git a/src/core/lib/support/stack_lockfree.h b/src/core/lib/support/stack_lockfree.h deleted file mode 100644 index 337ecc2b17a..00000000000 --- a/src/core/lib/support/stack_lockfree.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPC_CORE_LIB_SUPPORT_STACK_LOCKFREE_H -#define GRPC_CORE_LIB_SUPPORT_STACK_LOCKFREE_H - -#include <stddef.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct gpr_stack_lockfree gpr_stack_lockfree; - -/* This stack must specify the maximum number of entries to track. - The current implementation only allows up to 65534 entries */ -gpr_stack_lockfree* gpr_stack_lockfree_create(size_t entries); -void gpr_stack_lockfree_destroy(gpr_stack_lockfree* stack); - -/* Pass in a valid entry number for the next stack entry */ -/* Returns 1 if this is the first element on the stack, 0 otherwise */ -int gpr_stack_lockfree_push(gpr_stack_lockfree*, int entry); - -/* Returns -1 on empty or the actual entry number */ -int gpr_stack_lockfree_pop(gpr_stack_lockfree* stack); - -#ifdef __cplusplus -} -#endif - -#endif /* GRPC_CORE_LIB_SUPPORT_STACK_LOCKFREE_H */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 330c4185c61..efb4d8617dc 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -38,7 +38,6 @@ CORE_SOURCE_FILES = [ 'src/core/lib/support/log_windows.cc', 'src/core/lib/support/mpscq.cc', 'src/core/lib/support/murmur_hash.cc', - 'src/core/lib/support/stack_lockfree.cc', 'src/core/lib/support/string.cc', 'src/core/lib/support/string_posix.cc', 'src/core/lib/support/string_util_windows.cc', diff --git a/test/core/support/BUILD b/test/core/support/BUILD index 69512cd9a92..996166a371f 100644 --- a/test/core/support/BUILD +++ b/test/core/support/BUILD @@ -118,16 +118,6 @@ grpc_cc_test( ], ) -grpc_cc_test( - name = "stack_lockfree_test", - srcs = ["stack_lockfree_test.cc"], - language = "C++", - deps = [ - "//:gpr", - "//test/core/util:gpr_test_util", - ], -) - grpc_cc_test( name = "string_test", srcs = ["string_test.cc"], @@ -211,25 +201,25 @@ grpc_cc_test( grpc_cc_test( name = "memory_test", srcs = ["memory_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:grpc", "//test/core/util:gpr_test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "vector_test", srcs = ["vector_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:grpc", "//test/core/util:gpr_test_util", ], - external_deps = [ - "gtest", - ], ) diff --git a/test/core/support/stack_lockfree_test.cc b/test/core/support/stack_lockfree_test.cc deleted file mode 100644 index e6d0c9b795c..00000000000 --- a/test/core/support/stack_lockfree_test.cc +++ /dev/null @@ -1,140 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "src/core/lib/support/stack_lockfree.h" - -#include <stdlib.h> - -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include "test/core/util/test_config.h" - -/* max stack size supported */ -#define MAX_STACK_SIZE 65534 - -#define MAX_THREADS 32 - -static void test_serial_sized(size_t size) { - gpr_stack_lockfree* stack = gpr_stack_lockfree_create(size); - size_t i; - size_t j; - - /* First try popping empty */ - GPR_ASSERT(gpr_stack_lockfree_pop(stack) == -1); - - /* Now add one item and check it */ - gpr_stack_lockfree_push(stack, 3); - GPR_ASSERT(gpr_stack_lockfree_pop(stack) == 3); - GPR_ASSERT(gpr_stack_lockfree_pop(stack) == -1); - - /* Now add repeatedly more items and check them */ - for (i = 1; i < size; i *= 2) { - for (j = 0; j <= i; j++) { - GPR_ASSERT(gpr_stack_lockfree_push(stack, (int)j) == (j == 0)); - } - for (j = 0; j <= i; j++) { - GPR_ASSERT(gpr_stack_lockfree_pop(stack) == (int)(i - j)); - } - GPR_ASSERT(gpr_stack_lockfree_pop(stack) == -1); - } - - gpr_stack_lockfree_destroy(stack); -} - -static void test_serial() { - size_t i; - for (i = 128; i < MAX_STACK_SIZE; i *= 2) { - test_serial_sized(i); - } - test_serial_sized(MAX_STACK_SIZE); -} - -struct test_arg { - gpr_stack_lockfree* stack; - int stack_size; - int nthreads; - int rank; - int sum; -}; - -static void test_mt_body(void* v) { - struct test_arg* arg = (struct test_arg*)v; - int lo, hi; - int i; - int res; - lo = arg->rank * arg->stack_size / arg->nthreads; - hi = (arg->rank + 1) * arg->stack_size / arg->nthreads; - for (i = lo; i < hi; i++) { - gpr_stack_lockfree_push(arg->stack, i); - if ((res = gpr_stack_lockfree_pop(arg->stack)) != -1) { - arg->sum += res; - } - } - while ((res = gpr_stack_lockfree_pop(arg->stack)) != -1) { - arg->sum += res; - } -} - -static void test_mt_sized(size_t size, int nth) { - gpr_stack_lockfree* stack; - struct test_arg args[MAX_THREADS]; - gpr_thd_id thds[MAX_THREADS]; - int sum; - int i; - gpr_thd_options options = gpr_thd_options_default(); - - stack = gpr_stack_lockfree_create(size); - for (i = 0; i < nth; i++) { - args[i].stack = stack; - args[i].stack_size = (int)size; - args[i].nthreads = nth; - args[i].rank = i; - args[i].sum = 0; - } - gpr_thd_options_set_joinable(&options); - for (i = 0; i < nth; i++) { - GPR_ASSERT(gpr_thd_new(&thds[i], test_mt_body, &args[i], &options)); - } - sum = 0; - for (i = 0; i < nth; i++) { - gpr_thd_join(thds[i]); - sum = sum + args[i].sum; - } - GPR_ASSERT((unsigned)sum == ((unsigned)size * (size - 1)) / 2); - gpr_stack_lockfree_destroy(stack); -} - -static void test_mt() { - size_t size; - int nth; - for (nth = 1; nth < MAX_THREADS; nth++) { - for (size = 128; size < MAX_STACK_SIZE; size *= 2) { - test_mt_sized(size, nth); - } - test_mt_sized(MAX_STACK_SIZE, nth); - } -} - -int main(int argc, char** argv) { - grpc_test_init(argc, argv); - test_serial(); - test_mt(); - return 0; -} diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 3c564e203af..5d1bfb27359 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1037,7 +1037,6 @@ src/core/lib/support/memory.h \ src/core/lib/support/mpscq.h \ src/core/lib/support/murmur_hash.h \ src/core/lib/support/spinlock.h \ -src/core/lib/support/stack_lockfree.h \ src/core/lib/support/string.h \ src/core/lib/support/string_windows.h \ src/core/lib/support/time_precise.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 5674124f446..e8ae75eae93 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1299,8 +1299,6 @@ src/core/lib/support/mpscq.h \ src/core/lib/support/murmur_hash.cc \ src/core/lib/support/murmur_hash.h \ src/core/lib/support/spinlock.h \ -src/core/lib/support/stack_lockfree.cc \ -src/core/lib/support/stack_lockfree.h \ src/core/lib/support/string.cc \ src/core/lib/support/string.h \ src/core/lib/support/string_posix.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 5a3429c81f5..24d865932cc 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -793,21 +793,6 @@ "third_party": false, "type": "target" }, - { - "deps": [ - "gpr", - "gpr_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c", - "name": "gpr_stack_lockfree_test", - "src": [ - "test/core/support/stack_lockfree_test.cc" - ], - "third_party": false, - "type": "target" - }, { "deps": [ "gpr", @@ -7770,7 +7755,6 @@ "src/core/lib/support/log_windows.cc", "src/core/lib/support/mpscq.cc", "src/core/lib/support/murmur_hash.cc", - "src/core/lib/support/stack_lockfree.cc", "src/core/lib/support/string.cc", "src/core/lib/support/string_posix.cc", "src/core/lib/support/string_util_windows.cc", @@ -7840,7 +7824,6 @@ "src/core/lib/support/mpscq.h", "src/core/lib/support/murmur_hash.h", "src/core/lib/support/spinlock.h", - "src/core/lib/support/stack_lockfree.h", "src/core/lib/support/string.h", "src/core/lib/support/string_windows.h", "src/core/lib/support/time_precise.h", @@ -7889,7 +7872,6 @@ "src/core/lib/support/mpscq.h", "src/core/lib/support/murmur_hash.h", "src/core/lib/support/spinlock.h", - "src/core/lib/support/stack_lockfree.h", "src/core/lib/support/string.h", "src/core/lib/support/string_windows.h", "src/core/lib/support/time_precise.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index dfd7bfafe6a..58db35ccf9a 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -983,30 +983,6 @@ ], "uses_polling": false }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 7, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "gtest": false, - "language": "c", - "name": "gpr_stack_lockfree_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "uses_polling": false - }, { "args": [], "benchmark": false, From fba967747c279f676d9571cbec6478a884a9cbbe Mon Sep 17 00:00:00 2001 From: Muxi Yan <mxyan@google.com> Date: Mon, 27 Nov 2017 14:39:28 -0800 Subject: [PATCH 07/10] generate_projects --- src/ruby/ext/grpc/rb_grpc_imports.generated.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index ae1e1a0b30d..c2698d16ea4 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -337,7 +337,7 @@ extern grpc_composite_call_credentials_create_type grpc_composite_call_credentia typedef grpc_call_credentials*(*grpc_google_compute_engine_credentials_create_type)(void* reserved); extern grpc_google_compute_engine_credentials_create_type grpc_google_compute_engine_credentials_create_import; #define grpc_google_compute_engine_credentials_create grpc_google_compute_engine_credentials_create_import -typedef gpr_timespec(*grpc_max_auth_token_lifetime_type)(); +typedef gpr_timespec(*grpc_max_auth_token_lifetime_type)(void); extern grpc_max_auth_token_lifetime_type grpc_max_auth_token_lifetime_import; #define grpc_max_auth_token_lifetime grpc_max_auth_token_lifetime_import typedef grpc_call_credentials*(*grpc_service_account_jwt_access_credentials_create_type)(const char* json_key, gpr_timespec token_lifetime, void* reserved); @@ -589,7 +589,7 @@ extern gpr_free_aligned_type gpr_free_aligned_import; typedef void(*gpr_set_allocation_functions_type)(gpr_allocation_functions functions); extern gpr_set_allocation_functions_type gpr_set_allocation_functions_import; #define gpr_set_allocation_functions gpr_set_allocation_functions_import -typedef gpr_allocation_functions(*gpr_get_allocation_functions_type)(); +typedef gpr_allocation_functions(*gpr_get_allocation_functions_type)(void); extern gpr_get_allocation_functions_type gpr_get_allocation_functions_import; #define gpr_get_allocation_functions gpr_get_allocation_functions_import typedef gpr_avl(*gpr_avl_create_type)(const gpr_avl_vtable* vtable); @@ -712,7 +712,7 @@ extern gpr_log_message_type gpr_log_message_import; typedef void(*gpr_set_log_verbosity_type)(gpr_log_severity min_severity_to_print); extern gpr_set_log_verbosity_type gpr_set_log_verbosity_import; #define gpr_set_log_verbosity gpr_set_log_verbosity_import -typedef void(*gpr_log_verbosity_init_type)(); +typedef void(*gpr_log_verbosity_init_type)(void); extern gpr_log_verbosity_init_type gpr_log_verbosity_init_import; #define gpr_log_verbosity_init gpr_log_verbosity_init_import typedef void(*gpr_set_log_function_type)(gpr_log_func func); From 9f6a6f3f1a1ab44834ef5d4c3e4601e07c6287ed Mon Sep 17 00:00:00 2001 From: Muxi Yan <muxi@users.noreply.github.com> Date: Mon, 27 Nov 2017 16:28:44 -0800 Subject: [PATCH 08/10] Fix compiler error on need_to_unref_constructed `need_to_unref_constructed` is not initialized, making Xcode compiler [complain on Sierra](https://sponge-qa.corp.google.com/invocation?tab=Kokoro&id=0ff33b71-2f61-4ad6-837e-5e43043c282a&searchFor=): ``` /Volumes/BuildData/tmpfs/src/github/grpc/workspace_objc_macos_dbg_native/src/core/ext/filters/client_channel/subchannel_index.cc:206:7: error: variable 'need_to_unref_constructed' may be uninitialized when used here [-Werror,-Wconditional-uninitialized] ``` --- src/core/ext/filters/client_channel/subchannel_index.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/subchannel_index.cc b/src/core/ext/filters/client_channel/subchannel_index.cc index ae39ca394e2..1624643d0b4 100644 --- a/src/core/ext/filters/client_channel/subchannel_index.cc +++ b/src/core/ext/filters/client_channel/subchannel_index.cc @@ -163,7 +163,7 @@ grpc_subchannel* grpc_subchannel_index_register(grpc_exec_ctx* exec_ctx, grpc_subchannel_key* key, grpc_subchannel* constructed) { grpc_subchannel* c = nullptr; - bool need_to_unref_constructed; + bool need_to_unref_constructed = false; while (c == nullptr) { need_to_unref_constructed = false; From 14e96f9ae8b6490242b99915d4aa860ceac9154a Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari <mmx@google.com> Date: Mon, 27 Nov 2017 17:00:13 -0800 Subject: [PATCH 09/10] Bump 1.8.0-dev to 1.9.0-dev --- CMakeLists.txt | 2 +- Makefile | 4 ++-- build.yaml | 4 ++-- doc/g_stands_for.md | 1 + gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 4 ++-- src/core/lib/surface/version.cc | 2 +- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core/Version.csproj.include | 2 +- src/csharp/Grpc.Core/VersionInfo.cs | 4 ++-- src/csharp/build_packages_dotnetcli.bat | 2 +- src/csharp/build_packages_dotnetcli.sh | 4 ++-- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/composer.json | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 31 files changed, 36 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 77b60e898ab..fa178a86d10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.8.0-dev") +set(PACKAGE_VERSION "1.9.0-dev") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index c85b1bca733..cdba3d7ff19 100644 --- a/Makefile +++ b/Makefile @@ -412,8 +412,8 @@ Q = @ endif CORE_VERSION = 5.0.0-dev -CPP_VERSION = 1.8.0-dev -CSHARP_VERSION = 1.8.0-dev +CPP_VERSION = 1.9.0-dev +CSHARP_VERSION = 1.9.0-dev CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/build.yaml b/build.yaml index 4f6194ecc41..86054749e9a 100644 --- a/build.yaml +++ b/build.yaml @@ -13,8 +13,8 @@ settings: '#09': Per-language overrides are possible with (eg) ruby_version tag here '#10': See the expand_version.py for all the quirks here core_version: 5.0.0-dev - g_stands_for: generous - version: 1.8.0-dev + g_stands_for: glossy + version: 1.9.0-dev filegroups: - name: census public_headers: diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md index 4e2ca33276c..edc6dc1e798 100644 --- a/doc/g_stands_for.md +++ b/doc/g_stands_for.md @@ -12,3 +12,4 @@ future), and the corresponding version numbers that used them: - 1.6 'g' stands for 'garcia' - 1.7 'g' stands for 'gambit' - 1.8 'g' stands for 'generous' +- 1.9 'g' stands for 'glossy' diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 2f97565f1b4..8e0f60d4e93 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.8.0-dev' + version = '1.9.0-dev' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index db1e8db06c0..7533ef51dd3 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.8.0-dev' + version = '1.9.0-dev' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 36897790395..37410a573ad 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.8.0-dev' + version = '1.9.0-dev' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index 4c6cd3535f6..5fff7c81233 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.8.0-dev' + version = '1.9.0-dev' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index 59d49dd1657..7c0c309a895 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ <date>2017-08-24</date> <time>16:06:07</time> <version> - <release>1.8.0dev</release> - <api>1.8.0dev</api> + <release>1.9.0dev</release> + <api>1.9.0dev</api> </version> <stability> <release>beta</release> diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc index f4feadc640f..7d36c6c9e1d 100644 --- a/src/core/lib/surface/version.cc +++ b/src/core/lib/surface/version.cc @@ -23,4 +23,4 @@ const char* grpc_version_string(void) { return "5.0.0-dev"; } -const char* grpc_g_stands_for(void) { return "generous"; } +const char* grpc_g_stands_for(void) { return "glossy"; } diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index e1e5e895f69..7f01a66dcf0 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include <grpc++/grpc++.h> namespace grpc { -grpc::string Version() { return "1.8.0-dev"; } +grpc::string Version() { return "1.9.0-dev"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index b9ceaf82543..2d9e4ba16ae 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ <!-- This file is generated --> <Project> <PropertyGroup> - <GrpcCsharpVersion>1.8.0-dev</GrpcCsharpVersion> + <GrpcCsharpVersion>1.9.0-dev</GrpcCsharpVersion> <GoogleProtobufVersion>3.3.0</GoogleProtobufVersion> </PropertyGroup> </Project> diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index dab938821fa..9b5da1c9475 100644 --- a/src/csharp/Grpc.Core/VersionInfo.cs +++ b/src/csharp/Grpc.Core/VersionInfo.cs @@ -33,11 +33,11 @@ namespace Grpc.Core /// <summary> /// Current <c>AssemblyFileVersion</c> of gRPC C# assemblies /// </summary> - public const string CurrentAssemblyFileVersion = "1.8.0.0"; + public const string CurrentAssemblyFileVersion = "1.9.0.0"; /// <summary> /// Current version of gRPC C# /// </summary> - public const string CurrentVersion = "1.8.0-dev"; + public const string CurrentVersion = "1.9.0-dev"; } } diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index ff013d56800..8f89e2846a5 100755 --- a/src/csharp/build_packages_dotnetcli.bat +++ b/src/csharp/build_packages_dotnetcli.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.8.0-dev +set VERSION=1.9.0-dev @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/csharp/build_packages_dotnetcli.sh b/src/csharp/build_packages_dotnetcli.sh index 44a4791146b..6a6cafe2bdc 100755 --- a/src/csharp/build_packages_dotnetcli.sh +++ b/src/csharp/build_packages_dotnetcli.sh @@ -39,7 +39,7 @@ dotnet pack --configuration Release Grpc.Auth --output ../../../artifacts dotnet pack --configuration Release Grpc.HealthCheck --output ../../../artifacts dotnet pack --configuration Release Grpc.Reflection --output ../../../artifacts -nuget pack Grpc.nuspec -Version "1.8.0-dev" -OutputDirectory ../../artifacts -nuget pack Grpc.Tools.nuspec -Version "1.8.0-dev" -OutputDirectory ../../artifacts +nuget pack Grpc.nuspec -Version "1.9.0-dev" -OutputDirectory ../../artifacts +nuget pack Grpc.Tools.nuspec -Version "1.9.0-dev" -OutputDirectory ../../artifacts (cd ../../artifacts && zip csharp_nugets_dotnetcli.zip *.nupkg) diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 9065ab9f73e..80e1069dddf 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.8.0-dev' + v = '1.9.0-dev' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index db589d12de6..69dd6266fd6 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -23,4 +23,4 @@ // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.8.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.9.0-dev" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 02515063fa1..6e3a073020f 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -23,5 +23,5 @@ // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.8.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.9.0-dev" #define GRPC_C_VERSION_STRING @"5.0.0-dev" diff --git a/src/php/composer.json b/src/php/composer.json index 09471d23fee..43833980f9d 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -2,7 +2,7 @@ "name": "grpc/grpc-dev", "description": "gRPC library for PHP - for Developement use only", "license": "Apache-2.0", - "version": "1.8.0", + "version": "1.9.0", "require": { "php": ">=5.5.0", "google/protobuf": "^v3.3.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 93dd563cffb..48131d72d1a 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.8.0dev" +#define PHP_GRPC_VERSION "1.9.0dev" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 0887ac17224..993c49d4af2 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.8.0.dev0""" +__version__ = """1.9.0.dev0""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 61c41573756..8f07f3b30b2 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION='1.8.0.dev0' +VERSION='1.9.0.dev0' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 889297f0209..0987d57261d 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION='1.8.0.dev0' +VERSION='1.9.0.dev0' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 192f4cc2174..95d2ff143ad 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION='1.8.0.dev0' +VERSION='1.9.0.dev0' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 83470c28253..afc6dd83f29 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION='1.8.0.dev0' +VERSION='1.9.0.dev0' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 7065edd3bfc..99ca3fd82dd 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION='1.8.0.dev0' +VERSION='1.9.0.dev0' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 3001579ce77..be1412511ad 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.8.0.dev' + VERSION = '1.9.0.dev' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index c584a7cf593..48aad39e082 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.8.0.dev' + VERSION = '1.9.0.dev' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index db92b10c603..f613025be39 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION='1.8.0.dev0' +VERSION='1.9.0.dev0' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index eb27eed075f..269ce971f66 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.8.0-dev +PROJECT_NUMBER = 1.9.0-dev # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 3c564e203af..3e13de5b000 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.8.0-dev +PROJECT_NUMBER = 1.9.0-dev # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From 81e9581bf380ceea2f5edaf6661c040c7fa81859 Mon Sep 17 00:00:00 2001 From: Alex Polcyn <apolcyn@google.com> Date: Sat, 23 Sep 2017 18:48:02 -0700 Subject: [PATCH 10/10] Remove some sleeps in ruby tests and fix test server shutdown --- src/ruby/end2end/channel_closing_driver.rb | 6 +- src/ruby/end2end/channel_state_driver.rb | 7 +-- src/ruby/end2end/end2end_common.rb | 6 +- src/ruby/end2end/forking_client_driver.rb | 6 -- src/ruby/end2end/grpc_class_init_client.rb | 2 +- .../end2end/killed_client_thread_driver.rb | 56 ++++++++----------- ...multiple_killed_watching_threads_driver.rb | 2 + src/ruby/end2end/sig_handling_client.rb | 30 +++++++--- src/ruby/end2end/sig_handling_driver.rb | 35 ++++++++++-- .../sig_int_during_channel_watch_driver.rb | 4 -- src/ruby/lib/grpc/generic/rpc_server.rb | 37 ++++++++---- src/ruby/qps/worker.rb | 12 ++-- 12 files changed, 117 insertions(+), 86 deletions(-) diff --git a/src/ruby/end2end/channel_closing_driver.rb b/src/ruby/end2end/channel_closing_driver.rb index 0ceb3667eba..57544b03985 100755 --- a/src/ruby/end2end/channel_closing_driver.rb +++ b/src/ruby/end2end/channel_closing_driver.rb @@ -23,13 +23,11 @@ def main STDERR.puts 'start server' server_runner = ServerRunner.new(EchoServerImpl) server_port = server_runner.run - - sleep 1 - STDERR.puts 'start client' control_stub, client_pid = start_client('channel_closing_client.rb', server_port) - + # sleep to allow time for the client to get into + # the middle of a "watch connectivity state" call sleep 3 begin diff --git a/src/ruby/end2end/channel_state_driver.rb b/src/ruby/end2end/channel_state_driver.rb index 98339baebeb..f4b1cd2bb86 100755 --- a/src/ruby/end2end/channel_state_driver.rb +++ b/src/ruby/end2end/channel_state_driver.rb @@ -22,14 +22,11 @@ def main STDERR.puts 'start server' server_runner = ServerRunner.new(EchoServerImpl) server_port = server_runner.run - - sleep 1 - STDERR.puts 'start client' _, client_pid = start_client('channel_state_client.rb', server_port) - + # sleep to allow time for the client to get into + # the middle of a "watch connectivity state" call sleep 3 - Process.kill('SIGTERM', client_pid) begin diff --git a/src/ruby/end2end/end2end_common.rb b/src/ruby/end2end/end2end_common.rb index a1b824fcbf6..790fc23e923 100755 --- a/src/ruby/end2end/end2end_common.rb +++ b/src/ruby/end2end/end2end_common.rb @@ -40,12 +40,13 @@ end # ServerRunner starts an "echo server" that test clients can make calls to class ServerRunner - def initialize(service_impl) + def initialize(service_impl, rpc_server_args: {}) @service_impl = service_impl + @rpc_server_args = rpc_server_args end def run - @srv = GRPC::RpcServer.new + @srv = GRPC::RpcServer.new(@rpc_server_args) port = @srv.add_http2_port('0.0.0.0:0', :this_port_is_insecure) @srv.handle(@service_impl) @@ -75,7 +76,6 @@ def start_client(client_main, server_port) client_path, "--client_control_port=#{client_control_port}", "--server_port=#{server_port}") - sleep 1 control_stub = ClientControl::ClientController::Stub.new( "localhost:#{client_control_port}", :this_channel_is_insecure) [control_stub, client_pid] diff --git a/src/ruby/end2end/forking_client_driver.rb b/src/ruby/end2end/forking_client_driver.rb index 63565395f7d..5cf1d73112d 100755 --- a/src/ruby/end2end/forking_client_driver.rb +++ b/src/ruby/end2end/forking_client_driver.rb @@ -20,12 +20,6 @@ def main STDERR.puts 'start server' server_runner = ServerRunner.new(EchoServerImpl) server_port = server_runner.run - - # TODO(apolcyn) Can we get rid of this sleep? - # Without it, an immediate call to the just started EchoServer - # fails with UNAVAILABLE - sleep 1 - STDERR.puts 'start client' _, client_pid = start_client('forking_client_client.rb', server_port) diff --git a/src/ruby/end2end/grpc_class_init_client.rb b/src/ruby/end2end/grpc_class_init_client.rb index c35719a71fd..ff40350cfae 100755 --- a/src/ruby/end2end/grpc_class_init_client.rb +++ b/src/ruby/end2end/grpc_class_init_client.rb @@ -54,7 +54,7 @@ def run_concurrency_stress_test(test_proc) test_proc.call - fail 'exception thrown while child thread initing class' + fail '(expected) exception thrown while child thread initing class' end # default (no gc_stress and no concurrency_stress) diff --git a/src/ruby/end2end/killed_client_thread_driver.rb b/src/ruby/end2end/killed_client_thread_driver.rb index fce5d13e825..370f7e686bb 100755 --- a/src/ruby/end2end/killed_client_thread_driver.rb +++ b/src/ruby/end2end/killed_client_thread_driver.rb @@ -17,56 +17,46 @@ require_relative './end2end_common' # Service that sleeps for a long time upon receiving an 'echo request' -# Also, this notifies @call_started_cv once it has received a request. +# Also, this calls it's callback upon receiving an RPC as a method +# of synchronization/waiting for the child to start. class SleepingEchoServerImpl < Echo::EchoServer::Service - def initialize(call_started, call_started_mu, call_started_cv) - @call_started = call_started - @call_started_mu = call_started_mu - @call_started_cv = call_started_cv + def initialize(received_rpc_callback) + @received_rpc_callback = received_rpc_callback end def echo(echo_req, _) - @call_started_mu.synchronize do - @call_started.set_true - @call_started_cv.signal - end - sleep 1000 + @received_rpc_callback.call + # sleep forever to get the client stuck waiting + sleep Echo::EchoReply.new(response: echo_req.request) end end -# Mutable boolean -class BoolHolder - attr_reader :val - - def init - @val = false - end - - def set_true - @val = true - end -end - def main STDERR.puts 'start server' - call_started = BoolHolder.new - call_started_mu = Mutex.new - call_started_cv = ConditionVariable.new + client_started = false + client_started_mu = Mutex.new + client_started_cv = ConditionVariable.new + received_rpc_callback = proc do + client_started_mu.synchronize do + client_started = true + client_started_cv.signal + end + end - service_impl = SleepingEchoServerImpl.new(call_started, - call_started_mu, - call_started_cv) - server_runner = ServerRunner.new(service_impl) + service_impl = SleepingEchoServerImpl.new(received_rpc_callback) + # RPCs against the server will all be hanging, so kill thread + # pool workers immediately rather than after waiting for a second. + rpc_server_args = { poll_period: 0, pool_keep_alive: 0 } + server_runner = ServerRunner.new(service_impl, rpc_server_args: rpc_server_args) server_port = server_runner.run - STDERR.puts 'start client' _, client_pid = start_client('killed_client_thread_client.rb', server_port) - call_started_mu.synchronize do - call_started_cv.wait(call_started_mu) until call_started.val + client_started_mu.synchronize do + client_started_cv.wait(client_started_mu) until client_started end # SIGTERM the child process now that it's diff --git a/src/ruby/end2end/multiple_killed_watching_threads_driver.rb b/src/ruby/end2end/multiple_killed_watching_threads_driver.rb index 94d5e9da2d3..59f6f275e46 100755 --- a/src/ruby/end2end/multiple_killed_watching_threads_driver.rb +++ b/src/ruby/end2end/multiple_killed_watching_threads_driver.rb @@ -26,6 +26,8 @@ def watch_state(ch) fail "non-idle state: #{state}" unless state == IDLE ch.watch_connectivity_state(IDLE, Time.now + 360) end + # sleep to get the thread into the middle of a + # "watch connectivity state" call sleep 0.1 thd.kill end diff --git a/src/ruby/end2end/sig_handling_client.rb b/src/ruby/end2end/sig_handling_client.rb index 41b5f334be3..129ad7cb7fd 100755 --- a/src/ruby/end2end/sig_handling_client.rb +++ b/src/ruby/end2end/sig_handling_client.rb @@ -30,16 +30,18 @@ class SigHandlingClientController < ClientControl::ClientController::Service end def shutdown(_, _) - Thread.new do - # TODO(apolcyn) There is a race between stopping the - # server and the "shutdown" rpc completing, - # See if stop method on server can end active RPC cleanly, to - # avoid this sleep. - sleep 3 + # Spawn a new thread because RpcServer#stop is + # synchronous and blocks until either this RPC has finished, + # or the server's "poll_period" seconds have passed. + @shutdown_thread = Thread.new do @srv.stop end ClientControl::Void.new end + + def join_shutdown_thread + @shutdown_thread.join + end end def main @@ -62,13 +64,23 @@ def main STDERR.puts 'SIGINT received' end - srv = GRPC::RpcServer.new + # The "shutdown" RPC should end very quickly. + # Allow a few seconds to be safe. + srv = GRPC::RpcServer.new(poll_period: 3) srv.add_http2_port("0.0.0.0:#{client_control_port}", :this_port_is_insecure) stub = Echo::EchoServer::Stub.new("localhost:#{server_port}", :this_channel_is_insecure) - srv.handle(SigHandlingClientController.new(srv, stub)) - srv.run + control_service = SigHandlingClientController.new(srv, stub) + srv.handle(control_service) + server_thread = Thread.new do + srv.run + end + srv.wait_till_running + # send a first RPC to notify the parent process that we've started + stub.echo(Echo::EchoRequest.new(request: 'client/child started')) + server_thread.join + control_service.join_shutdown_thread end main diff --git a/src/ruby/end2end/sig_handling_driver.rb b/src/ruby/end2end/sig_handling_driver.rb index 291bf29424c..0ad1cbd661d 100755 --- a/src/ruby/end2end/sig_handling_driver.rb +++ b/src/ruby/end2end/sig_handling_driver.rb @@ -19,17 +19,42 @@ require_relative './end2end_common' +# A service that calls back it's received_rpc_callback +# upon receiving an RPC. Used for synchronization/waiting +# for child process to start. +class ClientStartedService < Echo::EchoServer::Service + def initialize(received_rpc_callback) + @received_rpc_callback = received_rpc_callback + end + + def echo(echo_req, _) + @received_rpc_callback.call unless @received_rpc_callback.nil? + @received_rpc_callback = nil + Echo::EchoReply.new(response: echo_req.request) + end +end + def main STDERR.puts 'start server' - server_runner = ServerRunner.new(EchoServerImpl) - server_port = server_runner.run - - sleep 1 + client_started = false + client_started_mu = Mutex.new + client_started_cv = ConditionVariable.new + received_rpc_callback = proc do + client_started_mu.synchronize do + client_started = true + client_started_cv.signal + end + end + client_started_service = ClientStartedService.new(received_rpc_callback) + server_runner = ServerRunner.new(client_started_service) + server_port = server_runner.run STDERR.puts 'start client' control_stub, client_pid = start_client('sig_handling_client.rb', server_port) - sleep 1 + client_started_mu.synchronize do + client_started_cv.wait(client_started_mu) until client_started + end count = 0 while count < 5 diff --git a/src/ruby/end2end/sig_int_during_channel_watch_driver.rb b/src/ruby/end2end/sig_int_during_channel_watch_driver.rb index b054f0f5f31..2df22f48a2e 100755 --- a/src/ruby/end2end/sig_int_during_channel_watch_driver.rb +++ b/src/ruby/end2end/sig_int_during_channel_watch_driver.rb @@ -23,13 +23,9 @@ def main STDERR.puts 'start server' server_runner = ServerRunner.new(EchoServerImpl) server_port = server_runner.run - - sleep 1 - STDERR.puts 'start client' _, client_pid = start_client('sig_int_during_channel_watch_client.rb', server_port) - # give time for the client to get into the middle # of a channel state watch call sleep 1 diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb index d5fc11dc1ca..c80c7fcd32c 100644 --- a/src/ruby/lib/grpc/generic/rpc_server.rb +++ b/src/ruby/lib/grpc/generic/rpc_server.rb @@ -92,9 +92,13 @@ module GRPC # Stops the jobs in the pool def stop GRPC.logger.info('stopping, will wait for all the workers to exit') - schedule { throw :exit } while ready_for_work? - @stop_mutex.synchronize do # wait @keep_alive for works to stop + @stop_mutex.synchronize do # wait @keep_alive seconds for workers to stop @stopped = true + loop do + break unless ready_for_work? + worker_queue = @ready_workers.pop + worker_queue << [proc { throw :exit }, []] + end @stop_cond.wait(@stop_mutex, @keep_alive) if @workers.size > 0 end forcibly_stop_workers @@ -138,7 +142,10 @@ module GRPC end # there shouldn't be any work given to this thread while its busy fail('received a task while busy') unless worker_queue.empty? - @ready_workers << worker_queue + @stop_mutex.synchronize do + return if @stopped + @ready_workers << worker_queue + end end end end @@ -186,8 +193,13 @@ module GRPC # * max_waiting_requests: Deprecated due to internal changes to the thread # pool. This is still an argument for compatibility but is ignored. # - # * poll_period: when present, the server polls for new events with this - # period + # * poll_period: The amount of time in seconds to wait for + # currently-serviced RPC's to finish before cancelling them when shutting + # down the server. + # + # * pool_keep_alive: The amount of time in seconds to wait + # for currently busy thread-pool threads to finish before + # forcing an abrupt exit to each thread. # # * connect_md_proc: # when non-nil is a proc for determining metadata to to send back the client @@ -202,17 +214,18 @@ module GRPC # intercepting server handlers to provide extra functionality. # Interceptors are an EXPERIMENTAL API. # - def initialize(pool_size:DEFAULT_POOL_SIZE, - max_waiting_requests:DEFAULT_MAX_WAITING_REQUESTS, - poll_period:DEFAULT_POLL_PERIOD, - connect_md_proc:nil, - server_args:{}, - interceptors:[]) + def initialize(pool_size: DEFAULT_POOL_SIZE, + max_waiting_requests: DEFAULT_MAX_WAITING_REQUESTS, + poll_period: DEFAULT_POLL_PERIOD, + pool_keep_alive: GRPC::RpcServer::DEFAULT_POOL_SIZE, + connect_md_proc: nil, + server_args: {}, + interceptors: []) @connect_md_proc = RpcServer.setup_connect_md_proc(connect_md_proc) @max_waiting_requests = max_waiting_requests @poll_period = poll_period @pool_size = pool_size - @pool = Pool.new(@pool_size) + @pool = Pool.new(@pool_size, keep_alive: pool_keep_alive) @run_cond = ConditionVariable.new @run_mutex = Mutex.new # running_state can take 4 values: :not_started, :running, :stopping, and diff --git a/src/ruby/qps/worker.rb b/src/ruby/qps/worker.rb index 21e88158907..82584874183 100755 --- a/src/ruby/qps/worker.rb +++ b/src/ruby/qps/worker.rb @@ -77,8 +77,7 @@ class WorkerServiceImpl < Grpc::Testing::WorkerService::Service Grpc::Testing::CoreResponse.new(cores: cpu_cores) end def quit_worker(_args, _call) - Thread.new { - sleep 3 + @shutdown_thread = Thread.new { @server.stop } Grpc::Testing::Void.new @@ -87,6 +86,9 @@ class WorkerServiceImpl < Grpc::Testing::WorkerService::Service @server = s @server_port = sp end + def join_shutdown_thread + @shutdown_thread.join + end end def main @@ -107,11 +109,13 @@ def main # Configure any errors with client or server child threads to surface Thread.abort_on_exception = true - s = GRPC::RpcServer.new + s = GRPC::RpcServer.new(poll_period: 3) s.add_http2_port("0.0.0.0:" + options['driver_port'].to_s, :this_port_is_insecure) - s.handle(WorkerServiceImpl.new(s, options['server_port'].to_i)) + worker_service = WorkerServiceImpl.new(s, options['server_port'].to_i) + s.handle(worker_service) s.run + worker_service.join_shutdown_thread end main