diff options
-rw-r--r-- | composer.json | 2 | ||||
-rw-r--r-- | doc/PROTOCOL-WEB.md | 29 | ||||
-rw-r--r-- | examples/php/composer.json | 2 | ||||
-rw-r--r-- | package.xml | 44 | ||||
-rw-r--r-- | src/core/ext/client_channel/client_channel.c | 222 | ||||
-rw-r--r-- | src/cpp/server/health/default_health_check_service.cc | 4 | ||||
-rw-r--r-- | src/php/README.md | 2 | ||||
-rw-r--r-- | src/php/composer.json | 2 | ||||
-rw-r--r-- | src/python/grpcio_tests/tests/unit/_thread_cleanup_test.py | 4 | ||||
-rw-r--r-- | templates/composer.json.template | 2 | ||||
-rw-r--r-- | templates/package.xml.template | 44 | ||||
-rw-r--r-- | templates/src/php/composer.json.template | 2 | ||||
-rw-r--r-- | tools/doxygen/Doxyfile.c++ | 1 | ||||
-rw-r--r-- | tools/doxygen/Doxyfile.c++.internal | 1 | ||||
-rw-r--r-- | tools/doxygen/Doxyfile.core | 1 | ||||
-rw-r--r-- | tools/doxygen/Doxyfile.core.internal | 1 | ||||
-rwxr-xr-x | tools/run_tests/run_microbenchmark.py | 34 |
17 files changed, 260 insertions, 137 deletions
diff --git a/composer.json b/composer.json index 53ae6388fb..0cafb94808 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ "license": "BSD-3-Clause", "require": { "php": ">=5.5.0", - "google/protobuf": "v3.1.0" + "google/protobuf": "^v3.1.0" }, "require-dev": { "google/auth": "v0.9" diff --git a/doc/PROTOCOL-WEB.md b/doc/PROTOCOL-WEB.md index 35448d683f..0b54e0f34f 100644 --- a/doc/PROTOCOL-WEB.md +++ b/doc/PROTOCOL-WEB.md @@ -39,6 +39,7 @@ Content-Type * e.g. application/grpc-web+[proto, json, thrift] 2. application/grpc-web-text * text-encoded streams of “application/grpc-web” + * e.g. application/grpc-web-text+[proto, thrift] --- @@ -60,10 +61,18 @@ HTTP/2 related behavior (specified in [gRPC over HTTP2](http://www.grpc.io/docs/ Message framing (vs. [http2-transport-mapping](http://www.grpc.io/docs/guides/wire.html#http2-transport-mapping)) 1. Response status encoded as part of the response body - * Key-value pairs encoded as a HTTP/1 headers block (without the terminating newline). + * Key-value pairs encoded as a HTTP/1 headers block (without the terminating newline), per https://tools.ietf.org/html/rfc7230#section-3.2 + ``` + key1: foo\r\n + key2: bar\r\n + ``` 2. 8th (MSB) bit of the 1st gRPC frame byte * 0: data * 1: trailers + ``` + 10000000b: an uncompressed trailer (as part of the body) + 10000001b: a compressed trailer + ``` 3. Trailers must be the last message of the response, as enforced by the implementation 4. Trailers-only responses: no change to the gRPC protocol spec. @@ -72,10 +81,9 @@ in the body. --- -User Agent and Server headers +User Agent -* U-A: grpc-web-javascript/0.1 -* Server: grpc-web-gateway/0.1 +* U-A: grpc-web-javascript --- @@ -93,7 +101,7 @@ to security policies with XHR response body is not necessarily a valid base64-encoded entity * While the server runtime will always base64-encode and flush gRPC messages atomically the client library should not assume base64 padding always - happens at the boundary of message frames. + happens at the boundary of message frames. That is, the implementation may send base64-encoded "chunks" with potential padding whenever the runtime needs to flush a byte buffer. 3. For binary trailers, when the content-type is set to application/grpc-web-text, the extra base64 encoding specified in [gRPC over HTTP2](http://www.grpc.io/docs/guides/wire.html) @@ -131,6 +139,10 @@ Security CORS preflight +* Should follow the [CORS spec](https://developer.mozilla.org/en-US/docs/Web/HTTP/Server-Side_Access_Control) + * Access-Control-Allow-Credentials to allow Authorization headers + * Access-Control-Allow-Methods to allow POST and (preflight) OPTIONS only + * Access-Control-Allow-Headers to whatever the preflight request carries * The client library may support header overwrites to avoid preflight * https://github.com/whatwg/fetch/issues/210 * CSP support to be specified @@ -149,3 +161,10 @@ Bidi-streaming, with flow-control * Pending on [whatwg fetch/streams](https://github.com/whatwg/fetch) to be finalized and implemented in modern browsers * gRPC-Web client will support the native gRPC protocol with modern browsers + +--- + +Versioning + +* Special headers may be introduced to support features that may break compatiblity. + diff --git a/examples/php/composer.json b/examples/php/composer.json index f0b9977252..f4b177c271 100644 --- a/examples/php/composer.json +++ b/examples/php/composer.json @@ -2,7 +2,7 @@ "name": "grpc/grpc-demo", "description": "gRPC example for PHP", "require": { - "grpc/grpc": "v1.1.0" + "grpc/grpc": "^v1.1.0" }, "autoload": { "psr-4": { diff --git a/package.xml b/package.xml index d82f2e49a8..e16161d7a2 100644 --- a/package.xml +++ b/package.xml @@ -10,7 +10,7 @@ <email>grpc-packages@google.com</email> <active>yes</active> </lead> - <date>2017-01-13</date> + <date>2017-03-01</date> <time>16:06:07</time> <version> <release>1.2.0dev</release> @@ -22,8 +22,8 @@ </stability> <license>BSD</license> <notes> -- PHP Proto3 adoption #8179 -- Various bug fixes +- Added arg info macros #9751 +- Updated codegen to be consistent with protobuf #9492 </notes> <contents> <dir baseinstalldir="/" name="/"> @@ -1276,8 +1276,8 @@ Update to wrap gRPC C Core version 0.10.0 </release> <release> <version> - <release>1.1.0dev</release> - <api>1.1.0dev</api> + <release>1.1.0RC1</release> + <api>1.1.0RC1</api> </version> <stability> <release>beta</release> @@ -1287,7 +1287,39 @@ Update to wrap gRPC C Core version 0.10.0 <license>BSD</license> <notes> - PHP Proto3 adoption #8179 -- Various bug fixes +- Various bug fixes + </notes> + </release> + <release> + <version> + <release>1.1.0</release> + <api>1.1.0</api> + </version> + <stability> + <release>stable</release> + <api>stable</api> + </stability> + <date>2017-01-31</date> + <license>BSD</license> + <notes> +- PHP Proto3 adoption #8179 +- Various bug fixes + </notes> + </release> + <release> + <version> + <release>1.2.0RC1</release> + <api>1.2.0RC1</api> + </version> + <stability> + <release>beta</release> + <api>beta</api> + </stability> + <date>2017-03-01</date> + <license>BSD</license> + <notes> +- Added arg info macros #9751 +- Updated codegen to be consistent with protobuf #9492 </notes> </release> </changelog> diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c index 34015c534e..bf64f84772 100644 --- a/src/core/ext/client_channel/client_channel.c +++ b/src/core/ext/client_channel/client_channel.c @@ -76,24 +76,82 @@ typedef enum { WAIT_FOR_READY_TRUE } wait_for_ready_value; -typedef struct method_parameters { +typedef struct { + gpr_refcount refs; gpr_timespec timeout; wait_for_ready_value wait_for_ready; } method_parameters; +static method_parameters *method_parameters_ref( + method_parameters *method_params) { + gpr_ref(&method_params->refs); + return method_params; +} + +static void method_parameters_unref(method_parameters *method_params) { + if (gpr_unref(&method_params->refs)) { + gpr_free(method_params); + } +} + static void *method_parameters_copy(void *value) { - void *new_value = gpr_malloc(sizeof(method_parameters)); - memcpy(new_value, value, sizeof(method_parameters)); - return new_value; + return method_parameters_ref(value); } -static void method_parameters_free(grpc_exec_ctx *exec_ctx, void *p) { - gpr_free(p); +static void method_parameters_free(grpc_exec_ctx *exec_ctx, void *value) { + method_parameters_unref(value); } static const grpc_slice_hash_table_vtable method_parameters_vtable = { method_parameters_free, method_parameters_copy}; +static bool parse_wait_for_ready(grpc_json *field, + wait_for_ready_value *wait_for_ready) { + if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) { + return false; + } + *wait_for_ready = field->type == GRPC_JSON_TRUE ? WAIT_FOR_READY_TRUE + : WAIT_FOR_READY_FALSE; + return true; +} + +static bool parse_timeout(grpc_json *field, gpr_timespec *timeout) { + if (field->type != GRPC_JSON_STRING) return false; + size_t len = strlen(field->value); + if (field->value[len - 1] != 's') return false; + char *buf = gpr_strdup(field->value); + buf[len - 1] = '\0'; // Remove trailing 's'. + char *decimal_point = strchr(buf, '.'); + if (decimal_point != NULL) { + *decimal_point = '\0'; + timeout->tv_nsec = gpr_parse_nonnegative_int(decimal_point + 1); + if (timeout->tv_nsec == -1) { + gpr_free(buf); + return false; + } + // There should always be exactly 3, 6, or 9 fractional digits. + int multiplier = 1; + switch (strlen(decimal_point + 1)) { + case 9: + break; + case 6: + multiplier *= 1000; + break; + case 3: + multiplier *= 1000000; + break; + default: // Unsupported number of digits. + gpr_free(buf); + return false; + } + timeout->tv_nsec *= multiplier; + } + timeout->tv_sec = gpr_parse_nonnegative_int(buf); + gpr_free(buf); + if (timeout->tv_sec == -1) return false; + return true; +} + static void *method_parameters_create_from_json(const grpc_json *json) { wait_for_ready_value wait_for_ready = WAIT_FOR_READY_UNSET; gpr_timespec timeout = {0, 0, GPR_TIMESPAN}; @@ -101,49 +159,14 @@ static void *method_parameters_create_from_json(const grpc_json *json) { if (field->key == NULL) continue; if (strcmp(field->key, "waitForReady") == 0) { if (wait_for_ready != WAIT_FOR_READY_UNSET) return NULL; // Duplicate. - if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) { - return NULL; - } - wait_for_ready = field->type == GRPC_JSON_TRUE ? WAIT_FOR_READY_TRUE - : WAIT_FOR_READY_FALSE; + if (!parse_wait_for_ready(field, &wait_for_ready)) return NULL; } else if (strcmp(field->key, "timeout") == 0) { if (timeout.tv_sec > 0 || timeout.tv_nsec > 0) return NULL; // Duplicate. - if (field->type != GRPC_JSON_STRING) return NULL; - size_t len = strlen(field->value); - if (field->value[len - 1] != 's') return NULL; - char *buf = gpr_strdup(field->value); - buf[len - 1] = '\0'; // Remove trailing 's'. - char *decimal_point = strchr(buf, '.'); - if (decimal_point != NULL) { - *decimal_point = '\0'; - timeout.tv_nsec = gpr_parse_nonnegative_int(decimal_point + 1); - if (timeout.tv_nsec == -1) { - gpr_free(buf); - return NULL; - } - // There should always be exactly 3, 6, or 9 fractional digits. - int multiplier = 1; - switch (strlen(decimal_point + 1)) { - case 9: - break; - case 6: - multiplier *= 1000; - break; - case 3: - multiplier *= 1000000; - break; - default: // Unsupported number of digits. - gpr_free(buf); - return NULL; - } - timeout.tv_nsec *= multiplier; - } - timeout.tv_sec = gpr_parse_nonnegative_int(buf); - if (timeout.tv_sec == -1) return NULL; - gpr_free(buf); + if (!parse_timeout(field, &timeout)) return NULL; } } method_parameters *value = gpr_malloc(sizeof(method_parameters)); + gpr_ref_init(&value->refs, 1); value->timeout = timeout; value->wait_for_ready = wait_for_ready; return value; @@ -629,7 +652,7 @@ typedef struct client_channel_call_data { grpc_slice path; // Request path. gpr_timespec call_start_time; gpr_timespec deadline; - wait_for_ready_value wait_for_ready_from_service_config; + method_parameters *method_params; grpc_closure read_service_config; grpc_error *cancel_error; @@ -837,10 +860,11 @@ static bool pick_subchannel_locked( initial_metadata_flags & GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET; const bool wait_for_ready_set_from_service_config = - calld->wait_for_ready_from_service_config != WAIT_FOR_READY_UNSET; + calld->method_params != NULL && + calld->method_params->wait_for_ready != WAIT_FOR_READY_UNSET; if (!wait_for_ready_set_from_api && wait_for_ready_set_from_service_config) { - if (calld->wait_for_ready_from_service_config == WAIT_FOR_READY_TRUE) { + if (calld->method_params->wait_for_ready == WAIT_FOR_READY_TRUE) { initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY; } else { initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY; @@ -978,10 +1002,9 @@ static void start_transport_stream_op_locked_inner(grpc_exec_ctx *exec_ctx, add_waiting_locked(calld, op); } -static void cc_start_transport_stream_op_locked(grpc_exec_ctx *exec_ctx, - void *arg, - grpc_error *error_ignored) { - GPR_TIMER_BEGIN("cc_start_transport_stream_op_locked", 0); +static void start_transport_stream_op_locked(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error_ignored) { + GPR_TIMER_BEGIN("start_transport_stream_op_locked", 0); grpc_transport_stream_op *op = arg; grpc_call_element *elem = op->handler_private.args[0]; @@ -991,7 +1014,7 @@ static void cc_start_transport_stream_op_locked(grpc_exec_ctx *exec_ctx, GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "start_transport_stream_op"); - GPR_TIMER_END("cc_start_transport_stream_op_locked", 0); + GPR_TIMER_END("start_transport_stream_op_locked", 0); } /* The logic here is fairly complicated, due to (a) the fact that we @@ -1031,52 +1054,53 @@ static void cc_start_transport_stream_op(grpc_exec_ctx *exec_ctx, grpc_closure_sched( exec_ctx, grpc_closure_init(&op->handler_private.closure, - cc_start_transport_stream_op_locked, op, + start_transport_stream_op_locked, op, grpc_combiner_scheduler(chand->combiner, false)), GRPC_ERROR_NONE); GPR_TIMER_END("cc_start_transport_stream_op", 0); } +// Sets calld->method_params. +// If the method params specify a timeout, populates +// *per_method_deadline and returns true. +static bool set_call_method_params_from_service_config_locked( + grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + gpr_timespec *per_method_deadline) { + channel_data *chand = elem->channel_data; + call_data *calld = elem->call_data; + if (chand->method_params_table != NULL) { + calld->method_params = grpc_method_config_table_get( + exec_ctx, chand->method_params_table, calld->path); + if (calld->method_params != NULL) { + method_parameters_ref(calld->method_params); + if (gpr_time_cmp(calld->method_params->timeout, + gpr_time_0(GPR_TIMESPAN)) != 0) { + *per_method_deadline = + gpr_time_add(calld->call_start_time, calld->method_params->timeout); + return true; + } + } + } + return false; +} + // Gets data from the service config. Invoked when the resolver returns // its initial result. static void read_service_config_locked(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_call_element *elem = arg; - channel_data *chand = elem->channel_data; call_data *calld = elem->call_data; // If this is an error, there's no point in looking at the service config. if (error == GRPC_ERROR_NONE) { - // Get the method config table from channel data. - grpc_slice_hash_table *method_params_table = NULL; - if (chand->method_params_table != NULL) { - method_params_table = - grpc_slice_hash_table_ref(chand->method_params_table); - } - // If the method config table was present, use it. - if (method_params_table != NULL) { - const method_parameters *method_params = grpc_method_config_table_get( - exec_ctx, method_params_table, calld->path); - if (method_params != NULL) { - const bool have_method_timeout = - gpr_time_cmp(method_params->timeout, gpr_time_0(GPR_TIMESPAN)) != 0; - if (have_method_timeout || - method_params->wait_for_ready != WAIT_FOR_READY_UNSET) { - if (have_method_timeout) { - const gpr_timespec per_method_deadline = - gpr_time_add(calld->call_start_time, method_params->timeout); - if (gpr_time_cmp(per_method_deadline, calld->deadline) < 0) { - calld->deadline = per_method_deadline; - // Reset deadline timer. - grpc_deadline_state_reset(exec_ctx, elem, calld->deadline); - } - } - if (method_params->wait_for_ready != WAIT_FOR_READY_UNSET) { - calld->wait_for_ready_from_service_config = - method_params->wait_for_ready; - } - } + gpr_timespec per_method_deadline; + if (set_call_method_params_from_service_config_locked( + exec_ctx, elem, &per_method_deadline)) { + // If the deadline from the service config is shorter than the one + // from the client API, reset the deadline timer. + if (gpr_time_cmp(per_method_deadline, calld->deadline) < 0) { + calld->deadline = per_method_deadline; + grpc_deadline_state_reset(exec_ctx, elem, calld->deadline); } - grpc_slice_hash_table_unref(exec_ctx, method_params_table); } } GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "read_service_config"); @@ -1091,29 +1115,12 @@ static void initial_read_service_config_locked(grpc_exec_ctx *exec_ctx, // If the resolver has already returned results, then we can access // the service config parameters immediately. Otherwise, we need to // defer that work until the resolver returns an initial result. - // TODO(roth): This code is almost but not quite identical to the code - // in read_service_config() above. It would be nice to find a way to - // combine them, to avoid having to maintain it twice. if (chand->lb_policy != NULL) { // We already have a resolver result, so check for service config. - if (chand->method_params_table != NULL) { - grpc_slice_hash_table *method_params_table = - grpc_slice_hash_table_ref(chand->method_params_table); - method_parameters *method_params = grpc_method_config_table_get( - exec_ctx, method_params_table, calld->path); - if (method_params != NULL) { - if (gpr_time_cmp(method_params->timeout, - gpr_time_0(GPR_CLOCK_MONOTONIC)) != 0) { - gpr_timespec per_method_deadline = - gpr_time_add(calld->call_start_time, method_params->timeout); - calld->deadline = gpr_time_min(calld->deadline, per_method_deadline); - } - if (method_params->wait_for_ready != WAIT_FOR_READY_UNSET) { - calld->wait_for_ready_from_service_config = - method_params->wait_for_ready; - } - } - grpc_slice_hash_table_unref(exec_ctx, method_params_table); + gpr_timespec per_method_deadline; + if (set_call_method_params_from_service_config_locked( + exec_ctx, elem, &per_method_deadline)) { + calld->deadline = gpr_time_min(calld->deadline, per_method_deadline); } } else { // We don't yet have a resolver result, so register a callback to @@ -1144,7 +1151,7 @@ static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx, calld->path = grpc_slice_ref_internal(args->path); calld->call_start_time = args->start_time; calld->deadline = gpr_convert_clock_type(args->deadline, GPR_CLOCK_MONOTONIC); - calld->wait_for_ready_from_service_config = WAIT_FOR_READY_UNSET; + calld->method_params = NULL; calld->cancel_error = GRPC_ERROR_NONE; gpr_atm_rel_store(&calld->subchannel_call, 0); calld->connected_subchannel = NULL; @@ -1172,6 +1179,9 @@ static void cc_destroy_call_elem(grpc_exec_ctx *exec_ctx, call_data *calld = elem->call_data; grpc_deadline_state_destroy(exec_ctx, elem); grpc_slice_unref_internal(exec_ctx, calld->path); + if (calld->method_params != NULL) { + method_parameters_unref(calld->method_params); + } GRPC_ERROR_UNREF(calld->cancel_error); grpc_subchannel_call *call = GET_CALL(calld); if (call != NULL && call != CANCELLED_CALL) { diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc index 46def70e8a..bc98ce79a7 100644 --- a/src/cpp/server/health/default_health_check_service.cc +++ b/src/cpp/server/health/default_health_check_service.cc @@ -63,7 +63,9 @@ Status DefaultHealthCheckService::HealthCheckServiceImpl::Check( ServerContext* context, const ByteBuffer* request, ByteBuffer* response) { // Decode request. std::vector<Slice> slices; - request->Dump(&slices); + if (!request->Dump(&slices).ok()) { + return Status(StatusCode::INVALID_ARGUMENT, ""); + } uint8_t* request_bytes = nullptr; bool request_bytes_owned = false; size_t request_size = 0; diff --git a/src/php/README.md b/src/php/README.md index 821ea16aab..f08541f16c 100644 --- a/src/php/README.md +++ b/src/php/README.md @@ -158,7 +158,7 @@ $ composer install ### Protobuf compiler Again if you don't have it already, you need to install the protobuf compiler -`protoc`, version 3.2.0+. +`protoc`, version 3.1.0+ (the newer the better). If `protoc` hasn't been installed, you can download the `protoc` binaries from [the protocol buffers Github repository](https://github.com/google/protobuf/releases). diff --git a/src/php/composer.json b/src/php/composer.json index 8528304c81..491e34795a 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -5,7 +5,7 @@ "version": "1.2.0", "require": { "php": ">=5.5.0", - "google/protobuf": "v3.1.0" + "google/protobuf": "^v3.1.0" }, "require-dev": { "google/auth": "v0.9" diff --git a/src/python/grpcio_tests/tests/unit/_thread_cleanup_test.py b/src/python/grpcio_tests/tests/unit/_thread_cleanup_test.py index be3522f46f..eb5f459848 100644 --- a/src/python/grpcio_tests/tests/unit/_thread_cleanup_test.py +++ b/src/python/grpcio_tests/tests/unit/_thread_cleanup_test.py @@ -35,8 +35,8 @@ import unittest from grpc import _common _SHORT_TIME = 0.5 -_LONG_TIME = 2.0 -_EPSILON = 0.1 +_LONG_TIME = 5.0 +_EPSILON = 0.5 def cleanup(timeout): diff --git a/templates/composer.json.template b/templates/composer.json.template index f56ecb69d6..94f0c236a9 100644 --- a/templates/composer.json.template +++ b/templates/composer.json.template @@ -9,7 +9,7 @@ "license": "BSD-3-Clause", "require": { "php": ">=5.5.0", - "google/protobuf": "v3.1.0" + "google/protobuf": "^v3.1.0" }, "require-dev": { "google/auth": "v0.9" diff --git a/templates/package.xml.template b/templates/package.xml.template index 80f1a1fe97..8655cfa1d9 100644 --- a/templates/package.xml.template +++ b/templates/package.xml.template @@ -12,7 +12,7 @@ <email>grpc-packages@google.com</email> <active>yes</active> </lead> - <date>2017-01-13</date> + <date>2017-03-01</date> <time>16:06:07</time> <version> <release>${settings.php_version.php()}</release> @@ -24,8 +24,8 @@ </stability> <license>BSD</license> <notes> - - PHP Proto3 adoption #8179 - - Various bug fixes + - Added arg info macros #9751 + - Updated codegen to be consistent with protobuf #9492 </notes> <contents> <dir baseinstalldir="/" name="/"> @@ -312,8 +312,8 @@ </release> <release> <version> - <release>1.1.0dev</release> - <api>1.1.0dev</api> + <release>1.1.0RC1</release> + <api>1.1.0RC1</api> </version> <stability> <release>beta</release> @@ -323,7 +323,39 @@ <license>BSD</license> <notes> - PHP Proto3 adoption #8179 - - Various bug fixes + - Various bug fixes + </notes> + </release> + <release> + <version> + <release>1.1.0</release> + <api>1.1.0</api> + </version> + <stability> + <release>stable</release> + <api>stable</api> + </stability> + <date>2017-01-31</date> + <license>BSD</license> + <notes> + - PHP Proto3 adoption #8179 + - Various bug fixes + </notes> + </release> + <release> + <version> + <release>1.2.0RC1</release> + <api>1.2.0RC1</api> + </version> + <stability> + <release>beta</release> + <api>beta</api> + </stability> + <date>2017-03-01</date> + <license>BSD</license> + <notes> + - Added arg info macros #9751 + - Updated codegen to be consistent with protobuf #9492 </notes> </release> </changelog> diff --git a/templates/src/php/composer.json.template b/templates/src/php/composer.json.template index ecc516d1c4..1887ee3c82 100644 --- a/templates/src/php/composer.json.template +++ b/templates/src/php/composer.json.template @@ -7,7 +7,7 @@ "version": "${settings.php_version.php_composer()}", "require": { "php": ">=5.5.0", - "google/protobuf": "v3.1.0" + "google/protobuf": "^v3.1.0" }, "require-dev": { "google/auth": "v0.9" diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 551ba46b3b..4d2c429957 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -779,6 +779,7 @@ doc/fail_fast.md \ doc/g_stands_for.md \ doc/health-checking.md \ doc/http-grpc-status-mapping.md \ +doc/internationalization.md \ doc/interop-test-descriptions.md \ doc/load-balancing.md \ doc/naming.md \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 0d7ddfc6d6..498f572dc6 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -779,6 +779,7 @@ doc/fail_fast.md \ doc/g_stands_for.md \ doc/health-checking.md \ doc/http-grpc-status-mapping.md \ +doc/internationalization.md \ doc/interop-test-descriptions.md \ doc/load-balancing.md \ doc/naming.md \ diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index 896ee0213b..fa41e56b43 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -778,6 +778,7 @@ doc/fail_fast.md \ doc/g_stands_for.md \ doc/health-checking.md \ doc/http-grpc-status-mapping.md \ +doc/internationalization.md \ doc/interop-test-descriptions.md \ doc/load-balancing.md \ doc/naming.md \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 04fd7bee22..bffa050041 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -778,6 +778,7 @@ doc/fail_fast.md \ doc/g_stands_for.md \ doc/health-checking.md \ doc/http-grpc-status-mapping.md \ +doc/internationalization.md \ doc/interop-test-descriptions.md \ doc/load-balancing.md \ doc/naming.md \ diff --git a/tools/run_tests/run_microbenchmark.py b/tools/run_tests/run_microbenchmark.py index c6cc60715e..2da52e5d49 100755 --- a/tools/run_tests/run_microbenchmark.py +++ b/tools/run_tests/run_microbenchmark.py @@ -170,12 +170,12 @@ def collect_perf(bm_name, args): jobset.run(profile_analysis, maxjobs=multiprocessing.cpu_count()) jobset.run(cleanup, maxjobs=multiprocessing.cpu_count()) -def run_summary(cfg): +def run_summary(bm_name, cfg, base_json_name): subprocess.check_call( ['make', bm_name, 'CONFIG=%s' % cfg, '-j', '%d' % multiprocessing.cpu_count()]) cmd = ['bins/%s/%s' % (cfg, bm_name), - '--benchmark_out=out.%s.json' % cfg, + '--benchmark_out=%s.%s.json' % (base_json_name, cfg), '--benchmark_out_format=json'] if args.summary_time is not None: cmd += ['--benchmark_min_time=%d' % args.summary_time] @@ -183,9 +183,9 @@ def run_summary(cfg): def collect_summary(bm_name, args): heading('Summary: %s [no counters]' % bm_name) - text(run_summary('opt')) + text(run_summary(bm_name, 'opt', 'out')) heading('Summary: %s [with counters]' % bm_name) - text(run_summary('counters')) + text(run_summary(bm_name, 'counters', 'out')) if args.bigquery_upload: with open('out.csv', 'w') as f: f.write(subprocess.check_output(['tools/profiling/microbenchmarks/bm2bq.py', 'out.counters.json', 'out.opt.json'])) @@ -200,7 +200,7 @@ collectors = { argp = argparse.ArgumentParser(description='Collect data from microbenchmarks') argp.add_argument('-c', '--collect', choices=sorted(collectors.keys()), - nargs='+', + nargs='*', default=sorted(collectors.keys()), help='Which collectors should be run against each benchmark') argp.add_argument('-b', '--benchmarks', @@ -214,6 +214,10 @@ argp.add_argument('-b', '--benchmarks', nargs='+', type=str, help='Which microbenchmarks should be run') +argp.add_argument('--diff_perf', + default=None, + type=str, + help='Diff microbenchmarks against this git revision') argp.add_argument('--bigquery_upload', default=False, action='store_const', @@ -228,6 +232,26 @@ args = argp.parse_args() for bm_name in args.benchmarks: for collect in args.collect: collectors[collect](bm_name, args) +if args.diff_perf: + for bm_name in args.benchmarks: + run_summary(bm_name, 'opt', '%s.new' % bm_name) + where_am_i = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD']).strip() + subprocess.check_call(['git', 'checkout', args.diff_perf]) + comparables = [] + subprocess.check_call(['make', 'clean']) + try: + for bm_name in args.benchmarks: + try: + run_summary(bm_name, 'opt', '%s.old' % bm_name) + comparables.append(bm_name) + except subprocess.CalledProcessError, e: + pass + finally: + subprocess.check_call(['git', 'checkout', where_am_i]) + for bm_name in comparables: + subprocess.check_call(['third_party/benchmark/tools/compare_bench.py', + '%s.new.opt.json' % bm_name, + '%s.old.opt.json' % bm_name]) index_html += "</body>\n</html>\n" with open('reports/index.html', 'w') as f: |