From 46e0453b7e63c70af6954f591eac65086b8784e2 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 18 Mar 2016 01:45:30 +0100 Subject: [PATCH 001/279] Adding a few curly braces. --- src/core/json/json_reader.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/core/json/json_reader.c b/src/core/json/json_reader.c index 9a97826287e..7e718939044 100644 --- a/src/core/json/json_reader.c +++ b/src/core/json/json_reader.c @@ -171,8 +171,9 @@ grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader) { switch (reader->state) { case GRPC_JSON_STATE_OBJECT_KEY_STRING: case GRPC_JSON_STATE_VALUE_STRING: - if (reader->unicode_high_surrogate != 0) + if (reader->unicode_high_surrogate != 0) { return GRPC_JSON_PARSE_ERROR; + } json_reader_string_add_char(reader, c); break; @@ -280,8 +281,9 @@ grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader) { break; case GRPC_JSON_STATE_OBJECT_KEY_STRING: - if (reader->unicode_high_surrogate != 0) + if (reader->unicode_high_surrogate != 0) { return GRPC_JSON_PARSE_ERROR; + } if (c == '"') { reader->state = GRPC_JSON_STATE_OBJECT_KEY_END; json_reader_set_key(reader); @@ -293,8 +295,9 @@ grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader) { break; case GRPC_JSON_STATE_VALUE_STRING: - if (reader->unicode_high_surrogate != 0) + if (reader->unicode_high_surrogate != 0) { return GRPC_JSON_PARSE_ERROR; + } if (c == '"') { reader->state = GRPC_JSON_STATE_VALUE_END; json_reader_set_string(reader); @@ -374,8 +377,9 @@ grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader) { } else { reader->state = GRPC_JSON_STATE_VALUE_STRING; } - if (reader->unicode_high_surrogate && c != 'u') + if (reader->unicode_high_surrogate && c != 'u') { return GRPC_JSON_PARSE_ERROR; + } switch (c) { case '"': case '/': From 23df75a97054822e1a7f89ab5a0601d6bd4b3aa6 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 18 Mar 2016 08:27:13 +0100 Subject: [PATCH 002/279] Copyrights. --- src/core/json/json_reader.c | 2 +- test/core/json/json_test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/json/json_reader.c b/src/core/json/json_reader.c index 7e718939044..aa654dfc0e2 100644 --- a/src/core/json/json_reader.c +++ b/src/core/json/json_reader.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/json/json_test.c b/test/core/json/json_test.c index 035265a6be5..cbd96a75fe2 100644 --- a/test/core/json/json_test.c +++ b/test/core/json/json_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without From dbd03b5e2d97f869089b2165edd2c419101b1c83 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 31 May 2016 13:00:33 -0700 Subject: [PATCH 003/279] Make client_channels be across all clients, not per-client --- test/cpp/qps/driver.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 04b2b453f9e..da47a985b8c 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -306,6 +306,7 @@ std::unique_ptr RunScenario( // clients is array rather than std::vector to avoid gcc-4.4 issues // where class contained in std::vector must have a copy constructor auto* clients = new ClientData[num_clients]; + size_t channels_allocated = 0; for (size_t i = 0; i < num_clients; i++) { const auto& worker = workers[i + num_servers]; gpr_log(GPR_INFO, "Starting client on %s (worker #%d)", worker.c_str(), @@ -341,6 +342,13 @@ std::unique_ptr RunScenario( } } + size_t num_channels = + (i == num_clients - 1) + ? channels_allocated - client_config.client_channels() + : client_config.client_channels() / num_clients; + channels_allocated += num_channels; + per_client_config.set_client_channels(num_channels); + ClientArgs args; *args.mutable_setup() = per_client_config; clients[i].stream = From 1adb13143f21a54a3e3d7018d0db4d15d78c1adc Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 31 May 2016 13:04:32 -0700 Subject: [PATCH 004/279] Add comment --- test/cpp/qps/driver.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index da47a985b8c..147c540840e 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -342,6 +342,8 @@ std::unique_ptr RunScenario( } } + // Reduce channel count so that total channels specified is held regardless + // of the number of clients available size_t num_channels = (i == num_clients - 1) ? channels_allocated - client_config.client_channels() From d4aa7cf5a502462debd4a42f0daf4c018c824263 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 31 May 2016 13:59:25 -0700 Subject: [PATCH 005/279] Fix negation --- test/cpp/qps/driver.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 147c540840e..298087dd36f 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -346,9 +346,10 @@ std::unique_ptr RunScenario( // of the number of clients available size_t num_channels = (i == num_clients - 1) - ? channels_allocated - client_config.client_channels() + ? client_config.client_channels() - channels_allocated : client_config.client_channels() / num_clients; channels_allocated += num_channels; + gpr_log(GPR_DEBUG, "Client %d gets %d channels", i, num_channels); per_client_config.set_client_channels(num_channels); ClientArgs args; From e1ad41a0ff89ed215458441b4ee08e8d4ecd9670 Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Thu, 2 Jun 2016 14:16:05 -0700 Subject: [PATCH 006/279] change Metric->Resource, simplify Resource definition --- src/core/ext/census/gen/census.pb.c | 38 +++++------ src/core/ext/census/gen/census.pb.h | 98 +++++++++++++---------------- src/proto/census/census.proto | 62 +++++++++--------- 3 files changed, 86 insertions(+), 112 deletions(-) diff --git a/src/core/ext/census/gen/census.pb.c b/src/core/ext/census/gen/census.pb.c index d614636c908..c73c2c9b7cc 100644 --- a/src/core/ext/census/gen/census.pb.c +++ b/src/core/ext/census/gen/census.pb.c @@ -53,23 +53,17 @@ const pb_field_t google_census_Timestamp_fields[3] = { PB_LAST_FIELD }; -const pb_field_t google_census_Metric_fields[5] = { - PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, google_census_Metric, name, name, 0), - PB_FIELD( 2, STRING , OPTIONAL, CALLBACK, OTHER, google_census_Metric, description, name, 0), - PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_Metric, unit, description, &google_census_Metric_MeasurementUnit_fields), - PB_FIELD( 4, INT32 , OPTIONAL, STATIC , OTHER, google_census_Metric, id, unit, 0), +const pb_field_t google_census_Resource_fields[4] = { + PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, google_census_Resource, name, name, 0), + PB_FIELD( 2, STRING , OPTIONAL, CALLBACK, OTHER, google_census_Resource, description, name, 0), + PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_Resource, unit, description, &google_census_Resource_MeasurementUnit_fields), PB_LAST_FIELD }; -const pb_field_t google_census_Metric_BasicUnit_fields[2] = { - PB_FIELD( 1, UENUM , OPTIONAL, STATIC , FIRST, google_census_Metric_BasicUnit, type, type, 0), - PB_LAST_FIELD -}; - -const pb_field_t google_census_Metric_MeasurementUnit_fields[4] = { - PB_FIELD( 1, INT32 , OPTIONAL, STATIC , FIRST, google_census_Metric_MeasurementUnit, prefix, prefix, 0), - PB_FIELD( 2, MESSAGE , REPEATED, CALLBACK, OTHER, google_census_Metric_MeasurementUnit, numerator, prefix, &google_census_Metric_BasicUnit_fields), - PB_FIELD( 3, MESSAGE , REPEATED, CALLBACK, OTHER, google_census_Metric_MeasurementUnit, denominator, numerator, &google_census_Metric_BasicUnit_fields), +const pb_field_t google_census_Resource_MeasurementUnit_fields[4] = { + PB_FIELD( 1, INT32 , OPTIONAL, STATIC , FIRST, google_census_Resource_MeasurementUnit, prefix, prefix, 0), + PB_FIELD( 2, UENUM , REPEATED, CALLBACK, OTHER, google_census_Resource_MeasurementUnit, numerator, prefix, 0), + PB_FIELD( 3, UENUM , REPEATED, CALLBACK, OTHER, google_census_Resource_MeasurementUnit, denominator, numerator, 0), PB_LAST_FIELD }; @@ -124,8 +118,8 @@ const pb_field_t google_census_Tag_fields[3] = { const pb_field_t google_census_View_fields[6] = { PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, google_census_View, name, name, 0), PB_FIELD( 2, STRING , OPTIONAL, CALLBACK, OTHER, google_census_View, description, name, 0), - PB_FIELD( 3, INT32 , OPTIONAL, STATIC , OTHER, google_census_View, metric_id, description, 0), - PB_FIELD( 4, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_View, aggregation, metric_id, &google_census_AggregationDescriptor_fields), + PB_FIELD( 3, STRING , OPTIONAL, CALLBACK, OTHER, google_census_View, resource_name, description, 0), + PB_FIELD( 4, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_View, aggregation, resource_name, &google_census_AggregationDescriptor_fields), PB_FIELD( 5, STRING , REPEATED, CALLBACK, OTHER, google_census_View, tag_key, aggregation, 0), PB_LAST_FIELD }; @@ -139,10 +133,10 @@ const pb_field_t google_census_Aggregation_fields[6] = { PB_LAST_FIELD }; -const pb_field_t google_census_ViewAggregations_fields[4] = { - PB_FIELD( 1, MESSAGE , REPEATED, CALLBACK, FIRST, google_census_ViewAggregations, aggregation, aggregation, &google_census_Aggregation_fields), - PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_ViewAggregations, start, aggregation, &google_census_Timestamp_fields), - PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_ViewAggregations, end, start, &google_census_Timestamp_fields), +const pb_field_t google_census_Metric_fields[4] = { + PB_FIELD( 1, MESSAGE , REPEATED, CALLBACK, FIRST, google_census_Metric, aggregation, aggregation, &google_census_Aggregation_fields), + PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_Metric, start, aggregation, &google_census_Timestamp_fields), + PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_Metric, end, start, &google_census_Timestamp_fields), PB_LAST_FIELD }; @@ -156,7 +150,7 @@ const pb_field_t google_census_ViewAggregations_fields[4] = { * numbers or field sizes that are larger than what can fit in 8 or 16 bit * field descriptors. */ -PB_STATIC_ASSERT((pb_membersize(google_census_Metric, unit) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Metric, unit) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Distribution, range) < 65536 && pb_membersize(google_census_IntervalStats, window) < 65536 && pb_membersize(google_census_IntervalStats_Window, window_size) < 65536 && pb_membersize(google_census_View, aggregation) < 65536 && pb_membersize(google_census_Aggregation, data.distribution) < 65536 && pb_membersize(google_census_Aggregation, data.interval_stats) < 65536 && pb_membersize(google_census_Metric, unit) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Metric, unit) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Distribution, range) < 65536 && pb_membersize(google_census_IntervalStats, window) < 65536 && pb_membersize(google_census_IntervalStats_Window, window_size) < 65536 && pb_membersize(google_census_View, aggregation) < 65536 && pb_membersize(google_census_Aggregation, data.distribution) < 65536 && pb_membersize(google_census_Aggregation, data.interval_stats) < 65536 && pb_membersize(google_census_Aggregation, tag) < 65536 && pb_membersize(google_census_ViewAggregations, aggregation) < 65536 && pb_membersize(google_census_ViewAggregations, start) < 65536 && pb_membersize(google_census_ViewAggregations, end) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_census_Duration_google_census_Timestamp_google_census_Metric_google_census_Metric_BasicUnit_google_census_Metric_MeasurementUnit_google_census_AggregationDescriptor_google_census_AggregationDescriptor_BucketBoundaries_google_census_AggregationDescriptor_IntervalBoundaries_google_census_Distribution_google_census_Distribution_Range_google_census_IntervalStats_google_census_IntervalStats_Window_google_census_Tag_google_census_View_google_census_Aggregation_google_census_ViewAggregations) +PB_STATIC_ASSERT((pb_membersize(google_census_Resource, unit) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Resource, unit) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Distribution, range) < 65536 && pb_membersize(google_census_IntervalStats, window) < 65536 && pb_membersize(google_census_IntervalStats_Window, window_size) < 65536 && pb_membersize(google_census_View, aggregation) < 65536 && pb_membersize(google_census_Aggregation, data.distribution) < 65536 && pb_membersize(google_census_Aggregation, data.interval_stats) < 65536 && pb_membersize(google_census_Resource, unit) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Resource, unit) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Distribution, range) < 65536 && pb_membersize(google_census_IntervalStats, window) < 65536 && pb_membersize(google_census_IntervalStats_Window, window_size) < 65536 && pb_membersize(google_census_View, aggregation) < 65536 && pb_membersize(google_census_Aggregation, data.distribution) < 65536 && pb_membersize(google_census_Aggregation, data.interval_stats) < 65536 && pb_membersize(google_census_Aggregation, tag) < 65536 && pb_membersize(google_census_Metric, aggregation) < 65536 && pb_membersize(google_census_Metric, start) < 65536 && pb_membersize(google_census_Metric, end) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_census_Duration_google_census_Timestamp_google_census_Resource_google_census_Resource_MeasurementUnit_google_census_AggregationDescriptor_google_census_AggregationDescriptor_BucketBoundaries_google_census_AggregationDescriptor_IntervalBoundaries_google_census_Distribution_google_census_Distribution_Range_google_census_IntervalStats_google_census_IntervalStats_Window_google_census_Tag_google_census_View_google_census_Aggregation_google_census_Metric) #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) @@ -167,7 +161,7 @@ PB_STATIC_ASSERT((pb_membersize(google_census_Metric, unit) < 65536 && pb_member * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -PB_STATIC_ASSERT((pb_membersize(google_census_Metric, unit) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Metric, unit) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Distribution, range) < 256 && pb_membersize(google_census_IntervalStats, window) < 256 && pb_membersize(google_census_IntervalStats_Window, window_size) < 256 && pb_membersize(google_census_View, aggregation) < 256 && pb_membersize(google_census_Aggregation, data.distribution) < 256 && pb_membersize(google_census_Aggregation, data.interval_stats) < 256 && pb_membersize(google_census_Metric, unit) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Metric, unit) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Distribution, range) < 256 && pb_membersize(google_census_IntervalStats, window) < 256 && pb_membersize(google_census_IntervalStats_Window, window_size) < 256 && pb_membersize(google_census_View, aggregation) < 256 && pb_membersize(google_census_Aggregation, data.distribution) < 256 && pb_membersize(google_census_Aggregation, data.interval_stats) < 256 && pb_membersize(google_census_Aggregation, tag) < 256 && pb_membersize(google_census_ViewAggregations, aggregation) < 256 && pb_membersize(google_census_ViewAggregations, start) < 256 && pb_membersize(google_census_ViewAggregations, end) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_census_Duration_google_census_Timestamp_google_census_Metric_google_census_Metric_BasicUnit_google_census_Metric_MeasurementUnit_google_census_AggregationDescriptor_google_census_AggregationDescriptor_BucketBoundaries_google_census_AggregationDescriptor_IntervalBoundaries_google_census_Distribution_google_census_Distribution_Range_google_census_IntervalStats_google_census_IntervalStats_Window_google_census_Tag_google_census_View_google_census_Aggregation_google_census_ViewAggregations) +PB_STATIC_ASSERT((pb_membersize(google_census_Resource, unit) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Resource, unit) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Distribution, range) < 256 && pb_membersize(google_census_IntervalStats, window) < 256 && pb_membersize(google_census_IntervalStats_Window, window_size) < 256 && pb_membersize(google_census_View, aggregation) < 256 && pb_membersize(google_census_Aggregation, data.distribution) < 256 && pb_membersize(google_census_Aggregation, data.interval_stats) < 256 && pb_membersize(google_census_Resource, unit) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Resource, unit) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Distribution, range) < 256 && pb_membersize(google_census_IntervalStats, window) < 256 && pb_membersize(google_census_IntervalStats_Window, window_size) < 256 && pb_membersize(google_census_View, aggregation) < 256 && pb_membersize(google_census_Aggregation, data.distribution) < 256 && pb_membersize(google_census_Aggregation, data.interval_stats) < 256 && pb_membersize(google_census_Aggregation, tag) < 256 && pb_membersize(google_census_Metric, aggregation) < 256 && pb_membersize(google_census_Metric, start) < 256 && pb_membersize(google_census_Metric, end) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_census_Duration_google_census_Timestamp_google_census_Resource_google_census_Resource_MeasurementUnit_google_census_AggregationDescriptor_google_census_AggregationDescriptor_BucketBoundaries_google_census_AggregationDescriptor_IntervalBoundaries_google_census_Distribution_google_census_Distribution_Range_google_census_IntervalStats_google_census_IntervalStats_Window_google_census_Tag_google_census_View_google_census_Aggregation_google_census_Metric) #endif diff --git a/src/core/ext/census/gen/census.pb.h b/src/core/ext/census/gen/census.pb.h index d040fe29e74..dfb53948204 100644 --- a/src/core/ext/census/gen/census.pb.h +++ b/src/core/ext/census/gen/census.pb.h @@ -45,14 +45,14 @@ extern "C" { #endif /* Enum definitions */ -typedef enum _google_census_Metric_BasicUnit_Measure { - google_census_Metric_BasicUnit_Measure_UNKNOWN = 0, - google_census_Metric_BasicUnit_Measure_BITS = 1, - google_census_Metric_BasicUnit_Measure_BYTES = 2, - google_census_Metric_BasicUnit_Measure_SECS = 3, - google_census_Metric_BasicUnit_Measure_CORES = 4, - google_census_Metric_BasicUnit_Measure_MAX_UNITS = 5 -} google_census_Metric_BasicUnit_Measure; +typedef enum _google_census_Resource_BasicUnit { + google_census_Resource_BasicUnit_UNKNOWN = 0, + google_census_Resource_BasicUnit_BITS = 1, + google_census_Resource_BasicUnit_BYTES = 2, + google_census_Resource_BasicUnit_SECS = 3, + google_census_Resource_BasicUnit_CORES = 4, + google_census_Resource_BasicUnit_MAX_UNITS = 5 +} google_census_Resource_BasicUnit; /* Struct definitions */ typedef struct _google_census_AggregationDescriptor_BucketBoundaries { @@ -89,17 +89,12 @@ typedef struct _google_census_Duration { int32_t nanos; } google_census_Duration; -typedef struct _google_census_Metric_BasicUnit { - bool has_type; - google_census_Metric_BasicUnit_Measure type; -} google_census_Metric_BasicUnit; - -typedef struct _google_census_Metric_MeasurementUnit { +typedef struct _google_census_Resource_MeasurementUnit { bool has_prefix; int32_t prefix; pb_callback_t numerator; pb_callback_t denominator; -} google_census_Metric_MeasurementUnit; +} google_census_Resource_MeasurementUnit; typedef struct _google_census_Tag { bool has_key; @@ -135,32 +130,29 @@ typedef struct _google_census_IntervalStats_Window { } google_census_IntervalStats_Window; typedef struct _google_census_Metric { + pb_callback_t aggregation; + bool has_start; + google_census_Timestamp start; + bool has_end; + google_census_Timestamp end; +} google_census_Metric; + +typedef struct _google_census_Resource { pb_callback_t name; pb_callback_t description; bool has_unit; - google_census_Metric_MeasurementUnit unit; - bool has_id; - int32_t id; -} google_census_Metric; + google_census_Resource_MeasurementUnit unit; +} google_census_Resource; typedef struct _google_census_View { pb_callback_t name; pb_callback_t description; - bool has_metric_id; - int32_t metric_id; + pb_callback_t resource_name; bool has_aggregation; google_census_AggregationDescriptor aggregation; pb_callback_t tag_key; } google_census_View; -typedef struct _google_census_ViewAggregations { - pb_callback_t aggregation; - bool has_start; - google_census_Timestamp start; - bool has_end; - google_census_Timestamp end; -} google_census_ViewAggregations; - typedef struct _google_census_Aggregation { pb_callback_t name; pb_callback_t description; @@ -177,9 +169,8 @@ typedef struct _google_census_Aggregation { /* Initializer values for message structs */ #define google_census_Duration_init_default {false, 0, false, 0} #define google_census_Timestamp_init_default {false, 0, false, 0} -#define google_census_Metric_init_default {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Metric_MeasurementUnit_init_default, false, 0} -#define google_census_Metric_BasicUnit_init_default {false, (google_census_Metric_BasicUnit_Measure)0} -#define google_census_Metric_MeasurementUnit_init_default {false, 0, {{NULL}, NULL}, {{NULL}, NULL}} +#define google_census_Resource_init_default {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Resource_MeasurementUnit_init_default} +#define google_census_Resource_MeasurementUnit_init_default {false, 0, {{NULL}, NULL}, {{NULL}, NULL}} #define google_census_AggregationDescriptor_init_default {0, {google_census_AggregationDescriptor_BucketBoundaries_init_default}} #define google_census_AggregationDescriptor_BucketBoundaries_init_default {{{NULL}, NULL}} #define google_census_AggregationDescriptor_IntervalBoundaries_init_default {{{NULL}, NULL}} @@ -188,14 +179,13 @@ typedef struct _google_census_Aggregation { #define google_census_IntervalStats_init_default {{{NULL}, NULL}} #define google_census_IntervalStats_Window_init_default {false, google_census_Duration_init_default, false, 0, false, 0} #define google_census_Tag_init_default {false, "", false, ""} -#define google_census_View_init_default {{{NULL}, NULL}, {{NULL}, NULL}, false, 0, false, google_census_AggregationDescriptor_init_default, {{NULL}, NULL}} +#define google_census_View_init_default {{{NULL}, NULL}, {{NULL}, NULL}, {{NULL}, NULL}, false, google_census_AggregationDescriptor_init_default, {{NULL}, NULL}} #define google_census_Aggregation_init_default {{{NULL}, NULL}, {{NULL}, NULL}, 0, {google_census_Distribution_init_default}, {{NULL}, NULL}} -#define google_census_ViewAggregations_init_default {{{NULL}, NULL}, false, google_census_Timestamp_init_default, false, google_census_Timestamp_init_default} +#define google_census_Metric_init_default {{{NULL}, NULL}, false, google_census_Timestamp_init_default, false, google_census_Timestamp_init_default} #define google_census_Duration_init_zero {false, 0, false, 0} #define google_census_Timestamp_init_zero {false, 0, false, 0} -#define google_census_Metric_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Metric_MeasurementUnit_init_zero, false, 0} -#define google_census_Metric_BasicUnit_init_zero {false, (google_census_Metric_BasicUnit_Measure)0} -#define google_census_Metric_MeasurementUnit_init_zero {false, 0, {{NULL}, NULL}, {{NULL}, NULL}} +#define google_census_Resource_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Resource_MeasurementUnit_init_zero} +#define google_census_Resource_MeasurementUnit_init_zero {false, 0, {{NULL}, NULL}, {{NULL}, NULL}} #define google_census_AggregationDescriptor_init_zero {0, {google_census_AggregationDescriptor_BucketBoundaries_init_zero}} #define google_census_AggregationDescriptor_BucketBoundaries_init_zero {{{NULL}, NULL}} #define google_census_AggregationDescriptor_IntervalBoundaries_init_zero {{{NULL}, NULL}} @@ -204,9 +194,9 @@ typedef struct _google_census_Aggregation { #define google_census_IntervalStats_init_zero {{{NULL}, NULL}} #define google_census_IntervalStats_Window_init_zero {false, google_census_Duration_init_zero, false, 0, false, 0} #define google_census_Tag_init_zero {false, "", false, ""} -#define google_census_View_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, false, 0, false, google_census_AggregationDescriptor_init_zero, {{NULL}, NULL}} +#define google_census_View_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, {{NULL}, NULL}, false, google_census_AggregationDescriptor_init_zero, {{NULL}, NULL}} #define google_census_Aggregation_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, 0, {google_census_Distribution_init_zero}, {{NULL}, NULL}} -#define google_census_ViewAggregations_init_zero {{{NULL}, NULL}, false, google_census_Timestamp_init_zero, false, google_census_Timestamp_init_zero} +#define google_census_Metric_init_zero {{{NULL}, NULL}, false, google_census_Timestamp_init_zero, false, google_census_Timestamp_init_zero} /* Field tags (for use in manual encoding/decoding) */ #define google_census_AggregationDescriptor_BucketBoundaries_bounds_tag 1 @@ -219,10 +209,9 @@ typedef struct _google_census_Aggregation { #define google_census_Distribution_Range_max_tag 2 #define google_census_Duration_seconds_tag 1 #define google_census_Duration_nanos_tag 2 -#define google_census_Metric_BasicUnit_type_tag 1 -#define google_census_Metric_MeasurementUnit_prefix_tag 1 -#define google_census_Metric_MeasurementUnit_numerator_tag 2 -#define google_census_Metric_MeasurementUnit_denominator_tag 3 +#define google_census_Resource_MeasurementUnit_prefix_tag 1 +#define google_census_Resource_MeasurementUnit_numerator_tag 2 +#define google_census_Resource_MeasurementUnit_denominator_tag 3 #define google_census_Tag_key_tag 1 #define google_census_Tag_value_tag 2 #define google_census_Timestamp_seconds_tag 1 @@ -234,18 +223,17 @@ typedef struct _google_census_Aggregation { #define google_census_IntervalStats_Window_window_size_tag 1 #define google_census_IntervalStats_Window_count_tag 2 #define google_census_IntervalStats_Window_mean_tag 3 -#define google_census_Metric_name_tag 1 -#define google_census_Metric_description_tag 2 -#define google_census_Metric_unit_tag 3 -#define google_census_Metric_id_tag 4 +#define google_census_Metric_aggregation_tag 1 +#define google_census_Metric_start_tag 2 +#define google_census_Metric_end_tag 3 +#define google_census_Resource_name_tag 1 +#define google_census_Resource_description_tag 2 +#define google_census_Resource_unit_tag 3 #define google_census_View_name_tag 1 #define google_census_View_description_tag 2 -#define google_census_View_metric_id_tag 3 +#define google_census_View_resource_name_tag 3 #define google_census_View_aggregation_tag 4 #define google_census_View_tag_key_tag 5 -#define google_census_ViewAggregations_aggregation_tag 1 -#define google_census_ViewAggregations_start_tag 2 -#define google_census_ViewAggregations_end_tag 3 #define google_census_Aggregation_distribution_tag 3 #define google_census_Aggregation_interval_stats_tag 4 @@ -256,9 +244,8 @@ typedef struct _google_census_Aggregation { /* Struct field encoding specification for nanopb */ extern const pb_field_t google_census_Duration_fields[3]; extern const pb_field_t google_census_Timestamp_fields[3]; -extern const pb_field_t google_census_Metric_fields[5]; -extern const pb_field_t google_census_Metric_BasicUnit_fields[2]; -extern const pb_field_t google_census_Metric_MeasurementUnit_fields[4]; +extern const pb_field_t google_census_Resource_fields[4]; +extern const pb_field_t google_census_Resource_MeasurementUnit_fields[4]; extern const pb_field_t google_census_AggregationDescriptor_fields[3]; extern const pb_field_t google_census_AggregationDescriptor_BucketBoundaries_fields[2]; extern const pb_field_t google_census_AggregationDescriptor_IntervalBoundaries_fields[2]; @@ -269,12 +256,11 @@ extern const pb_field_t google_census_IntervalStats_Window_fields[4]; extern const pb_field_t google_census_Tag_fields[3]; extern const pb_field_t google_census_View_fields[6]; extern const pb_field_t google_census_Aggregation_fields[6]; -extern const pb_field_t google_census_ViewAggregations_fields[4]; +extern const pb_field_t google_census_Metric_fields[4]; /* Maximum encoded size of messages (where known) */ #define google_census_Duration_size 22 #define google_census_Timestamp_size 22 -#define google_census_Metric_BasicUnit_size 2 #define google_census_Distribution_Range_size 18 #define google_census_IntervalStats_Window_size 44 #define google_census_Tag_size 516 diff --git a/src/proto/census/census.proto b/src/proto/census/census.proto index c869d851ff1..56c291ff17c 100644 --- a/src/proto/census/census.proto +++ b/src/proto/census/census.proto @@ -33,12 +33,12 @@ package google.census; // All the census protos. // -// Nomenclature note: capitalized names below (like Metric) are protos. +// Nomenclature note: capitalized names below (like Resource) are protos. // -// Census lets you define a Metric - something which can be measured, like the +// Census lets you define a Resource - something which can be measured, like the // latency of an RPC, the number of CPU cycles spent on an operation, or // anything else you care to measure. You can record individual instances of -// measurements (a double value) for every metric of interest. These +// measurements (a double value) for every Resource of interest. These // individual measurements are aggregated together into an Aggregation. There // are two Aggregation types available: Distribution (describes the // distribution of all measurements, possibly with a histogram) and @@ -47,8 +47,8 @@ package google.census; // // You can define how your stats are broken down by Tag values and which // Aggregations to use through a View. The corresponding combination of -// Metric/View/Aggregation which is available to census clients is called a -// ViewAggregation. +// Resource/View/Aggregation which is available to census clients is called a +// Metric. // The following two types are copied from @@ -85,26 +85,23 @@ message Timestamp { int32 nanos = 2; } -// Describes a metric -message Metric { - // name of metric, e.g. rpc_latency, cpu. +// Describes a Resource. +message Resource { + // name of resource, e.g. rpc_latency, cpu. Must be unique. string name = 1; - // More detailed description of the metric, used in documentation. + // More detailed description of the resource, used in documentation. string description = 2; // Fundamental units of measurement supported by Census // TODO(aveitch): expand this to include other S.I. units? - message BasicUnit { - enum Measure { - UNKNOWN = 0; - BITS = 1; - BYTES = 2; - SECS = 3; - CORES = 4; - MAX_UNITS = 5; - } - Measure type = 1; + enum BasicUnit { + UNKNOWN = 0; + BITS = 1; + BYTES = 2; + SECS = 3; + CORES = 4; + MAX_UNITS = 5; } // MeasurementUnit lets you build compound units of the form @@ -141,14 +138,11 @@ message Metric { repeated BasicUnit denominator = 3; } - // The units in which the Metric value is reported. + // The units in which Resource values are measured. MeasurementUnit unit = 3; - - // Metrics will be assigned an ID when registered. Invalid if <= 0. - int32 id = 4; } -// An Aggregation summarizes a series of individual Metric measurements, an +// An Aggregation summarizes a series of individual Resource measurements, an // AggregationDescriptor describes an Aggregation. message AggregationDescriptor { // At most one set of options. If neither option is set, a default type @@ -251,7 +245,7 @@ message IntervalStats { double mean = 3; } - // Full set of windows for this metric. + // Full set of windows for this aggregation. repeated Window window = 1; } @@ -264,24 +258,24 @@ message Tag { // A View specifies an Aggregation and a set of tag keys. The Aggregation will // be broken down by the unique set of matching tag values for each measurement. message View { - // Name of view. + // Name of view. Must be unique. string name = 1; // More detailed description, for documentation purposes. string description = 2; - // ID of Metric to associate with this View. - int32 metric_id = 3; + // Name of Resource to be broken down for this view. + string resource_name = 3; // Aggregation type to associate with this View. AggregationDescriptor aggregation = 4; - // Tag keys to match with a given Metric. If no keys are specified, then all - // stats for the Metric are recorded. Keys must be unique. + // Tag keys to match with a given Resource measurement. If no keys are + // specified, then all stats are recorded. Keys must be unique. repeated string tag_key = 5; } -// An Aggregation summarizes a series of individual Metric measures. +// An Aggregation summarizes a series of individual Resource measurements. message Aggregation { // Name of this aggregation. string name = 1; @@ -299,13 +293,13 @@ message Aggregation { repeated Tag tag = 5; } -// A ViewAggregations represents all the Aggregations for a particular view. -message ViewAggregations { +// A Metric represents all the Aggregations for a particular view. +message Metric { // Aggregations - each will have a unique set of tag values for the tag_keys // associated with the corresponding View. repeated Aggregation aggregation = 1; - // Start and end timestamps over which the value was accumulated. These + // Start and end timestamps over which the metric was accumulated. These // values are not relevant/defined for IntervalStats aggregations, which are // always accumulated over a fixed time period. Timestamp start = 2; From 4aaba75a822c6dde718d7fe646f7671b4f64d8a0 Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Thu, 2 Jun 2016 17:11:46 -0700 Subject: [PATCH 007/279] initial implementation of resource handling --- BUILD | 12 + Makefile | 40 +++ binding.gyp | 2 + build.yaml | 14 + config.m4 | 2 + gRPC.podspec | 6 + grpc.def | 11 +- grpc.gemspec | 4 + include/grpc/census.h | 136 +++------- package.xml | 4 + src/core/ext/census/base_resources.c | 148 ++++++++++ src/core/ext/census/base_resources.h | 39 +++ src/core/ext/census/initialize.c | 20 +- src/core/ext/census/placeholders.c | 45 ---- src/core/ext/census/resource.c | 255 ++++++++++++++++++ src/core/ext/census/resource.h | 42 +++ .../grpcio/grpc/_cython/imports.generated.c | 22 +- .../grpcio/grpc/_cython/imports.generated.h | 33 +-- src/python/grpcio/grpc_core_dependencies.py | 2 + src/ruby/ext/grpc/rb_grpc_imports.generated.c | 22 +- src/ruby/ext/grpc/rb_grpc_imports.generated.h | 33 +-- test/core/census/README | 7 + test/core/census/data/resource_empty_name.pb | 1 + test/core/census/data/resource_empty_name.txt | 5 + test/core/census/data/resource_full.pb | 2 + test/core/census/data/resource_full.txt | 9 + .../core/census/data/resource_minimal_good.pb | 2 + .../census/data/resource_minimal_good.txt | 5 + test/core/census/data/resource_no_name.pb | 1 + test/core/census/data/resource_no_name.txt | 4 + .../core/census/data/resource_no_numerator.pb | 2 + .../census/data/resource_no_numerator.txt | 6 + test/core/census/data/resource_no_unit.pb | 2 + test/core/census/data/resource_no_unit.txt | 2 + test/core/census/resource_test.c | 157 +++++++++++ tools/doxygen/Doxyfile.core.internal | 4 + tools/run_tests/sources_and_headers.json | 22 ++ tools/run_tests/tests.json | 21 ++ vsprojects/buildtests_c.sln | 27 ++ vsprojects/vcxproj/grpc/grpc.vcxproj | 6 + vsprojects/vcxproj/grpc/grpc.vcxproj.filters | 12 + .../grpc_unsecure/grpc_unsecure.vcxproj | 6 + .../grpc_unsecure.vcxproj.filters | 12 + .../census_resource_test.vcxproj | 199 ++++++++++++++ .../census_resource_test.vcxproj.filters | 21 ++ 45 files changed, 1194 insertions(+), 233 deletions(-) create mode 100644 src/core/ext/census/base_resources.c create mode 100644 src/core/ext/census/base_resources.h create mode 100644 src/core/ext/census/resource.c create mode 100644 src/core/ext/census/resource.h create mode 100644 test/core/census/README create mode 100644 test/core/census/data/resource_empty_name.pb create mode 100644 test/core/census/data/resource_empty_name.txt create mode 100644 test/core/census/data/resource_full.pb create mode 100644 test/core/census/data/resource_full.txt create mode 100644 test/core/census/data/resource_minimal_good.pb create mode 100644 test/core/census/data/resource_minimal_good.txt create mode 100644 test/core/census/data/resource_no_name.pb create mode 100644 test/core/census/data/resource_no_name.txt create mode 100644 test/core/census/data/resource_no_numerator.pb create mode 100644 test/core/census/data/resource_no_numerator.txt create mode 100644 test/core/census/data/resource_no_unit.pb create mode 100644 test/core/census/data/resource_no_unit.txt create mode 100644 test/core/census/resource_test.c create mode 100644 vsprojects/vcxproj/test/census_resource_test/census_resource_test.vcxproj create mode 100644 vsprojects/vcxproj/test/census_resource_test/census_resource_test.vcxproj.filters diff --git a/BUILD b/BUILD index 024a5182ce5..b3b75ed0bb8 100644 --- a/BUILD +++ b/BUILD @@ -299,11 +299,13 @@ cc_library( "src/core/ext/lb_policy/grpclb/load_balancer_api.h", "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h", "src/core/ext/census/aggregation.h", + "src/core/ext/census/base_resources.h", "src/core/ext/census/census_interface.h", "src/core/ext/census/census_rpc_stats.h", "src/core/ext/census/gen/census.pb.h", "src/core/ext/census/grpc_filter.h", "src/core/ext/census/mlog.h", + "src/core/ext/census/resource.h", "src/core/ext/census/rpc_metric_id.h", "src/core/lib/surface/init.c", "src/core/lib/channel/channel_args.c", @@ -469,6 +471,7 @@ cc_library( "src/core/ext/lb_policy/round_robin/round_robin.c", "src/core/ext/resolver/dns/native/dns_resolver.c", "src/core/ext/resolver/sockaddr/sockaddr_resolver.c", + "src/core/ext/census/base_resources.c", "src/core/ext/census/context.c", "src/core/ext/census/gen/census.pb.c", "src/core/ext/census/grpc_context.c", @@ -478,6 +481,7 @@ cc_library( "src/core/ext/census/mlog.c", "src/core/ext/census/operation.c", "src/core/ext/census/placeholders.c", + "src/core/ext/census/resource.c", "src/core/ext/census/tracing.c", "src/core/plugin_registry/grpc_plugin_registry.c", ], @@ -647,11 +651,13 @@ cc_library( "src/core/ext/lb_policy/grpclb/load_balancer_api.h", "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h", "src/core/ext/census/aggregation.h", + "src/core/ext/census/base_resources.h", "src/core/ext/census/census_interface.h", "src/core/ext/census/census_rpc_stats.h", "src/core/ext/census/gen/census.pb.h", "src/core/ext/census/grpc_filter.h", "src/core/ext/census/mlog.h", + "src/core/ext/census/resource.h", "src/core/ext/census/rpc_metric_id.h", "src/core/lib/surface/init.c", "src/core/lib/surface/init_unsecure.c", @@ -786,6 +792,7 @@ cc_library( "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", "src/core/ext/lb_policy/pick_first/pick_first.c", "src/core/ext/lb_policy/round_robin/round_robin.c", + "src/core/ext/census/base_resources.c", "src/core/ext/census/context.c", "src/core/ext/census/gen/census.pb.c", "src/core/ext/census/grpc_context.c", @@ -795,6 +802,7 @@ cc_library( "src/core/ext/census/mlog.c", "src/core/ext/census/operation.c", "src/core/ext/census/placeholders.c", + "src/core/ext/census/resource.c", "src/core/ext/census/tracing.c", "src/core/plugin_registry/grpc_unsecure_plugin_registry.c", ], @@ -1512,6 +1520,7 @@ objc_library( "src/core/ext/lb_policy/round_robin/round_robin.c", "src/core/ext/resolver/dns/native/dns_resolver.c", "src/core/ext/resolver/sockaddr/sockaddr_resolver.c", + "src/core/ext/census/base_resources.c", "src/core/ext/census/context.c", "src/core/ext/census/gen/census.pb.c", "src/core/ext/census/grpc_context.c", @@ -1521,6 +1530,7 @@ objc_library( "src/core/ext/census/mlog.c", "src/core/ext/census/operation.c", "src/core/ext/census/placeholders.c", + "src/core/ext/census/resource.c", "src/core/ext/census/tracing.c", "src/core/plugin_registry/grpc_plugin_registry.c", ], @@ -1693,11 +1703,13 @@ objc_library( "src/core/ext/lb_policy/grpclb/load_balancer_api.h", "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h", "src/core/ext/census/aggregation.h", + "src/core/ext/census/base_resources.h", "src/core/ext/census/census_interface.h", "src/core/ext/census/census_rpc_stats.h", "src/core/ext/census/gen/census.pb.h", "src/core/ext/census/grpc_filter.h", "src/core/ext/census/mlog.h", + "src/core/ext/census/resource.h", "src/core/ext/census/rpc_metric_id.h", ], includes = [ diff --git a/Makefile b/Makefile index 98f6e562c69..34daedc6d27 100644 --- a/Makefile +++ b/Makefile @@ -891,6 +891,7 @@ alpn_test: $(BINDIR)/$(CONFIG)/alpn_test api_fuzzer: $(BINDIR)/$(CONFIG)/api_fuzzer bin_encoder_test: $(BINDIR)/$(CONFIG)/bin_encoder_test census_context_test: $(BINDIR)/$(CONFIG)/census_context_test +census_resource_test: $(BINDIR)/$(CONFIG)/census_resource_test channel_create_test: $(BINDIR)/$(CONFIG)/channel_create_test chttp2_hpack_encoder_test: $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test chttp2_status_conversion_test: $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test @@ -1223,6 +1224,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/alpn_test \ $(BINDIR)/$(CONFIG)/bin_encoder_test \ $(BINDIR)/$(CONFIG)/census_context_test \ + $(BINDIR)/$(CONFIG)/census_resource_test \ $(BINDIR)/$(CONFIG)/channel_create_test \ $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test \ $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test \ @@ -1475,6 +1477,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/bin_encoder_test || ( echo test bin_encoder_test failed ; exit 1 ) $(E) "[RUN] Testing census_context_test" $(Q) $(BINDIR)/$(CONFIG)/census_context_test || ( echo test census_context_test failed ; exit 1 ) + $(E) "[RUN] Testing census_resource_test" + $(Q) $(BINDIR)/$(CONFIG)/census_resource_test || ( echo test census_resource_test failed ; exit 1 ) $(E) "[RUN] Testing channel_create_test" $(Q) $(BINDIR)/$(CONFIG)/channel_create_test || ( echo test channel_create_test failed ; exit 1 ) $(E) "[RUN] Testing chttp2_hpack_encoder_test" @@ -2637,6 +2641,7 @@ LIBGRPC_SRC = \ src/core/ext/lb_policy/round_robin/round_robin.c \ src/core/ext/resolver/dns/native/dns_resolver.c \ src/core/ext/resolver/sockaddr/sockaddr_resolver.c \ + src/core/ext/census/base_resources.c \ src/core/ext/census/context.c \ src/core/ext/census/gen/census.pb.c \ src/core/ext/census/grpc_context.c \ @@ -2646,6 +2651,7 @@ LIBGRPC_SRC = \ src/core/ext/census/mlog.c \ src/core/ext/census/operation.c \ src/core/ext/census/placeholders.c \ + src/core/ext/census/resource.c \ src/core/ext/census/tracing.c \ src/core/plugin_registry/grpc_plugin_registry.c \ @@ -2961,6 +2967,7 @@ LIBGRPC_UNSECURE_SRC = \ third_party/nanopb/pb_encode.c \ src/core/ext/lb_policy/pick_first/pick_first.c \ src/core/ext/lb_policy/round_robin/round_robin.c \ + src/core/ext/census/base_resources.c \ src/core/ext/census/context.c \ src/core/ext/census/gen/census.pb.c \ src/core/ext/census/grpc_context.c \ @@ -2970,6 +2977,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/census/mlog.c \ src/core/ext/census/operation.c \ src/core/ext/census/placeholders.c \ + src/core/ext/census/resource.c \ src/core/ext/census/tracing.c \ src/core/plugin_registry/grpc_unsecure_plugin_registry.c \ @@ -6195,6 +6203,38 @@ endif endif +CENSUS_RESOURCE_TEST_SRC = \ + test/core/census/resource_test.c \ + +CENSUS_RESOURCE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CENSUS_RESOURCE_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/census_resource_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/census_resource_test: $(CENSUS_RESOURCE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(CENSUS_RESOURCE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/census_resource_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/census/resource_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_census_resource_test: $(CENSUS_RESOURCE_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(CENSUS_RESOURCE_TEST_OBJS:.o=.dep) +endif +endif + + CHANNEL_CREATE_TEST_SRC = \ test/core/surface/channel_create_test.c \ diff --git a/binding.gyp b/binding.gyp index 1e8b5e294f8..cc8077d5662 100644 --- a/binding.gyp +++ b/binding.gyp @@ -730,6 +730,7 @@ 'src/core/ext/lb_policy/round_robin/round_robin.c', 'src/core/ext/resolver/dns/native/dns_resolver.c', 'src/core/ext/resolver/sockaddr/sockaddr_resolver.c', + 'src/core/ext/census/base_resources.c', 'src/core/ext/census/context.c', 'src/core/ext/census/gen/census.pb.c', 'src/core/ext/census/grpc_context.c', @@ -739,6 +740,7 @@ 'src/core/ext/census/mlog.c', 'src/core/ext/census/operation.c', 'src/core/ext/census/placeholders.c', + 'src/core/ext/census/resource.c', 'src/core/ext/census/tracing.c', 'src/core/plugin_registry/grpc_plugin_registry.c', ], diff --git a/build.yaml b/build.yaml index f211575e925..0d192eee1d8 100644 --- a/build.yaml +++ b/build.yaml @@ -14,13 +14,16 @@ filegroups: - include/grpc/census.h headers: - src/core/ext/census/aggregation.h + - src/core/ext/census/base_resources.h - src/core/ext/census/census_interface.h - src/core/ext/census/census_rpc_stats.h - src/core/ext/census/gen/census.pb.h - src/core/ext/census/grpc_filter.h - src/core/ext/census/mlog.h + - src/core/ext/census/resource.h - src/core/ext/census/rpc_metric_id.h src: + - src/core/ext/census/base_resources.c - src/core/ext/census/context.c - src/core/ext/census/gen/census.pb.c - src/core/ext/census/grpc_context.c @@ -30,6 +33,7 @@ filegroups: - src/core/ext/census/mlog.c - src/core/ext/census/operation.c - src/core/ext/census/placeholders.c + - src/core/ext/census/resource.c - src/core/ext/census/tracing.c plugin: census_grpc_plugin uses: @@ -1192,6 +1196,16 @@ targets: - grpc - gpr_test_util - gpr +- name: census_resource_test + build: test + language: c + src: + - test/core/census/resource_test.c + deps: + - grpc_test_util + - grpc + - gpr_test_util + - gpr - name: channel_create_test build: test language: c diff --git a/config.m4 b/config.m4 index e8506bb269c..b8a84291745 100644 --- a/config.m4 +++ b/config.m4 @@ -249,6 +249,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/lb_policy/round_robin/round_robin.c \ src/core/ext/resolver/dns/native/dns_resolver.c \ src/core/ext/resolver/sockaddr/sockaddr_resolver.c \ + src/core/ext/census/base_resources.c \ src/core/ext/census/context.c \ src/core/ext/census/gen/census.pb.c \ src/core/ext/census/grpc_context.c \ @@ -258,6 +259,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/census/mlog.c \ src/core/ext/census/operation.c \ src/core/ext/census/placeholders.c \ + src/core/ext/census/resource.c \ src/core/ext/census/tracing.c \ src/core/plugin_registry/grpc_plugin_registry.c \ src/boringssl/err_data.c \ diff --git a/gRPC.podspec b/gRPC.podspec index 9c049f03b19..8187b40a29d 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -306,11 +306,13 @@ Pod::Spec.new do |s| 'third_party/nanopb/pb_decode.h', 'third_party/nanopb/pb_encode.h', 'src/core/ext/census/aggregation.h', + 'src/core/ext/census/base_resources.h', 'src/core/ext/census/census_interface.h', 'src/core/ext/census/census_rpc_stats.h', 'src/core/ext/census/gen/census.pb.h', 'src/core/ext/census/grpc_filter.h', 'src/core/ext/census/mlog.h', + 'src/core/ext/census/resource.h', 'src/core/ext/census/rpc_metric_id.h', 'include/grpc/byte_buffer.h', 'include/grpc/byte_buffer_reader.h', @@ -509,6 +511,7 @@ Pod::Spec.new do |s| 'src/core/ext/lb_policy/round_robin/round_robin.c', 'src/core/ext/resolver/dns/native/dns_resolver.c', 'src/core/ext/resolver/sockaddr/sockaddr_resolver.c', + 'src/core/ext/census/base_resources.c', 'src/core/ext/census/context.c', 'src/core/ext/census/gen/census.pb.c', 'src/core/ext/census/grpc_context.c', @@ -518,6 +521,7 @@ Pod::Spec.new do |s| 'src/core/ext/census/mlog.c', 'src/core/ext/census/operation.c', 'src/core/ext/census/placeholders.c', + 'src/core/ext/census/resource.c', 'src/core/ext/census/tracing.c', 'src/core/plugin_registry/grpc_plugin_registry.c' @@ -675,11 +679,13 @@ Pod::Spec.new do |s| 'third_party/nanopb/pb_decode.h', 'third_party/nanopb/pb_encode.h', 'src/core/ext/census/aggregation.h', + 'src/core/ext/census/base_resources.h', 'src/core/ext/census/census_interface.h', 'src/core/ext/census/census_rpc_stats.h', 'src/core/ext/census/gen/census.pb.h', 'src/core/ext/census/grpc_filter.h', 'src/core/ext/census/mlog.h', + 'src/core/ext/census/resource.h', 'src/core/ext/census/rpc_metric_id.h' ss.header_mappings_dir = '.' diff --git a/grpc.def b/grpc.def index b811f0ff129..f69370ae8ab 100644 --- a/grpc.def +++ b/grpc.def @@ -23,15 +23,10 @@ EXPORTS census_trace_scan_start census_get_trace_record census_trace_scan_end + census_define_resource + census_delete_resource + census_resource_id census_record_values - census_view_create - census_view_delete - census_view_metric - census_view_naggregations - census_view_tags - census_view_aggregrations - census_view_get_data - census_view_reset grpc_compression_algorithm_parse grpc_compression_algorithm_name grpc_compression_algorithm_for_level diff --git a/grpc.gemspec b/grpc.gemspec index 047845cd843..acb23bd043d 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -315,11 +315,13 @@ Gem::Specification.new do |s| s.files += %w( third_party/nanopb/pb_decode.h ) s.files += %w( third_party/nanopb/pb_encode.h ) s.files += %w( src/core/ext/census/aggregation.h ) + s.files += %w( src/core/ext/census/base_resources.h ) s.files += %w( src/core/ext/census/census_interface.h ) s.files += %w( src/core/ext/census/census_rpc_stats.h ) s.files += %w( src/core/ext/census/gen/census.pb.h ) s.files += %w( src/core/ext/census/grpc_filter.h ) s.files += %w( src/core/ext/census/mlog.h ) + s.files += %w( src/core/ext/census/resource.h ) s.files += %w( src/core/ext/census/rpc_metric_id.h ) s.files += %w( src/core/lib/surface/init.c ) s.files += %w( src/core/lib/channel/channel_args.c ) @@ -488,6 +490,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/lb_policy/round_robin/round_robin.c ) s.files += %w( src/core/ext/resolver/dns/native/dns_resolver.c ) s.files += %w( src/core/ext/resolver/sockaddr/sockaddr_resolver.c ) + s.files += %w( src/core/ext/census/base_resources.c ) s.files += %w( src/core/ext/census/context.c ) s.files += %w( src/core/ext/census/gen/census.pb.c ) s.files += %w( src/core/ext/census/grpc_context.c ) @@ -497,6 +500,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/census/mlog.c ) s.files += %w( src/core/ext/census/operation.c ) s.files += %w( src/core/ext/census/placeholders.c ) + s.files += %w( src/core/ext/census/resource.c ) s.files += %w( src/core/ext/census/tracing.c ) s.files += %w( src/core/plugin_registry/grpc_plugin_registry.c ) s.files += %w( third_party/boringssl/crypto/aes/internal.h ) diff --git a/include/grpc/census.h b/include/grpc/census.h index 39d87ba119c..62ff45d8941 100644 --- a/include/grpc/census.h +++ b/include/grpc/census.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -56,9 +56,11 @@ enum census_features { /** Shutdown and startup census subsystem. The 'features' argument should be * the OR (|) of census_features values. If census fails to initialize, then - * census_initialize() will return a non-zero value. It is an error to call - * census_initialize() more than once (without an intervening - * census_shutdown()). */ + * census_initialize() will return -1, otherwise the set of enabled features + * (which may be smaller than that provided in the `features` argument, see + * census_supported()) is returned. It is an error to call census_initialize() + * more than once (without an intervening census_shutdown()). These functions + * are not thread-safe. */ CENSUSAPI int census_initialize(int features); CENSUSAPI void census_shutdown(void); @@ -430,30 +432,44 @@ CENSUSAPI int census_get_trace_record(census_trace_record *trace_record); CENSUSAPI void census_trace_scan_end(); /* Core stats collection API's. The following concepts are used: - * Aggregation: A collection of values. Census supports the following - aggregation types: - Sum - a single summation type. Typically used for keeping (e.g.) - counts of events. - Distribution - statistical distribution information, used for - recording average, standard deviation etc. - Histogram - a histogram of measurements falling in defined bucket - boundaries. - Window - a count of events that happen in reolling time window. - New aggregation types can be added by the user, if desired (see - census_register_aggregation()). - * Metric: Each measurement is for a single metric. Examples include RPC - latency, CPU seconds consumed, and bytes transmitted. - * View: A view is a combination of a metric, a tag set (in which the tag - values are regular expressions) and a set of aggregations. When a - measurement for a metric matches the view tags, it is recorded (for each - unique set of tags) against each aggregation. Each metric can have an - arbitrary number of views by which it will be broken down. + * Resource: Users record measurements for a single resource. Examples + include RPC latency, CPU seconds consumed, and bytes transmitted. + * Aggregation: An aggregation of a set of measurements. Census supports the + following aggregation types: + * Distribution - statistical distribution information, used for + recording average, standard deviation etc. Can include a histogram. + * Interval - a count of events that happen in a rolling time window. + * View: A view is a combination of a Resource, a set of tag keys and an + Aggregation. When a measurement for a Resource matches the View tags, it is + recorded (for each unique set of tag values) using the Aggregation type. + Each resource can have an arbitrary number of views by which it will be + broken down. + + Census uses protos to define each of the above, and output results. This + ensures unification across the different language and runtime + implementations. The proto definitions can be found in src/proto/census. */ +/* Define a new resource. `resource_pb` should contain an encoded Resource + protobuf, `resource_pb_size` being the size of the buffer. Returns a -ve + value on error, or a positive (>= 0) resource id (for use in + census_delete_resource() and census_record_values()). In order to be valid, a + resource must have a name, and at least one numerator in it's unit type. The + resource name must be unique, and an error will be returned if it is not. */ +CENSUSAPI int32_t census_define_resource(const uint8_t *resource_pb, + size_t resource_pb_size); + +/* Delete a resource created by census_define_resource(). */ +CENSUSAPI void census_delete_resource(int32_t resource_id); + +/* Determine the id of a resource, given it's name. returns -1 if the resource + does not exist. */ +CENSUSAPI int32_t census_resource_id(const char *name); + /* A single value to be recorded comprises two parts: an ID for the particular - * metric and the value to be recorded against it. */ + * resource and the value to be recorded against it. */ typedef struct { - uint32_t metric_id; + int32_t resource_id; double value; } census_value; @@ -461,78 +477,6 @@ typedef struct { CENSUSAPI void census_record_values(census_context *context, census_value *values, size_t nvalues); -/** Type representing a particular aggregation */ -typedef struct census_aggregation_ops census_aggregation_ops; - -/* Predefined aggregation types, for use with census_view_create(). */ -extern census_aggregation_ops census_agg_sum; -extern census_aggregation_ops census_agg_distribution; -extern census_aggregation_ops census_agg_histogram; -extern census_aggregation_ops census_agg_window; - -/** Information needed to instantiate a new aggregation. Used in view - construction via census_define_view(). */ -typedef struct { - const census_aggregation_ops *ops; - const void *create_arg; /* Aaggregation initialization argument. */ -} census_aggregation; - -/** A census view type. Opaque. */ -typedef struct census_view census_view; - -/** Create a new view. - @param metric_id Metric with which this view is associated. - @param tags tags that define the view. - @param aggregations aggregations to associate with the view - @param naggregations number of aggregations - - @return A new census view -*/ - -/* TODO(aveitch): consider if context is the right argument type to pass in - tags. */ -CENSUSAPI census_view *census_view_create( - uint32_t metric_id, const census_context *tags, - const census_aggregation *aggregations, size_t naggregations); - -/** Destroy a previously created view. */ -CENSUSAPI void census_view_delete(census_view *view); - -/** Metric ID associated with a view */ -CENSUSAPI size_t census_view_metric(const census_view *view); - -/** Number of aggregations associated with view. */ -CENSUSAPI size_t census_view_naggregations(const census_view *view); - -/** Get tags associated with view. */ -CENSUSAPI const census_context *census_view_tags(const census_view *view); - -/** Get aggregation descriptors associated with a view. */ -CENSUSAPI const census_aggregation *census_view_aggregrations( - const census_view *view); - -/** Holds all the aggregation data for a particular view instantiation. Forms - part of the data returned by census_view_data(). */ -typedef struct { - const census_context *tags; /* Tags for this set of aggregations. */ - const void **data; /* One data set for every aggregation in the view. */ -} census_view_aggregation_data; - -/** Census view data as returned by census_view_get_data(). */ -typedef struct { - size_t n_tag_sets; /* Number of unique tag sets that matched view. */ - const census_view_aggregation_data *data; /* n_tag_sets entries */ -} census_view_data; - -/** Get data from aggregations associated with a view. - @param view View from which to get data. - @return Full set of data for all aggregations for the view. -*/ -CENSUSAPI const census_view_data *census_view_get_data(const census_view *view); - -/** Reset all view data to zero for the specified view */ -CENSUSAPI void census_view_reset(census_view *view); - #ifdef __cplusplus } #endif diff --git a/package.xml b/package.xml index 6f6b8dd4bdb..575b7438fae 100644 --- a/package.xml +++ b/package.xml @@ -322,11 +322,13 @@ + + @@ -495,6 +497,7 @@ + @@ -504,6 +507,7 @@ + diff --git a/src/core/ext/census/base_resources.c b/src/core/ext/census/base_resources.c new file mode 100644 index 00000000000..8f0329a72bd --- /dev/null +++ b/src/core/ext/census/base_resources.c @@ -0,0 +1,148 @@ +/* + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include + +#include +#include + +#include "base_resources.h" +#include "gen/census.pb.h" +#include "third_party/nanopb/pb_encode.h" + +// Add base RPC resource definitions for use by RPC runtime. +// +// TODO(aveitch): All of these are currently hardwired definitions encoded in +// the code in this file. These should be converted to use an external +// configuration mechanism, in which these resources are defined in a text +// file, which is compiled to .pb format and read by still-to-be-written +// configuration functions. + +// Structure representing a MeasurementUnit proto. +typedef struct { + int32_t prefix; + int n_numerators; + const google_census_Resource_BasicUnit *numerators; + int n_denominators; + const google_census_Resource_BasicUnit *denominators; +} measurement_unit; + +// Encode a nanopb string. Expects the string argument to be passed in as `arg`. +static bool encode_string(pb_ostream_t *stream, const pb_field_t *field, + void *const *arg) { + if (!pb_encode_tag_for_field(stream, field)) { + return false; + } + return pb_encode_string(stream, (uint8_t *)*arg, strlen((const char *)*arg)); +} + +// Encode the numerators part of a measurement_unit (passed in as `arg`). +static bool encode_numerators(pb_ostream_t *stream, const pb_field_t *field, + void *const *arg) { + const measurement_unit *mu = (const measurement_unit *)*arg; + for (int i = 0; i < mu->n_numerators; i++) { + if (!pb_encode_tag_for_field(stream, field)) { + return false; + } + if (!pb_encode_varint(stream, mu->numerators[i])) { + return false; + } + } + return true; +} + +// Encode the denominators part of a measurement_unit (passed in as `arg`). +static bool encode_denominators(pb_ostream_t *stream, const pb_field_t *field, + void *const *arg) { + const measurement_unit *mu = (const measurement_unit *)*arg; + for (int i = 0; i < mu->n_denominators; i++) { + if (!pb_encode_tag_for_field(stream, field)) { + return false; + } + if (!pb_encode_varint(stream, mu->numerators[i])) { + return false; + } + } + return true; +} + +// Define a Resource, given the important details. Encodes a protobuf, which +// is then passed to census_define_resource. +static void define_resource(const char *name, const char *description, + const measurement_unit *unit) { + // nanopb generated type for Resource. Initialize encoding functions to NULL + // since we can't directly initialize them due to embedded union in struct. + google_census_Resource resource = { + {{NULL}, (void *)name}, + {{NULL}, (void *)description}, + true, // has_unit + {true, unit->prefix, {{NULL}, (void *)unit}, {{NULL}, (void *)unit}}}; + resource.name.funcs.encode = &encode_string; + resource.description.funcs.encode = &encode_string; + resource.unit.numerator.funcs.encode = &encode_numerators; + resource.unit.denominator.funcs.encode = &encode_denominators; + + // Buffer for storing encoded proto. + uint8_t buffer[512]; + pb_ostream_t stream = pb_ostream_from_buffer(buffer, 512); + if (!pb_encode(&stream, google_census_Resource_fields, &resource)) { + gpr_log(GPR_ERROR, "Error encoding resource %s.", name); + return; + } + int32_t mid = census_define_resource(buffer, stream.bytes_written); + if (mid < 0) { + gpr_log(GPR_ERROR, "Error defining resource %s.", name); + } +} + +// Define a resource for client RPC latency. +static void define_client_rpc_latency_resource() { + google_census_Resource_BasicUnit numerator = + google_census_Resource_BasicUnit_SECS; + measurement_unit unit = {0, 1, &numerator, 0, NULL}; + define_resource("client_rpc_latency", "Client RPC latency in seconds", &unit); +} + +// Define a resource for server RPC latency. +static void define_server_rpc_latency_resource() { + google_census_Resource_BasicUnit numerator = + google_census_Resource_BasicUnit_SECS; + measurement_unit unit = {0, 1, &numerator, 0, NULL}; + define_resource("server_rpc_latency", "Server RPC latency in seconds", &unit); +} + +// Define all base resources. This should be called by census initialization. +void define_base_resources() { + define_client_rpc_latency_resource(); + define_server_rpc_latency_resource(); +} diff --git a/src/core/ext/census/base_resources.h b/src/core/ext/census/base_resources.h new file mode 100644 index 00000000000..992e5f6ebea --- /dev/null +++ b/src/core/ext/census/base_resources.h @@ -0,0 +1,39 @@ +/* + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_CORE_EXT_CENSUS_BASE_RESOURCES_H +#define GRPC_CORE_EXT_CENSUS_BASE_RESOURCES_H + +// Define all base resources. This should be called by census initialization. +void define_base_resources(); + +#endif // GRPC_CORE_EXT_CENSUS_BASE_RESOURCES_H diff --git a/src/core/ext/census/initialize.c b/src/core/ext/census/initialize.c index 896276e44a1..118163512ad 100644 --- a/src/core/ext/census/initialize.c +++ b/src/core/ext/census/initialize.c @@ -32,19 +32,31 @@ */ #include +#include "base_resources.h" +#include "resource.h" static int features_enabled = CENSUS_FEATURE_NONE; int census_initialize(int features) { if (features_enabled != CENSUS_FEATURE_NONE) { // Must have been a previous call to census_initialize; return error - return 1; + return -1; } - features_enabled = features; - return 0; + features_enabled = features & CENSUS_FEATURE_ALL; + if (features & CENSUS_FEATURE_STATS) { + initialize_resources(); + define_base_resources(); + } + + return features_enabled; } -void census_shutdown(void) { features_enabled = CENSUS_FEATURE_NONE; } +void census_shutdown(void) { + if (features_enabled & CENSUS_FEATURE_STATS) { + shutdown_resources(); + } + features_enabled = CENSUS_FEATURE_NONE; +} int census_supported(void) { /* TODO(aveitch): improve this as we implement features... */ diff --git a/src/core/ext/census/placeholders.c b/src/core/ext/census/placeholders.c index fe23d13971a..9f99c5bdcfb 100644 --- a/src/core/ext/census/placeholders.c +++ b/src/core/ext/census/placeholders.c @@ -62,48 +62,3 @@ int census_trace_scan_start(int consume) { (void)consume; abort(); } - -const census_aggregation *census_view_aggregrations(const census_view *view) { - (void)view; - abort(); -} - -census_view *census_view_create(uint32_t metric_id, const census_context *tags, - const census_aggregation *aggregations, - size_t naggregations) { - (void)metric_id; - (void)tags; - (void)aggregations; - (void)naggregations; - abort(); -} - -const census_context *census_view_tags(const census_view *view) { - (void)view; - abort(); -} - -void census_view_delete(census_view *view) { - (void)view; - abort(); -} - -const census_view_data *census_view_get_data(const census_view *view) { - (void)view; - abort(); -} - -size_t census_view_metric(const census_view *view) { - (void)view; - abort(); -} - -size_t census_view_naggregations(const census_view *view) { - (void)view; - abort(); -} - -void census_view_reset(census_view *view) { - (void)view; - abort(); -} diff --git a/src/core/ext/census/resource.c b/src/core/ext/census/resource.c new file mode 100644 index 00000000000..632b899e415 --- /dev/null +++ b/src/core/ext/census/resource.c @@ -0,0 +1,255 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "resource.h" +#include "gen/census.pb.h" +#include "third_party/nanopb/pb_decode.h" + +#include +#include +#include +#include + +#include +#include + +// Internal representation of a resource. +typedef struct { + char *name; + // Pointer to raw protobuf used in resource definition. + uint8_t *raw_pb; +} resource; + +// Protect local resource data structures. +static gpr_mu resource_lock; + +// Deleteing and creating resources are relatively rare events, and should not +// be done in the critical path of performance sensitive code. We record +// current resource id's used in a simple array, and just search it each time +// we need to assign a new id, or look up a resource. +static resource **resources = NULL; + +// Number of entries in *resources +static size_t n_resources = 0; + +// Number of defined resources +static size_t n_defined_resources = 0; + +void initialize_resources() { + gpr_mu_init(&resource_lock); + gpr_mu_lock(&resource_lock); + GPR_ASSERT(resources == NULL && n_resources == 0 && n_defined_resources == 0); + // 8 seems like a reasonable size for initial number of resources. + n_resources = 8; + resources = gpr_malloc(n_resources * sizeof(resource *)); + memset(resources, 0, n_resources * sizeof(resource *)); + gpr_mu_unlock(&resource_lock); +} + +// Delete a resource given it's ID. Must be called with resource_lock held. +static void delete_resource_locked(size_t rid) { + GPR_ASSERT(resources[rid] != NULL && resources[rid]->raw_pb != NULL && + resources[rid]->name != NULL && n_defined_resources > 0); + gpr_free(resources[rid]->name); + gpr_free(resources[rid]->raw_pb); + gpr_free(resources[rid]); + resources[rid] = NULL; + n_defined_resources--; +} + +void shutdown_resources() { + gpr_mu_lock(&resource_lock); + for (size_t i = 0; i < n_resources; i++) { + if (resources[i] != NULL) { + delete_resource_locked(i); + } + } + GPR_ASSERT(n_defined_resources == 0); + gpr_free(resources); + resources = NULL; + n_resources = 0; + gpr_mu_unlock(&resource_lock); +} + +// Check the contents of string fields in a resource proto. +static bool validate_string(pb_istream_t *stream, const pb_field_t *field, + void **arg) { + resource *vresource = (resource *)*arg; + switch (field->tag) { + case google_census_Resource_name_tag: + // Name must have at least one character + if (stream->bytes_left == 0) { + gpr_log(GPR_INFO, "Zero-length Resource name."); + return false; + } + vresource->name = gpr_malloc(stream->bytes_left + 1); + vresource->name[stream->bytes_left] = '\0'; + if (!pb_read(stream, (uint8_t *)vresource->name, stream->bytes_left)) { + return false; + } + // Can't have same name as an existing resource. + for (size_t i = 0; i < n_resources; i++) { + resource *compare = resources[i]; + if (compare == vresource || compare == NULL) continue; + if (strcmp(compare->name, vresource->name) == 0) { + gpr_log(GPR_INFO, "Duplicate Resource name %s.", vresource->name); + return false; + } + } + break; + case google_census_Resource_description_tag: + // Description is optional, does not need validating, just skip. + if (!pb_read(stream, NULL, stream->bytes_left)) { + return false; + } + break; + default: + // No other string fields in Resource. Print warning and skip. + gpr_log(GPR_INFO, "Unknown string field type in Resource protobuf."); + if (!pb_read(stream, NULL, stream->bytes_left)) { + return false; + } + break; + } + return true; +} + +// Validate units field of a Resource proto. +static bool validate_units(pb_istream_t *stream, const pb_field_t *field, + void **arg) { + if (field->tag == google_census_Resource_MeasurementUnit_numerator_tag) { + *(bool *)*arg = true; // has_numerator = true. + } + while (stream->bytes_left) { + uint64_t value; + if (!pb_decode_varint(stream, &value)) { + return false; + } + } + return true; +} + +// Vlaidate the contents of a Resource proto. `id` is the intended resource id. +static bool validate_resource_pb(const uint8_t *resource_pb, + size_t resource_pb_size, size_t id) { + GPR_ASSERT(id < n_resources); + if (resource_pb == NULL) { + return false; + } + google_census_Resource vresource; + vresource.name.funcs.decode = &validate_string; + vresource.name.arg = resources[id]; + vresource.description.funcs.decode = &validate_string; + vresource.unit.numerator.funcs.decode = &validate_units; + bool has_numerator = false; + vresource.unit.numerator.arg = &has_numerator; + vresource.unit.denominator.funcs.decode = &validate_units; + + pb_istream_t stream = + pb_istream_from_buffer((uint8_t *)resource_pb, resource_pb_size); + if (!pb_decode(&stream, google_census_Resource_fields, &vresource)) { + return false; + } + // A Resource must have a name, a unit, with at least one numerator. + return (resources[id]->name != NULL && vresource.has_unit && has_numerator); +} + +int32_t census_define_resource(const uint8_t *resource_pb, + size_t resource_pb_size) { + // use next_id to optimize expected placement of next new resource. + static size_t next_id = 0; + if (resource_pb == NULL) { + return -1; + } + gpr_mu_lock(&resource_lock); + size_t id = n_resources; // resource ID - initialize to invalid value. + // Expand resources if needed. + if (n_resources == n_defined_resources) { + resource **new_resources = gpr_malloc(n_resources * 2 * sizeof(resource *)); + memcpy(new_resources, resources, n_resources * sizeof(resource *)); + memset(new_resources + n_resources, 0, n_resources * sizeof(resource *)); + gpr_free(resources); + resources = new_resources; + n_resources *= 2; + id = n_defined_resources; + } else { + GPR_ASSERT(n_defined_resources < n_resources); + // Find a free id. + for (size_t base = 0; base < n_resources; base++) { + id = (next_id + base) % n_resources; + if (resources[id] == NULL) break; + } + } + GPR_ASSERT(id < n_resources && resources[id] == NULL); + resources[id] = gpr_malloc(sizeof(resource)); + resources[id]->name = NULL; + // Validate pb, extract name. + if (!validate_resource_pb(resource_pb, resource_pb_size, id)) { + if (resources[id]->name != NULL) { + gpr_free(resources[id]->name); + } + gpr_free(resources[id]); + resources[id] = NULL; + gpr_mu_unlock(&resource_lock); + return -1; + } + next_id = (id + 1) % n_resources; + // Make copy of raw proto, and return. + resources[id]->raw_pb = gpr_malloc(resource_pb_size); + memcpy(resources[id]->raw_pb, resource_pb, resource_pb_size); + n_defined_resources++; + gpr_mu_unlock(&resource_lock); + return (int32_t)id; +} + +void census_delete_resource(int32_t rid) { + gpr_mu_lock(&resource_lock); + if (rid >= 0 && (size_t)rid < n_resources && resources[rid] != NULL) { + delete_resource_locked((size_t)rid); + } + gpr_mu_unlock(&resource_lock); +} + +int32_t census_resource_id(const char *name) { + gpr_mu_lock(&resource_lock); + for (int32_t id = 0; (size_t)id < n_resources; id++) { + if (resources[id] != NULL) { + if (strcmp(resources[id]->name, name) == 0) { + gpr_mu_unlock(&resource_lock); + return id; + } + } + } + gpr_mu_unlock(&resource_lock); + return -1; +} diff --git a/src/core/ext/census/resource.h b/src/core/ext/census/resource.h new file mode 100644 index 00000000000..5ad5a0f7a0c --- /dev/null +++ b/src/core/ext/census/resource.h @@ -0,0 +1,42 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +// Census-internal resource definition and manipluation functions. +#ifndef GRPC_CORE_EXT_CENSUS_RESOURCE_H +#define GRPC_CORE_EXT_CENSUS_RESOURCE_H + +// Initialize and shutdown the resources subsystem. +void initialize_resources(); +void shutdown_resources(); + +#endif /* GRPC_CORE_EXT_CENSUS_RESOURCE_H */ diff --git a/src/python/grpcio/grpc/_cython/imports.generated.c b/src/python/grpcio/grpc/_cython/imports.generated.c index f71cf128445..29ada16afdd 100644 --- a/src/python/grpcio/grpc/_cython/imports.generated.c +++ b/src/python/grpcio/grpc/_cython/imports.generated.c @@ -61,15 +61,10 @@ census_trace_print_type census_trace_print_import; census_trace_scan_start_type census_trace_scan_start_import; census_get_trace_record_type census_get_trace_record_import; census_trace_scan_end_type census_trace_scan_end_import; +census_define_resource_type census_define_resource_import; +census_delete_resource_type census_delete_resource_import; +census_resource_id_type census_resource_id_import; census_record_values_type census_record_values_import; -census_view_create_type census_view_create_import; -census_view_delete_type census_view_delete_import; -census_view_metric_type census_view_metric_import; -census_view_naggregations_type census_view_naggregations_import; -census_view_tags_type census_view_tags_import; -census_view_aggregrations_type census_view_aggregrations_import; -census_view_get_data_type census_view_get_data_import; -census_view_reset_type census_view_reset_import; grpc_compression_algorithm_parse_type grpc_compression_algorithm_parse_import; grpc_compression_algorithm_name_type grpc_compression_algorithm_name_import; grpc_compression_algorithm_for_level_type grpc_compression_algorithm_for_level_import; @@ -333,15 +328,10 @@ void pygrpc_load_imports(HMODULE library) { census_trace_scan_start_import = (census_trace_scan_start_type) GetProcAddress(library, "census_trace_scan_start"); census_get_trace_record_import = (census_get_trace_record_type) GetProcAddress(library, "census_get_trace_record"); census_trace_scan_end_import = (census_trace_scan_end_type) GetProcAddress(library, "census_trace_scan_end"); + census_define_resource_import = (census_define_resource_type) GetProcAddress(library, "census_define_resource"); + census_delete_resource_import = (census_delete_resource_type) GetProcAddress(library, "census_delete_resource"); + census_resource_id_import = (census_resource_id_type) GetProcAddress(library, "census_resource_id"); census_record_values_import = (census_record_values_type) GetProcAddress(library, "census_record_values"); - census_view_create_import = (census_view_create_type) GetProcAddress(library, "census_view_create"); - census_view_delete_import = (census_view_delete_type) GetProcAddress(library, "census_view_delete"); - census_view_metric_import = (census_view_metric_type) GetProcAddress(library, "census_view_metric"); - census_view_naggregations_import = (census_view_naggregations_type) GetProcAddress(library, "census_view_naggregations"); - census_view_tags_import = (census_view_tags_type) GetProcAddress(library, "census_view_tags"); - census_view_aggregrations_import = (census_view_aggregrations_type) GetProcAddress(library, "census_view_aggregrations"); - census_view_get_data_import = (census_view_get_data_type) GetProcAddress(library, "census_view_get_data"); - census_view_reset_import = (census_view_reset_type) GetProcAddress(library, "census_view_reset"); grpc_compression_algorithm_parse_import = (grpc_compression_algorithm_parse_type) GetProcAddress(library, "grpc_compression_algorithm_parse"); grpc_compression_algorithm_name_import = (grpc_compression_algorithm_name_type) GetProcAddress(library, "grpc_compression_algorithm_name"); grpc_compression_algorithm_for_level_import = (grpc_compression_algorithm_for_level_type) GetProcAddress(library, "grpc_compression_algorithm_for_level"); diff --git a/src/python/grpcio/grpc/_cython/imports.generated.h b/src/python/grpcio/grpc/_cython/imports.generated.h index a364075e9e3..f6dd79cadc2 100644 --- a/src/python/grpcio/grpc/_cython/imports.generated.h +++ b/src/python/grpcio/grpc/_cython/imports.generated.h @@ -134,33 +134,18 @@ extern census_get_trace_record_type census_get_trace_record_import; typedef void(*census_trace_scan_end_type)(); extern census_trace_scan_end_type census_trace_scan_end_import; #define census_trace_scan_end census_trace_scan_end_import +typedef int32_t(*census_define_resource_type)(const uint8_t *resource_pb, size_t resource_pb_size); +extern census_define_resource_type census_define_resource_import; +#define census_define_resource census_define_resource_import +typedef void(*census_delete_resource_type)(int32_t resource_id); +extern census_delete_resource_type census_delete_resource_import; +#define census_delete_resource census_delete_resource_import +typedef int32_t(*census_resource_id_type)(const char *name); +extern census_resource_id_type census_resource_id_import; +#define census_resource_id census_resource_id_import typedef void(*census_record_values_type)(census_context *context, census_value *values, size_t nvalues); extern census_record_values_type census_record_values_import; #define census_record_values census_record_values_import -typedef census_view *(*census_view_create_type)(uint32_t metric_id, const census_context *tags, const census_aggregation *aggregations, size_t naggregations); -extern census_view_create_type census_view_create_import; -#define census_view_create census_view_create_import -typedef void(*census_view_delete_type)(census_view *view); -extern census_view_delete_type census_view_delete_import; -#define census_view_delete census_view_delete_import -typedef size_t(*census_view_metric_type)(const census_view *view); -extern census_view_metric_type census_view_metric_import; -#define census_view_metric census_view_metric_import -typedef size_t(*census_view_naggregations_type)(const census_view *view); -extern census_view_naggregations_type census_view_naggregations_import; -#define census_view_naggregations census_view_naggregations_import -typedef const census_context *(*census_view_tags_type)(const census_view *view); -extern census_view_tags_type census_view_tags_import; -#define census_view_tags census_view_tags_import -typedef const census_aggregation *(*census_view_aggregrations_type)(const census_view *view); -extern census_view_aggregrations_type census_view_aggregrations_import; -#define census_view_aggregrations census_view_aggregrations_import -typedef const census_view_data *(*census_view_get_data_type)(const census_view *view); -extern census_view_get_data_type census_view_get_data_import; -#define census_view_get_data census_view_get_data_import -typedef void(*census_view_reset_type)(census_view *view); -extern census_view_reset_type census_view_reset_import; -#define census_view_reset census_view_reset_import typedef int(*grpc_compression_algorithm_parse_type)(const char *name, size_t name_length, grpc_compression_algorithm *algorithm); extern grpc_compression_algorithm_parse_type grpc_compression_algorithm_parse_import; #define grpc_compression_algorithm_parse grpc_compression_algorithm_parse_import diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index d0f23f42ccc..c7d042d5657 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -243,6 +243,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/lb_policy/round_robin/round_robin.c', 'src/core/ext/resolver/dns/native/dns_resolver.c', 'src/core/ext/resolver/sockaddr/sockaddr_resolver.c', + 'src/core/ext/census/base_resources.c', 'src/core/ext/census/context.c', 'src/core/ext/census/gen/census.pb.c', 'src/core/ext/census/grpc_context.c', @@ -252,6 +253,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/census/mlog.c', 'src/core/ext/census/operation.c', 'src/core/ext/census/placeholders.c', + 'src/core/ext/census/resource.c', 'src/core/ext/census/tracing.c', 'src/core/plugin_registry/grpc_plugin_registry.c', 'src/boringssl/err_data.c', diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index 3b62984defa..5d0f565ea83 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -61,15 +61,10 @@ census_trace_print_type census_trace_print_import; census_trace_scan_start_type census_trace_scan_start_import; census_get_trace_record_type census_get_trace_record_import; census_trace_scan_end_type census_trace_scan_end_import; +census_define_resource_type census_define_resource_import; +census_delete_resource_type census_delete_resource_import; +census_resource_id_type census_resource_id_import; census_record_values_type census_record_values_import; -census_view_create_type census_view_create_import; -census_view_delete_type census_view_delete_import; -census_view_metric_type census_view_metric_import; -census_view_naggregations_type census_view_naggregations_import; -census_view_tags_type census_view_tags_import; -census_view_aggregrations_type census_view_aggregrations_import; -census_view_get_data_type census_view_get_data_import; -census_view_reset_type census_view_reset_import; grpc_compression_algorithm_parse_type grpc_compression_algorithm_parse_import; grpc_compression_algorithm_name_type grpc_compression_algorithm_name_import; grpc_compression_algorithm_for_level_type grpc_compression_algorithm_for_level_import; @@ -329,15 +324,10 @@ void grpc_rb_load_imports(HMODULE library) { census_trace_scan_start_import = (census_trace_scan_start_type) GetProcAddress(library, "census_trace_scan_start"); census_get_trace_record_import = (census_get_trace_record_type) GetProcAddress(library, "census_get_trace_record"); census_trace_scan_end_import = (census_trace_scan_end_type) GetProcAddress(library, "census_trace_scan_end"); + census_define_resource_import = (census_define_resource_type) GetProcAddress(library, "census_define_resource"); + census_delete_resource_import = (census_delete_resource_type) GetProcAddress(library, "census_delete_resource"); + census_resource_id_import = (census_resource_id_type) GetProcAddress(library, "census_resource_id"); census_record_values_import = (census_record_values_type) GetProcAddress(library, "census_record_values"); - census_view_create_import = (census_view_create_type) GetProcAddress(library, "census_view_create"); - census_view_delete_import = (census_view_delete_type) GetProcAddress(library, "census_view_delete"); - census_view_metric_import = (census_view_metric_type) GetProcAddress(library, "census_view_metric"); - census_view_naggregations_import = (census_view_naggregations_type) GetProcAddress(library, "census_view_naggregations"); - census_view_tags_import = (census_view_tags_type) GetProcAddress(library, "census_view_tags"); - census_view_aggregrations_import = (census_view_aggregrations_type) GetProcAddress(library, "census_view_aggregrations"); - census_view_get_data_import = (census_view_get_data_type) GetProcAddress(library, "census_view_get_data"); - census_view_reset_import = (census_view_reset_type) GetProcAddress(library, "census_view_reset"); grpc_compression_algorithm_parse_import = (grpc_compression_algorithm_parse_type) GetProcAddress(library, "grpc_compression_algorithm_parse"); grpc_compression_algorithm_name_import = (grpc_compression_algorithm_name_type) GetProcAddress(library, "grpc_compression_algorithm_name"); grpc_compression_algorithm_for_level_import = (grpc_compression_algorithm_for_level_type) GetProcAddress(library, "grpc_compression_algorithm_for_level"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 1428e6d71c3..4033e5e6263 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -134,33 +134,18 @@ extern census_get_trace_record_type census_get_trace_record_import; typedef void(*census_trace_scan_end_type)(); extern census_trace_scan_end_type census_trace_scan_end_import; #define census_trace_scan_end census_trace_scan_end_import +typedef int32_t(*census_define_resource_type)(const uint8_t *resource_pb, size_t resource_pb_size); +extern census_define_resource_type census_define_resource_import; +#define census_define_resource census_define_resource_import +typedef void(*census_delete_resource_type)(int32_t resource_id); +extern census_delete_resource_type census_delete_resource_import; +#define census_delete_resource census_delete_resource_import +typedef int32_t(*census_resource_id_type)(const char *name); +extern census_resource_id_type census_resource_id_import; +#define census_resource_id census_resource_id_import typedef void(*census_record_values_type)(census_context *context, census_value *values, size_t nvalues); extern census_record_values_type census_record_values_import; #define census_record_values census_record_values_import -typedef census_view *(*census_view_create_type)(uint32_t metric_id, const census_context *tags, const census_aggregation *aggregations, size_t naggregations); -extern census_view_create_type census_view_create_import; -#define census_view_create census_view_create_import -typedef void(*census_view_delete_type)(census_view *view); -extern census_view_delete_type census_view_delete_import; -#define census_view_delete census_view_delete_import -typedef size_t(*census_view_metric_type)(const census_view *view); -extern census_view_metric_type census_view_metric_import; -#define census_view_metric census_view_metric_import -typedef size_t(*census_view_naggregations_type)(const census_view *view); -extern census_view_naggregations_type census_view_naggregations_import; -#define census_view_naggregations census_view_naggregations_import -typedef const census_context *(*census_view_tags_type)(const census_view *view); -extern census_view_tags_type census_view_tags_import; -#define census_view_tags census_view_tags_import -typedef const census_aggregation *(*census_view_aggregrations_type)(const census_view *view); -extern census_view_aggregrations_type census_view_aggregrations_import; -#define census_view_aggregrations census_view_aggregrations_import -typedef const census_view_data *(*census_view_get_data_type)(const census_view *view); -extern census_view_get_data_type census_view_get_data_import; -#define census_view_get_data census_view_get_data_import -typedef void(*census_view_reset_type)(census_view *view); -extern census_view_reset_type census_view_reset_import; -#define census_view_reset census_view_reset_import typedef int(*grpc_compression_algorithm_parse_type)(const char *name, size_t name_length, grpc_compression_algorithm *algorithm); extern grpc_compression_algorithm_parse_type grpc_compression_algorithm_parse_import; #define grpc_compression_algorithm_parse grpc_compression_algorithm_parse_import diff --git a/test/core/census/README b/test/core/census/README new file mode 100644 index 00000000000..d5363b72333 --- /dev/null +++ b/test/core/census/README @@ -0,0 +1,7 @@ +Test source and data files for Census. + +binary proto files (*.pb) in data directory are generated from the *.txt file, +via: + +BASE="filename" +cat $BASE.txt | protoc --encode=google.census.Resource census.proto > $BASE.pb diff --git a/test/core/census/data/resource_empty_name.pb b/test/core/census/data/resource_empty_name.pb new file mode 100644 index 00000000000..4d547445fae --- /dev/null +++ b/test/core/census/data/resource_empty_name.pb @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/core/census/data/resource_empty_name.txt b/test/core/census/data/resource_empty_name.txt new file mode 100644 index 00000000000..271fd3274c2 --- /dev/null +++ b/test/core/census/data/resource_empty_name.txt @@ -0,0 +1,5 @@ +# Name is present, but empty. +name : '' +unit { + numerator : SECS +} diff --git a/test/core/census/data/resource_full.pb b/test/core/census/data/resource_full.pb new file mode 100644 index 00000000000..e4c6a2aef53 --- /dev/null +++ b/test/core/census/data/resource_full.pb @@ -0,0 +1,2 @@ + + full_resource"A resource with everything defined \ No newline at end of file diff --git a/test/core/census/data/resource_full.txt b/test/core/census/data/resource_full.txt new file mode 100644 index 00000000000..1aa2fafe3a4 --- /dev/null +++ b/test/core/census/data/resource_full.txt @@ -0,0 +1,9 @@ +# A full resource definition - all fields filled out. +name : 'full_resource' +description : 'A resource with everything defined' +unit { + # Megabits per second. + prefix : 6 + numerator : BITS + denominator : SECS +} diff --git a/test/core/census/data/resource_minimal_good.pb b/test/core/census/data/resource_minimal_good.pb new file mode 100644 index 00000000000..7100c462bf1 --- /dev/null +++ b/test/core/census/data/resource_minimal_good.pb @@ -0,0 +1,2 @@ + + minimal_good \ No newline at end of file diff --git a/test/core/census/data/resource_minimal_good.txt b/test/core/census/data/resource_minimal_good.txt new file mode 100644 index 00000000000..a7a7e71dd62 --- /dev/null +++ b/test/core/census/data/resource_minimal_good.txt @@ -0,0 +1,5 @@ +# A minimal "good" Resource definition: has a name and numerator/unit. +name : 'minimal_good' +unit { + numerator : SECS +} diff --git a/test/core/census/data/resource_no_name.pb b/test/core/census/data/resource_no_name.pb new file mode 100644 index 00000000000..4d547445fae --- /dev/null +++ b/test/core/census/data/resource_no_name.pb @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/core/census/data/resource_no_name.txt b/test/core/census/data/resource_no_name.txt new file mode 100644 index 00000000000..8f12a91d35e --- /dev/null +++ b/test/core/census/data/resource_no_name.txt @@ -0,0 +1,4 @@ +# The minimal good Resource without a name. +unit { + numerator : SECS +} diff --git a/test/core/census/data/resource_no_numerator.pb b/test/core/census/data/resource_no_numerator.pb new file mode 100644 index 00000000000..2a5cceee70c --- /dev/null +++ b/test/core/census/data/resource_no_numerator.pb @@ -0,0 +1,2 @@ + +resource_no_numeratorýÿÿÿÿÿÿÿÿ \ No newline at end of file diff --git a/test/core/census/data/resource_no_numerator.txt b/test/core/census/data/resource_no_numerator.txt new file mode 100644 index 00000000000..fc1fec74a24 --- /dev/null +++ b/test/core/census/data/resource_no_numerator.txt @@ -0,0 +1,6 @@ +# Resource without a numerator +name : 'resource_no_numerator' +unit { + prefix : -3 + denominator : SECS +} diff --git a/test/core/census/data/resource_no_unit.pb b/test/core/census/data/resource_no_unit.pb new file mode 100644 index 00000000000..9dca2620e0a --- /dev/null +++ b/test/core/census/data/resource_no_unit.pb @@ -0,0 +1,2 @@ + +resource_no_unit \ No newline at end of file diff --git a/test/core/census/data/resource_no_unit.txt b/test/core/census/data/resource_no_unit.txt new file mode 100644 index 00000000000..c5d5115cebf --- /dev/null +++ b/test/core/census/data/resource_no_unit.txt @@ -0,0 +1,2 @@ +# The minimal good resource without a unit +name : 'resource_no_unit' diff --git a/test/core/census/resource_test.c b/test/core/census/resource_test.c new file mode 100644 index 00000000000..bfb76bcfb5e --- /dev/null +++ b/test/core/census/resource_test.c @@ -0,0 +1,157 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "src/core/ext/census/resource.h" +#include +#include +#include +#include +#include +#include +#include +#include "src/core/ext/census/base_resources.h" +#include "test/core/util/test_config.h" + +// Test all the functionality for dealing with Resources. + +// Just startup and shutdown resources subsystem. +static void test_enable_disable() { + initialize_resources(); + shutdown_resources(); +} + +// A blank/empty initialization should not work. +static void test_empty_definition() { + initialize_resources(); + int32_t rid = census_define_resource(NULL, 0); + GPR_ASSERT(rid == -1); + uint8_t buffer[50] = {0}; + rid = census_define_resource(buffer, 50); + GPR_ASSERT(rid == -1); + shutdown_resources(); +} + +// Given a file name, read raw proto and define the resource included within. +// Returns resource id from census_define_resource(). +static int32_t define_resource_from_file(const char *file) { + const size_t buf_size = 512; + uint8_t buffer[buf_size]; + FILE *input = fopen(file, "r"); + GPR_ASSERT(input != NULL); + size_t nbytes = fread(buffer, 1, buf_size, input); + GPR_ASSERT(nbytes != 0 && nbytes < buf_size); + int32_t rid = census_define_resource(buffer, nbytes); + GPR_ASSERT(fclose(input) == 0); + return rid; +} + +// Test definition of a single resource, using a proto read from a file. The +// `succeed` parameter indicates whether we expect the definition to succeed or +// fail. `name` is used to check that the returned resource can be looked up by +// name. +static void test_define_single_resource(const char *file, const char *name, + bool succeed) { + gpr_log(GPR_INFO, "Test defining resource \"%s\"\n", name); + initialize_resources(); + int32_t rid = define_resource_from_file(file); + if (succeed) { + GPR_ASSERT(rid >= 0); + int32_t rid2 = census_resource_id(name); + GPR_ASSERT(rid == rid2); + } else { + GPR_ASSERT(rid < 0); + } + shutdown_resources(); +} + +// Try deleting various resources (both those that exist and those that don't). +static void test_delete_resource() { + initialize_resources(); + // Try deleting resource before any are defined. + census_delete_resource(0); + // Create and check a couple of resources. + int32_t rid1 = define_resource_from_file( + "test/core/census/data/resource_minimal_good.pb"); + int32_t rid2 = + define_resource_from_file("test/core/census/data/resource_full.pb"); + GPR_ASSERT(rid1 >= 0 && rid2 >= 0 && rid1 != rid2); + int32_t rid3 = census_resource_id("minimal_good"); + int32_t rid4 = census_resource_id("full_resource"); + GPR_ASSERT(rid1 == rid3 && rid2 == rid4); + // Try deleting non-existant resources. + census_delete_resource(-1); + census_delete_resource(rid1 + rid2 + 1); + census_delete_resource(10000000); + // Delete one of the previously defined resources and check for deletion. + census_delete_resource(rid1); + rid3 = census_resource_id("minimal_good"); + GPR_ASSERT(rid3 < 0); + // Check that re-adding works. + rid1 = define_resource_from_file( + "test/core/census/data/resource_minimal_good.pb"); + GPR_ASSERT(rid1 >= 0); + rid3 = census_resource_id("minimal_good"); + GPR_ASSERT(rid1 == rid3); + shutdown_resources(); +} + +// Test define base resources. +static void test_base_resources() { + initialize_resources(); + define_base_resources(); + int32_t rid1 = census_resource_id("client_rpc_latency"); + int32_t rid2 = census_resource_id("server_rpc_latency"); + GPR_ASSERT(rid1 >= 0 && rid2 >= 0 && rid1 != rid2); + shutdown_resources(); +} + +int main(int argc, char **argv) { + grpc_test_init(argc, argv); + test_enable_disable(); + test_empty_definition(); + test_define_single_resource("test/core/census/data/resource_minimal_good.pb", + "minimal_good", true); + test_define_single_resource("test/core/census/data/resource_full.pb", + "full_resource", true); + test_define_single_resource("test/core/census/data/resource_no_name.pb", + "resource_no_name", false); + test_define_single_resource("test/core/census/data/resource_no_numerator.pb", + "resource_no_numerator", false); + test_define_single_resource("test/core/census/data/resource_no_unit.pb", + "resource_no_unit", false); + test_define_single_resource("test/core/census/data/resource_empty_name.pb", + "resource_empty_name", false); + test_delete_resource(); + test_base_resources(); + return 0; +} diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 7446fec8244..51007a5da96 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -932,11 +932,13 @@ third_party/nanopb/pb_common.h \ third_party/nanopb/pb_decode.h \ third_party/nanopb/pb_encode.h \ src/core/ext/census/aggregation.h \ +src/core/ext/census/base_resources.h \ src/core/ext/census/census_interface.h \ src/core/ext/census/census_rpc_stats.h \ src/core/ext/census/gen/census.pb.h \ src/core/ext/census/grpc_filter.h \ src/core/ext/census/mlog.h \ +src/core/ext/census/resource.h \ src/core/ext/census/rpc_metric_id.h \ src/core/lib/surface/init.c \ src/core/lib/channel/channel_args.c \ @@ -1105,6 +1107,7 @@ src/core/ext/lb_policy/pick_first/pick_first.c \ src/core/ext/lb_policy/round_robin/round_robin.c \ src/core/ext/resolver/dns/native/dns_resolver.c \ src/core/ext/resolver/sockaddr/sockaddr_resolver.c \ +src/core/ext/census/base_resources.c \ src/core/ext/census/context.c \ src/core/ext/census/gen/census.pb.c \ src/core/ext/census/grpc_context.c \ @@ -1114,6 +1117,7 @@ src/core/ext/census/initialize.c \ src/core/ext/census/mlog.c \ src/core/ext/census/operation.c \ src/core/ext/census/placeholders.c \ +src/core/ext/census/resource.c \ src/core/ext/census/tracing.c \ src/core/plugin_registry/grpc_plugin_registry.c \ include/grpc/support/alloc.h \ diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index e0471234954..28f54e7c9e2 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -109,6 +109,22 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "language": "c", + "name": "census_resource_test", + "src": [ + "test/core/census/resource_test.c" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -5296,11 +5312,13 @@ "headers": [ "include/grpc/census.h", "src/core/ext/census/aggregation.h", + "src/core/ext/census/base_resources.h", "src/core/ext/census/census_interface.h", "src/core/ext/census/census_rpc_stats.h", "src/core/ext/census/gen/census.pb.h", "src/core/ext/census/grpc_filter.h", "src/core/ext/census/mlog.h", + "src/core/ext/census/resource.h", "src/core/ext/census/rpc_metric_id.h" ], "language": "c", @@ -5308,6 +5326,8 @@ "src": [ "include/grpc/census.h", "src/core/ext/census/aggregation.h", + "src/core/ext/census/base_resources.c", + "src/core/ext/census/base_resources.h", "src/core/ext/census/census_interface.h", "src/core/ext/census/census_rpc_stats.h", "src/core/ext/census/context.c", @@ -5322,6 +5342,8 @@ "src/core/ext/census/mlog.h", "src/core/ext/census/operation.c", "src/core/ext/census/placeholders.c", + "src/core/ext/census/resource.c", + "src/core/ext/census/resource.h", "src/core/ext/census/rpc_metric_id.h", "src/core/ext/census/tracing.c" ], diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index 850f9474aec..a1946d27cf8 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -127,6 +127,27 @@ "windows" ] }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "census_resource_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, { "args": [], "ci_platforms": [ diff --git a/vsprojects/buildtests_c.sln b/vsprojects/buildtests_c.sln index be8b5d40ace..d94a43501e0 100644 --- a/vsprojects/buildtests_c.sln +++ b/vsprojects/buildtests_c.sln @@ -180,6 +180,17 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "census_context_test", "vcxp {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "census_resource_test", "vcxproj\test\census_resource_test\census_resource_test.vcxproj", "{18CF99B5-3C61-EC3D-9509-3C95334C3B88}" + ProjectSection(myProperties) = preProject + lib = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} + {29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9} + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "channel_create_test", "vcxproj\test\channel_create_test\channel_create_test.vcxproj", "{AFC88484-3A2E-32BC-25B2-23DF741D4F3D}" ProjectSection(myProperties) = preProject lib = "False" @@ -1707,6 +1718,22 @@ Global {5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release-DLL|Win32.Build.0 = Release|Win32 {5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release-DLL|x64.ActiveCfg = Release|x64 {5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release-DLL|x64.Build.0 = Release|x64 + {18CF99B5-3C61-EC3D-9509-3C95334C3B88}.Debug|Win32.ActiveCfg = Debug|Win32 + {18CF99B5-3C61-EC3D-9509-3C95334C3B88}.Debug|x64.ActiveCfg = Debug|x64 + {18CF99B5-3C61-EC3D-9509-3C95334C3B88}.Release|Win32.ActiveCfg = Release|Win32 + {18CF99B5-3C61-EC3D-9509-3C95334C3B88}.Release|x64.ActiveCfg = Release|x64 + {18CF99B5-3C61-EC3D-9509-3C95334C3B88}.Debug|Win32.Build.0 = Debug|Win32 + {18CF99B5-3C61-EC3D-9509-3C95334C3B88}.Debug|x64.Build.0 = Debug|x64 + {18CF99B5-3C61-EC3D-9509-3C95334C3B88}.Release|Win32.Build.0 = Release|Win32 + {18CF99B5-3C61-EC3D-9509-3C95334C3B88}.Release|x64.Build.0 = Release|x64 + {18CF99B5-3C61-EC3D-9509-3C95334C3B88}.Debug-DLL|Win32.ActiveCfg = Debug|Win32 + {18CF99B5-3C61-EC3D-9509-3C95334C3B88}.Debug-DLL|Win32.Build.0 = Debug|Win32 + {18CF99B5-3C61-EC3D-9509-3C95334C3B88}.Debug-DLL|x64.ActiveCfg = Debug|x64 + {18CF99B5-3C61-EC3D-9509-3C95334C3B88}.Debug-DLL|x64.Build.0 = Debug|x64 + {18CF99B5-3C61-EC3D-9509-3C95334C3B88}.Release-DLL|Win32.ActiveCfg = Release|Win32 + {18CF99B5-3C61-EC3D-9509-3C95334C3B88}.Release-DLL|Win32.Build.0 = Release|Win32 + {18CF99B5-3C61-EC3D-9509-3C95334C3B88}.Release-DLL|x64.ActiveCfg = Release|x64 + {18CF99B5-3C61-EC3D-9509-3C95334C3B88}.Release-DLL|x64.Build.0 = Release|x64 {AFC88484-3A2E-32BC-25B2-23DF741D4F3D}.Debug|Win32.ActiveCfg = Debug|Win32 {AFC88484-3A2E-32BC-25B2-23DF741D4F3D}.Debug|x64.ActiveCfg = Debug|x64 {AFC88484-3A2E-32BC-25B2-23DF741D4F3D}.Release|Win32.ActiveCfg = Release|Win32 diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj index 61a59e7c3f0..d5ac625eb22 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj @@ -441,11 +441,13 @@ + + @@ -783,6 +785,8 @@ + + @@ -801,6 +805,8 @@ + + diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters index 4bd436aa167..37b1f0993a8 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters @@ -502,6 +502,9 @@ src\core\ext\resolver\sockaddr + + src\core\ext\census + src\core\ext\census @@ -529,6 +532,9 @@ src\core\ext\census + + src\core\ext\census + src\core\ext\census @@ -1055,6 +1061,9 @@ src\core\ext\census + + src\core\ext\census + src\core\ext\census @@ -1070,6 +1079,9 @@ src\core\ext\census + + src\core\ext\census + src\core\ext\census diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj index e29a275d5ab..5bb261486e9 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj @@ -405,11 +405,13 @@ + + @@ -685,6 +687,8 @@ + + @@ -703,6 +707,8 @@ + + diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters index e5e4acc9a5d..3616227ac3e 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -409,6 +409,9 @@ src\core\ext\lb_policy\round_robin + + src\core\ext\census + src\core\ext\census @@ -436,6 +439,9 @@ src\core\ext\census + + src\core\ext\census + src\core\ext\census @@ -881,6 +887,9 @@ src\core\ext\census + + src\core\ext\census + src\core\ext\census @@ -896,6 +905,9 @@ src\core\ext\census + + src\core\ext\census + src\core\ext\census diff --git a/vsprojects/vcxproj/test/census_resource_test/census_resource_test.vcxproj b/vsprojects/vcxproj/test/census_resource_test/census_resource_test.vcxproj new file mode 100644 index 00000000000..c4fbd54e222 --- /dev/null +++ b/vsprojects/vcxproj/test/census_resource_test/census_resource_test.vcxproj @@ -0,0 +1,199 @@ + + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {18CF99B5-3C61-EC3D-9509-3C95334C3B88} + true + $(SolutionDir)IntDir\$(MSBuildProjectName)\ + + + + v100 + + + v110 + + + v120 + + + v140 + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + census_resource_test + static + Debug + static + Debug + + + census_resource_test + static + Release + static + Release + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + + + + + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} + + + {29D16885-7228-4C31-81ED-5F9187C7F2A9} + + + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + + + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + diff --git a/vsprojects/vcxproj/test/census_resource_test/census_resource_test.vcxproj.filters b/vsprojects/vcxproj/test/census_resource_test/census_resource_test.vcxproj.filters new file mode 100644 index 00000000000..93faac55d07 --- /dev/null +++ b/vsprojects/vcxproj/test/census_resource_test/census_resource_test.vcxproj.filters @@ -0,0 +1,21 @@ + + + + + test\core\census + + + + + + {313aad4e-d33b-88c5-7d94-e04a4cb0c912} + + + {ff2d74ef-228a-1739-7fa7-7dccbec5b0c5} + + + {4f529bd9-396f-027c-bc49-f9a6bbc97c72} + + + + From 7a97fe2c10e5b55c5f28f7031c2c67fc47581e09 Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Fri, 3 Jun 2016 12:10:45 -0700 Subject: [PATCH 008/279] use macro rather than constant in array size --- test/core/census/resource_test.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/core/census/resource_test.c b/test/core/census/resource_test.c index bfb76bcfb5e..1375d56a6bc 100644 --- a/test/core/census/resource_test.c +++ b/test/core/census/resource_test.c @@ -64,12 +64,12 @@ static void test_empty_definition() { // Given a file name, read raw proto and define the resource included within. // Returns resource id from census_define_resource(). static int32_t define_resource_from_file(const char *file) { - const size_t buf_size = 512; - uint8_t buffer[buf_size]; +#define BUF_SIZE 512 + uint8_t buffer[BUF_SIZE]; FILE *input = fopen(file, "r"); GPR_ASSERT(input != NULL); - size_t nbytes = fread(buffer, 1, buf_size, input); - GPR_ASSERT(nbytes != 0 && nbytes < buf_size); + size_t nbytes = fread(buffer, 1, BUF_SIZE, input); + GPR_ASSERT(nbytes != 0 && nbytes < BUF_SIZE); int32_t rid = census_define_resource(buffer, nbytes); GPR_ASSERT(fclose(input) == 0); return rid; From 4eb67b47a0918f5633585cfc3335476139d37685 Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Fri, 3 Jun 2016 15:45:04 -0700 Subject: [PATCH 009/279] Proto tweaks --- src/core/ext/census/gen/census.pb.c | 25 +++++++------ src/core/ext/census/gen/census.pb.h | 49 ++++++++++++++++--------- src/proto/census/census.proto | 57 ++++++++++++++++++----------- 3 files changed, 82 insertions(+), 49 deletions(-) diff --git a/src/core/ext/census/gen/census.pb.c b/src/core/ext/census/gen/census.pb.c index c73c2c9b7cc..647f0635b74 100644 --- a/src/core/ext/census/gen/census.pb.c +++ b/src/core/ext/census/gen/census.pb.c @@ -67,9 +67,10 @@ const pb_field_t google_census_Resource_MeasurementUnit_fields[4] = { PB_LAST_FIELD }; -const pb_field_t google_census_AggregationDescriptor_fields[3] = { - PB_ONEOF_FIELD(options, 1, MESSAGE , ONEOF, STATIC , FIRST, google_census_AggregationDescriptor, bucket_boundaries, bucket_boundaries, &google_census_AggregationDescriptor_BucketBoundaries_fields), - PB_ONEOF_FIELD(options, 2, MESSAGE , ONEOF, STATIC , FIRST, google_census_AggregationDescriptor, interval_boundaries, interval_boundaries, &google_census_AggregationDescriptor_IntervalBoundaries_fields), +const pb_field_t google_census_AggregationDescriptor_fields[4] = { + PB_FIELD( 1, UENUM , OPTIONAL, STATIC , FIRST, google_census_AggregationDescriptor, type, type, 0), + PB_ONEOF_FIELD(options, 2, MESSAGE , ONEOF, STATIC , OTHER, google_census_AggregationDescriptor, bucket_boundaries, type, &google_census_AggregationDescriptor_BucketBoundaries_fields), + PB_ONEOF_FIELD(options, 3, MESSAGE , ONEOF, STATIC , OTHER, google_census_AggregationDescriptor, interval_boundaries, type, &google_census_AggregationDescriptor_IntervalBoundaries_fields), PB_LAST_FIELD }; @@ -124,19 +125,21 @@ const pb_field_t google_census_View_fields[6] = { PB_LAST_FIELD }; -const pb_field_t google_census_Aggregation_fields[6] = { +const pb_field_t google_census_Aggregation_fields[7] = { PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, google_census_Aggregation, name, name, 0), PB_FIELD( 2, STRING , OPTIONAL, CALLBACK, OTHER, google_census_Aggregation, description, name, 0), - PB_ONEOF_FIELD(data, 3, MESSAGE , ONEOF, STATIC , OTHER, google_census_Aggregation, distribution, description, &google_census_Distribution_fields), - PB_ONEOF_FIELD(data, 4, MESSAGE , ONEOF, STATIC , OTHER, google_census_Aggregation, interval_stats, description, &google_census_IntervalStats_fields), - PB_FIELD( 5, MESSAGE , REPEATED, CALLBACK, OTHER, google_census_Aggregation, tag, data.interval_stats, &google_census_Tag_fields), + PB_ONEOF_FIELD(data, 3, UINT64 , ONEOF, STATIC , OTHER, google_census_Aggregation, count, description, 0), + PB_ONEOF_FIELD(data, 4, MESSAGE , ONEOF, STATIC , OTHER, google_census_Aggregation, distribution, description, &google_census_Distribution_fields), + PB_ONEOF_FIELD(data, 5, MESSAGE , ONEOF, STATIC , OTHER, google_census_Aggregation, interval_stats, description, &google_census_IntervalStats_fields), + PB_FIELD( 6, MESSAGE , REPEATED, CALLBACK, OTHER, google_census_Aggregation, tag, data.interval_stats, &google_census_Tag_fields), PB_LAST_FIELD }; -const pb_field_t google_census_Metric_fields[4] = { - PB_FIELD( 1, MESSAGE , REPEATED, CALLBACK, FIRST, google_census_Metric, aggregation, aggregation, &google_census_Aggregation_fields), - PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_Metric, start, aggregation, &google_census_Timestamp_fields), - PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_Metric, end, start, &google_census_Timestamp_fields), +const pb_field_t google_census_Metric_fields[5] = { + PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, google_census_Metric, view_name, view_name, 0), + PB_FIELD( 2, MESSAGE , REPEATED, CALLBACK, OTHER, google_census_Metric, aggregation, view_name, &google_census_Aggregation_fields), + PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_Metric, start, aggregation, &google_census_Timestamp_fields), + PB_FIELD( 4, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_Metric, end, start, &google_census_Timestamp_fields), PB_LAST_FIELD }; diff --git a/src/core/ext/census/gen/census.pb.h b/src/core/ext/census/gen/census.pb.h index dfb53948204..dae583f33d3 100644 --- a/src/core/ext/census/gen/census.pb.h +++ b/src/core/ext/census/gen/census.pb.h @@ -54,6 +54,13 @@ typedef enum _google_census_Resource_BasicUnit { google_census_Resource_BasicUnit_MAX_UNITS = 5 } google_census_Resource_BasicUnit; +typedef enum _google_census_AggregationDescriptor_AggregationType { + google_census_AggregationDescriptor_AggregationType_UNKNOWN = 0, + google_census_AggregationDescriptor_AggregationType_COUNT = 1, + google_census_AggregationDescriptor_AggregationType_DISTRIBUTION = 2, + google_census_AggregationDescriptor_AggregationType_INTERVAL = 3 +} google_census_AggregationDescriptor_AggregationType; + /* Struct definitions */ typedef struct _google_census_AggregationDescriptor_BucketBoundaries { pb_callback_t bounds; @@ -68,6 +75,8 @@ typedef struct _google_census_IntervalStats { } google_census_IntervalStats; typedef struct _google_census_AggregationDescriptor { + bool has_type; + google_census_AggregationDescriptor_AggregationType type; pb_size_t which_options; union { google_census_AggregationDescriptor_BucketBoundaries bucket_boundaries; @@ -130,6 +139,7 @@ typedef struct _google_census_IntervalStats_Window { } google_census_IntervalStats_Window; typedef struct _google_census_Metric { + pb_callback_t view_name; pb_callback_t aggregation; bool has_start; google_census_Timestamp start; @@ -158,6 +168,7 @@ typedef struct _google_census_Aggregation { pb_callback_t description; pb_size_t which_data; union { + uint64_t count; google_census_Distribution distribution; google_census_IntervalStats interval_stats; } data; @@ -171,7 +182,7 @@ typedef struct _google_census_Aggregation { #define google_census_Timestamp_init_default {false, 0, false, 0} #define google_census_Resource_init_default {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Resource_MeasurementUnit_init_default} #define google_census_Resource_MeasurementUnit_init_default {false, 0, {{NULL}, NULL}, {{NULL}, NULL}} -#define google_census_AggregationDescriptor_init_default {0, {google_census_AggregationDescriptor_BucketBoundaries_init_default}} +#define google_census_AggregationDescriptor_init_default {false, (google_census_AggregationDescriptor_AggregationType)0, 0, {google_census_AggregationDescriptor_BucketBoundaries_init_default}} #define google_census_AggregationDescriptor_BucketBoundaries_init_default {{{NULL}, NULL}} #define google_census_AggregationDescriptor_IntervalBoundaries_init_default {{{NULL}, NULL}} #define google_census_Distribution_init_default {false, 0, false, 0, false, google_census_Distribution_Range_init_default, {{NULL}, NULL}} @@ -180,13 +191,13 @@ typedef struct _google_census_Aggregation { #define google_census_IntervalStats_Window_init_default {false, google_census_Duration_init_default, false, 0, false, 0} #define google_census_Tag_init_default {false, "", false, ""} #define google_census_View_init_default {{{NULL}, NULL}, {{NULL}, NULL}, {{NULL}, NULL}, false, google_census_AggregationDescriptor_init_default, {{NULL}, NULL}} -#define google_census_Aggregation_init_default {{{NULL}, NULL}, {{NULL}, NULL}, 0, {google_census_Distribution_init_default}, {{NULL}, NULL}} -#define google_census_Metric_init_default {{{NULL}, NULL}, false, google_census_Timestamp_init_default, false, google_census_Timestamp_init_default} +#define google_census_Aggregation_init_default {{{NULL}, NULL}, {{NULL}, NULL}, 0, {0}, {{NULL}, NULL}} +#define google_census_Metric_init_default {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Timestamp_init_default, false, google_census_Timestamp_init_default} #define google_census_Duration_init_zero {false, 0, false, 0} #define google_census_Timestamp_init_zero {false, 0, false, 0} #define google_census_Resource_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Resource_MeasurementUnit_init_zero} #define google_census_Resource_MeasurementUnit_init_zero {false, 0, {{NULL}, NULL}, {{NULL}, NULL}} -#define google_census_AggregationDescriptor_init_zero {0, {google_census_AggregationDescriptor_BucketBoundaries_init_zero}} +#define google_census_AggregationDescriptor_init_zero {false, (google_census_AggregationDescriptor_AggregationType)0, 0, {google_census_AggregationDescriptor_BucketBoundaries_init_zero}} #define google_census_AggregationDescriptor_BucketBoundaries_init_zero {{{NULL}, NULL}} #define google_census_AggregationDescriptor_IntervalBoundaries_init_zero {{{NULL}, NULL}} #define google_census_Distribution_init_zero {false, 0, false, 0, false, google_census_Distribution_Range_init_zero, {{NULL}, NULL}} @@ -195,16 +206,17 @@ typedef struct _google_census_Aggregation { #define google_census_IntervalStats_Window_init_zero {false, google_census_Duration_init_zero, false, 0, false, 0} #define google_census_Tag_init_zero {false, "", false, ""} #define google_census_View_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, {{NULL}, NULL}, false, google_census_AggregationDescriptor_init_zero, {{NULL}, NULL}} -#define google_census_Aggregation_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, 0, {google_census_Distribution_init_zero}, {{NULL}, NULL}} -#define google_census_Metric_init_zero {{{NULL}, NULL}, false, google_census_Timestamp_init_zero, false, google_census_Timestamp_init_zero} +#define google_census_Aggregation_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, 0, {0}, {{NULL}, NULL}} +#define google_census_Metric_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Timestamp_init_zero, false, google_census_Timestamp_init_zero} /* Field tags (for use in manual encoding/decoding) */ #define google_census_AggregationDescriptor_BucketBoundaries_bounds_tag 1 #define google_census_AggregationDescriptor_IntervalBoundaries_window_size_tag 1 #define google_census_IntervalStats_window_tag 1 -#define google_census_AggregationDescriptor_bucket_boundaries_tag 1 +#define google_census_AggregationDescriptor_bucket_boundaries_tag 2 -#define google_census_AggregationDescriptor_interval_boundaries_tag 2 +#define google_census_AggregationDescriptor_interval_boundaries_tag 3 +#define google_census_AggregationDescriptor_type_tag 1 #define google_census_Distribution_Range_min_tag 1 #define google_census_Distribution_Range_max_tag 2 #define google_census_Duration_seconds_tag 1 @@ -223,9 +235,10 @@ typedef struct _google_census_Aggregation { #define google_census_IntervalStats_Window_window_size_tag 1 #define google_census_IntervalStats_Window_count_tag 2 #define google_census_IntervalStats_Window_mean_tag 3 -#define google_census_Metric_aggregation_tag 1 -#define google_census_Metric_start_tag 2 -#define google_census_Metric_end_tag 3 +#define google_census_Metric_view_name_tag 1 +#define google_census_Metric_aggregation_tag 2 +#define google_census_Metric_start_tag 3 +#define google_census_Metric_end_tag 4 #define google_census_Resource_name_tag 1 #define google_census_Resource_description_tag 2 #define google_census_Resource_unit_tag 3 @@ -234,19 +247,21 @@ typedef struct _google_census_Aggregation { #define google_census_View_resource_name_tag 3 #define google_census_View_aggregation_tag 4 #define google_census_View_tag_key_tag 5 -#define google_census_Aggregation_distribution_tag 3 +#define google_census_Aggregation_count_tag 3 + +#define google_census_Aggregation_distribution_tag 4 -#define google_census_Aggregation_interval_stats_tag 4 +#define google_census_Aggregation_interval_stats_tag 5 #define google_census_Aggregation_name_tag 1 #define google_census_Aggregation_description_tag 2 -#define google_census_Aggregation_tag_tag 5 +#define google_census_Aggregation_tag_tag 6 /* Struct field encoding specification for nanopb */ extern const pb_field_t google_census_Duration_fields[3]; extern const pb_field_t google_census_Timestamp_fields[3]; extern const pb_field_t google_census_Resource_fields[4]; extern const pb_field_t google_census_Resource_MeasurementUnit_fields[4]; -extern const pb_field_t google_census_AggregationDescriptor_fields[3]; +extern const pb_field_t google_census_AggregationDescriptor_fields[4]; extern const pb_field_t google_census_AggregationDescriptor_BucketBoundaries_fields[2]; extern const pb_field_t google_census_AggregationDescriptor_IntervalBoundaries_fields[2]; extern const pb_field_t google_census_Distribution_fields[5]; @@ -255,8 +270,8 @@ extern const pb_field_t google_census_IntervalStats_fields[2]; extern const pb_field_t google_census_IntervalStats_Window_fields[4]; extern const pb_field_t google_census_Tag_fields[3]; extern const pb_field_t google_census_View_fields[6]; -extern const pb_field_t google_census_Aggregation_fields[6]; -extern const pb_field_t google_census_Metric_fields[4]; +extern const pb_field_t google_census_Aggregation_fields[7]; +extern const pb_field_t google_census_Metric_fields[5]; /* Maximum encoded size of messages (where known) */ #define google_census_Duration_size 22 diff --git a/src/proto/census/census.proto b/src/proto/census/census.proto index 56c291ff17c..c2a594b6415 100644 --- a/src/proto/census/census.proto +++ b/src/proto/census/census.proto @@ -121,7 +121,7 @@ message Resource { // denominator: SECS // denominator: SECS // - // To specify multiples (in power of 10) units, specify a non-zero prefix + // To specify multiples (in power of 10) of units, specify a non-zero prefix // value, for example: // // - MB/s (i.e. megabytes / s): @@ -145,22 +145,33 @@ message Resource { // An Aggregation summarizes a series of individual Resource measurements, an // AggregationDescriptor describes an Aggregation. message AggregationDescriptor { - // At most one set of options. If neither option is set, a default type - // of Distribution (without a histogram component) will be used. + enum AggregationType { + // Unspecified. Should not be used. + UNKNOWN = 0; + // A count of measurements made. + COUNT = 1; + // A Distribution. + DISTRIBUTION = 2; + // Counts over fixed time intervals. + INTERVAL = 3; + } + // The type of Aggregation. + AggregationType type = 1; + + // At most one set of options. It is illegal to specifiy an option for + // COUNT Aggregations. interval_boundaries must be set for INTERVAL types. + // bucket_boundaries are optional for DISTRIBUTION types. oneof options { - // Defines the histogram bucket boundaries for Distributions. - BucketBoundaries bucket_boundaries = 1; + // Defines histogram bucket boundaries for Distributions. + BucketBoundaries bucket_boundaries = 2; // Defines the time windows to record for IntervalStats. - IntervalBoundaries interval_boundaries = 2; + IntervalBoundaries interval_boundaries = 3; } // A Distribution may optionally contain a histogram of the values in the - // population. The bucket boundaries for that histogram is described by - // `bucket_boundaries`. - // - // Describes histogram bucket boundaries. Defines `size(bounds) + 1` (= N) - // buckets (for size(bounds) >= 1; if size(bounds) == 0, then no histogram - // will be defined. The boundaries for bucket index i are: + // population. The bucket boundaries for that histogram are described by + // `bucket_boundaries`. This defines `size(bounds) + 1` (= N) buckets. The + // boundaries for bucket index i are: // // [-infinity, bounds[i]) for i == 0 // [bounds[i-1], bounds[i]) for 0 < i < N-2 @@ -190,8 +201,8 @@ message AggregationDescriptor { // a specified set of histogram buckets, as defined in // Aggregation.bucket_options. // -// The summary statistics are the count, mean, sum of the squared deviation from -// the mean, the minimum, and the maximum of the set of population of values. +// The summary statistics are the count, mean, minimum, and the maximum of the +// set of population of values. // // Although it is not forbidden, it is generally a bad idea to include // non-finite values (infinities or NaNs) in the population of values, as this @@ -237,7 +248,7 @@ message Distribution { message IntervalStats { // Summary statistic over a single time window. message Window { - // The window duration. + // The window duration. Must be positive. Duration window_size = 1; // The number of measurements in this window. int64 count = 2; @@ -285,23 +296,27 @@ message Aggregation { // The data for this Aggregation. oneof data { - Distribution distribution = 3; - IntervalStats interval_stats = 4; + uint64 count = 3; + Distribution distribution = 4; + IntervalStats interval_stats = 5; } // Tags associated with this Aggregation. - repeated Tag tag = 5; + repeated Tag tag = 6; } // A Metric represents all the Aggregations for a particular view. message Metric { + // View associated with this Metric. + string view_name = 1; + // Aggregations - each will have a unique set of tag values for the tag_keys // associated with the corresponding View. - repeated Aggregation aggregation = 1; + repeated Aggregation aggregation = 2; // Start and end timestamps over which the metric was accumulated. These // values are not relevant/defined for IntervalStats aggregations, which are // always accumulated over a fixed time period. - Timestamp start = 2; - Timestamp end = 3; + Timestamp start = 3; + Timestamp end = 4; } From 0cf4defa42dfd0e1f09ea3e1fae7c111a673244f Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Tue, 7 Jun 2016 08:59:30 -0700 Subject: [PATCH 010/279] simplify base resource definition; misc comment updates --- src/core/ext/census/base_resources.c | 119 ++++------------------ src/core/ext/census/base_resources.h | 4 +- src/core/ext/census/resource.c | 142 +++++++++++++++++++-------- src/core/ext/census/resource.h | 29 +++++- 4 files changed, 148 insertions(+), 146 deletions(-) diff --git a/src/core/ext/census/base_resources.c b/src/core/ext/census/base_resources.c index 8f0329a72bd..f1ee41c5d97 100644 --- a/src/core/ext/census/base_resources.c +++ b/src/core/ext/census/base_resources.c @@ -30,15 +30,15 @@ * */ +#include "base_resources.h" + #include #include #include #include -#include "base_resources.h" -#include "gen/census.pb.h" -#include "third_party/nanopb/pb_encode.h" +#include "resource.h" // Add base RPC resource definitions for use by RPC runtime. // @@ -48,101 +48,24 @@ // file, which is compiled to .pb format and read by still-to-be-written // configuration functions. -// Structure representing a MeasurementUnit proto. -typedef struct { - int32_t prefix; - int n_numerators; - const google_census_Resource_BasicUnit *numerators; - int n_denominators; - const google_census_Resource_BasicUnit *denominators; -} measurement_unit; - -// Encode a nanopb string. Expects the string argument to be passed in as `arg`. -static bool encode_string(pb_ostream_t *stream, const pb_field_t *field, - void *const *arg) { - if (!pb_encode_tag_for_field(stream, field)) { - return false; - } - return pb_encode_string(stream, (uint8_t *)*arg, strlen((const char *)*arg)); -} - -// Encode the numerators part of a measurement_unit (passed in as `arg`). -static bool encode_numerators(pb_ostream_t *stream, const pb_field_t *field, - void *const *arg) { - const measurement_unit *mu = (const measurement_unit *)*arg; - for (int i = 0; i < mu->n_numerators; i++) { - if (!pb_encode_tag_for_field(stream, field)) { - return false; - } - if (!pb_encode_varint(stream, mu->numerators[i])) { - return false; - } - } - return true; -} - -// Encode the denominators part of a measurement_unit (passed in as `arg`). -static bool encode_denominators(pb_ostream_t *stream, const pb_field_t *field, - void *const *arg) { - const measurement_unit *mu = (const measurement_unit *)*arg; - for (int i = 0; i < mu->n_denominators; i++) { - if (!pb_encode_tag_for_field(stream, field)) { - return false; - } - if (!pb_encode_varint(stream, mu->numerators[i])) { - return false; - } - } - return true; -} - -// Define a Resource, given the important details. Encodes a protobuf, which -// is then passed to census_define_resource. -static void define_resource(const char *name, const char *description, - const measurement_unit *unit) { - // nanopb generated type for Resource. Initialize encoding functions to NULL - // since we can't directly initialize them due to embedded union in struct. - google_census_Resource resource = { - {{NULL}, (void *)name}, - {{NULL}, (void *)description}, - true, // has_unit - {true, unit->prefix, {{NULL}, (void *)unit}, {{NULL}, (void *)unit}}}; - resource.name.funcs.encode = &encode_string; - resource.description.funcs.encode = &encode_string; - resource.unit.numerator.funcs.encode = &encode_numerators; - resource.unit.denominator.funcs.encode = &encode_denominators; - - // Buffer for storing encoded proto. - uint8_t buffer[512]; - pb_ostream_t stream = pb_ostream_from_buffer(buffer, 512); - if (!pb_encode(&stream, google_census_Resource_fields, &resource)) { - gpr_log(GPR_ERROR, "Error encoding resource %s.", name); - return; - } - int32_t mid = census_define_resource(buffer, stream.bytes_written); - if (mid < 0) { - gpr_log(GPR_ERROR, "Error defining resource %s.", name); - } -} - -// Define a resource for client RPC latency. -static void define_client_rpc_latency_resource() { - google_census_Resource_BasicUnit numerator = - google_census_Resource_BasicUnit_SECS; - measurement_unit unit = {0, 1, &numerator, 0, NULL}; - define_resource("client_rpc_latency", "Client RPC latency in seconds", &unit); -} - -// Define a resource for server RPC latency. -static void define_server_rpc_latency_resource() { - google_census_Resource_BasicUnit numerator = - google_census_Resource_BasicUnit_SECS; - measurement_unit unit = {0, 1, &numerator, 0, NULL}; - define_resource("server_rpc_latency", "Server RPC latency in seconds", &unit); -} - // Define all base resources. This should be called by census initialization. void define_base_resources() { - define_client_rpc_latency_resource(); - define_server_rpc_latency_resource(); + google_census_Resource_BasicUnit numerator = + google_census_Resource_BasicUnit_SECS; + resource r = {"client_rpc_latency", // name + "Client RPC latency in seconds", // description + 0, // prefix + 1, // n_numerators + &numerator, // numerators + 0, // n_denominators + NULL}; // denominators + define_resource(&r); + r = (resource){"server_rpc_latency", // name + "Server RPC latency in seconds", // description + 0, // prefix + 1, // n_numerators + &numerator, // numerators + 0, // n_denominators + NULL}; // denominators + define_resource(&r); } diff --git a/src/core/ext/census/base_resources.h b/src/core/ext/census/base_resources.h index 992e5f6ebea..e5a7696db43 100644 --- a/src/core/ext/census/base_resources.h +++ b/src/core/ext/census/base_resources.h @@ -33,7 +33,7 @@ #ifndef GRPC_CORE_EXT_CENSUS_BASE_RESOURCES_H #define GRPC_CORE_EXT_CENSUS_BASE_RESOURCES_H -// Define all base resources. This should be called by census initialization. +/* Define all base resources. This should be called by census initialization. */ void define_base_resources(); -#endif // GRPC_CORE_EXT_CENSUS_BASE_RESOURCES_H +#endif /* GRPC_CORE_EXT_CENSUS_BASE_RESOURCES_H */ diff --git a/src/core/ext/census/resource.c b/src/core/ext/census/resource.c index 632b899e415..0ca0db94bad 100644 --- a/src/core/ext/census/resource.c +++ b/src/core/ext/census/resource.c @@ -32,7 +32,6 @@ */ #include "resource.h" -#include "gen/census.pb.h" #include "third_party/nanopb/pb_decode.h" #include @@ -43,13 +42,6 @@ #include #include -// Internal representation of a resource. -typedef struct { - char *name; - // Pointer to raw protobuf used in resource definition. - uint8_t *raw_pb; -} resource; - // Protect local resource data structures. static gpr_mu resource_lock; @@ -65,7 +57,7 @@ static size_t n_resources = 0; // Number of defined resources static size_t n_defined_resources = 0; -void initialize_resources() { +void initialize_resources(void) { gpr_mu_init(&resource_lock); gpr_mu_lock(&resource_lock); GPR_ASSERT(resources == NULL && n_resources == 0 && n_defined_resources == 0); @@ -78,16 +70,17 @@ void initialize_resources() { // Delete a resource given it's ID. Must be called with resource_lock held. static void delete_resource_locked(size_t rid) { - GPR_ASSERT(resources[rid] != NULL && resources[rid]->raw_pb != NULL && - resources[rid]->name != NULL && n_defined_resources > 0); + GPR_ASSERT(resources[rid] != NULL); gpr_free(resources[rid]->name); - gpr_free(resources[rid]->raw_pb); + gpr_free(resources[rid]->description); + gpr_free(resources[rid]->numerators); + gpr_free(resources[rid]->denominators); gpr_free(resources[rid]); resources[rid] = NULL; n_defined_resources--; } -void shutdown_resources() { +void shutdown_resources(void) { gpr_mu_lock(&resource_lock); for (size_t i = 0; i < n_resources; i++) { if (resources[i] != NULL) { @@ -128,8 +121,13 @@ static bool validate_string(pb_istream_t *stream, const pb_field_t *field, } break; case google_census_Resource_description_tag: - // Description is optional, does not need validating, just skip. - if (!pb_read(stream, NULL, stream->bytes_left)) { + if (stream->bytes_left == 0) { + return true; + } + vresource->description = gpr_malloc(stream->bytes_left + 1); + vresource->description[stream->bytes_left] = '\0'; + if (!pb_read(stream, (uint8_t *)vresource->description, + stream->bytes_left)) { return false; } break; @@ -144,17 +142,47 @@ static bool validate_string(pb_istream_t *stream, const pb_field_t *field, return true; } +// Decode numerators/denominators in a stream. The `count` and `bup` +// (BasicUnit pointer) are pointers to the approriate fields in a resource +// struct. +static bool validate_units_helper(pb_istream_t *stream, int *count, + google_census_Resource_BasicUnit **bup) { + while (stream->bytes_left) { + (*count)++; + // Have to allocate a new array of values. Normal case is 0 or 1, so + // this should normally not be an issue. + google_census_Resource_BasicUnit *new_bup = + gpr_malloc((size_t)*count * sizeof(google_census_Resource_BasicUnit)); + if (*count != 1) { + memcpy(new_bup, *bup, + (size_t)(*count - 1) * sizeof(google_census_Resource_BasicUnit)); + gpr_free(*bup); + } + *bup = new_bup; + if (!pb_decode_varint(stream, (uint64_t *)(*bup + *count - 1))) { + return false; + } + } + return true; +} + // Validate units field of a Resource proto. static bool validate_units(pb_istream_t *stream, const pb_field_t *field, void **arg) { - if (field->tag == google_census_Resource_MeasurementUnit_numerator_tag) { - *(bool *)*arg = true; // has_numerator = true. - } - while (stream->bytes_left) { - uint64_t value; - if (!pb_decode_varint(stream, &value)) { + resource *vresource = (resource *)(*arg); + switch (field->tag) { + case google_census_Resource_MeasurementUnit_numerator_tag: + return validate_units_helper(stream, &vresource->n_numerators, + &vresource->numerators); + break; + case google_census_Resource_MeasurementUnit_denominator_tag: + return validate_units_helper(stream, &vresource->n_denominators, + &vresource->denominators); + break; + default: + gpr_log(GPR_ERROR, "Unknown field type."); return false; - } + break; } return true; } @@ -170,10 +198,11 @@ static bool validate_resource_pb(const uint8_t *resource_pb, vresource.name.funcs.decode = &validate_string; vresource.name.arg = resources[id]; vresource.description.funcs.decode = &validate_string; + vresource.description.arg = resources[id]; vresource.unit.numerator.funcs.decode = &validate_units; - bool has_numerator = false; - vresource.unit.numerator.arg = &has_numerator; + vresource.unit.numerator.arg = resources[id]; vresource.unit.denominator.funcs.decode = &validate_units; + vresource.unit.denominator.arg = resources[id]; pb_istream_t stream = pb_istream_from_buffer((uint8_t *)resource_pb, resource_pb_size); @@ -181,17 +210,15 @@ static bool validate_resource_pb(const uint8_t *resource_pb, return false; } // A Resource must have a name, a unit, with at least one numerator. - return (resources[id]->name != NULL && vresource.has_unit && has_numerator); + return (resources[id]->name != NULL && vresource.has_unit && + resources[id]->n_numerators > 0); } -int32_t census_define_resource(const uint8_t *resource_pb, - size_t resource_pb_size) { +// Allocate a blank resource, and return associated ID. Must be called with +// resource_lock held. +size_t allocate_resource(void) { // use next_id to optimize expected placement of next new resource. static size_t next_id = 0; - if (resource_pb == NULL) { - return -1; - } - gpr_mu_lock(&resource_lock); size_t id = n_resources; // resource ID - initialize to invalid value. // Expand resources if needed. if (n_resources == n_defined_resources) { @@ -212,22 +239,25 @@ int32_t census_define_resource(const uint8_t *resource_pb, } GPR_ASSERT(id < n_resources && resources[id] == NULL); resources[id] = gpr_malloc(sizeof(resource)); - resources[id]->name = NULL; + memset(resources[id], 0, sizeof(resource)); + n_defined_resources++; + next_id = (id + 1) % n_resources; + return id; +} + +int32_t census_define_resource(const uint8_t *resource_pb, + size_t resource_pb_size) { + if (resource_pb == NULL) { + return -1; + } + gpr_mu_lock(&resource_lock); + size_t id = allocate_resource(); // Validate pb, extract name. if (!validate_resource_pb(resource_pb, resource_pb_size, id)) { - if (resources[id]->name != NULL) { - gpr_free(resources[id]->name); - } - gpr_free(resources[id]); - resources[id] = NULL; + delete_resource_locked(id); gpr_mu_unlock(&resource_lock); return -1; } - next_id = (id + 1) % n_resources; - // Make copy of raw proto, and return. - resources[id]->raw_pb = gpr_malloc(resource_pb_size); - memcpy(resources[id]->raw_pb, resource_pb, resource_pb_size); - n_defined_resources++; gpr_mu_unlock(&resource_lock); return (int32_t)id; } @@ -253,3 +283,31 @@ int32_t census_resource_id(const char *name) { gpr_mu_unlock(&resource_lock); return -1; } + +int32_t define_resource(const resource *base) { + GPR_ASSERT(base != NULL && base->name != NULL && base->n_numerators > 0 && + base->numerators != NULL); + gpr_mu_lock(&resource_lock); + size_t id = allocate_resource(); + size_t len = strlen(base->name) + 1; + resources[id]->name = gpr_malloc(len); + memcpy(resources[id]->name, base->name, len); + if (base->description) { + len = strlen(base->description); + resources[id]->description = gpr_malloc(len); + memcpy(resources[id]->description, base->description, len); + } + resources[id]->prefix = base->prefix; + resources[id]->n_numerators = base->n_numerators; + len = (size_t)base->n_numerators * sizeof(*base->numerators); + resources[id]->numerators = gpr_malloc(len); + memcpy(resources[id]->numerators, base->numerators, len); + resources[id]->n_denominators = base->n_denominators; + if (base->n_denominators != 0) { + len = (size_t)base->n_denominators * sizeof(*base->denominators); + resources[id]->denominators = gpr_malloc(len); + memcpy(resources[id]->denominators, base->denominators, len); + } + gpr_mu_unlock(&resource_lock); + return (int32_t)id; +} diff --git a/src/core/ext/census/resource.h b/src/core/ext/census/resource.h index 5ad5a0f7a0c..a0669f3a39b 100644 --- a/src/core/ext/census/resource.h +++ b/src/core/ext/census/resource.h @@ -31,12 +31,33 @@ * */ -// Census-internal resource definition and manipluation functions. +/* Census-internal resource definition and manipluation functions. */ #ifndef GRPC_CORE_EXT_CENSUS_RESOURCE_H #define GRPC_CORE_EXT_CENSUS_RESOURCE_H -// Initialize and shutdown the resources subsystem. -void initialize_resources(); -void shutdown_resources(); +#include +#include "gen/census.pb.h" + +/* Internal representation of a resource. */ +typedef struct { + char *name; + char *description; + int32_t prefix; + int n_numerators; + google_census_Resource_BasicUnit *numerators; + int n_denominators; + google_census_Resource_BasicUnit *denominators; +} resource; + +/* Initialize and shutdown the resources subsystem. */ +void initialize_resources(void); +void shutdown_resources(void); + +/* Add a new resource, given a proposed resource structure. Returns the + resource ID, or -ve on failure. + TODO(aveitch): this function exists to support addition of the base + resources. It should be removed when we have the ability to add resources + from configuration files. */ +int32_t define_resource(const resource *base); #endif /* GRPC_CORE_EXT_CENSUS_RESOURCE_H */ From ec0bc8b4ed4760ff0ab1e51d505f1b235fc9d60d Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 15 Jun 2016 14:02:57 -0700 Subject: [PATCH 011/279] Initial attempt at a C++ API for defining channel filters. --- BUILD | 4 + Makefile | 4 + build.yaml | 2 + include/grpc++/channel_filter.h | 211 ++++++++++++++++++ src/cpp/common/channel_filter.cc | 98 ++++++++ tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 2 + tools/run_tests/sources_and_headers.json | 3 + vsprojects/vcxproj/grpc++/grpc++.vcxproj | 3 + .../vcxproj/grpc++/grpc++.vcxproj.filters | 6 + .../grpc++_unsecure/grpc++_unsecure.vcxproj | 3 + .../grpc++_unsecure.vcxproj.filters | 6 + 12 files changed, 343 insertions(+) create mode 100644 include/grpc++/channel_filter.h create mode 100644 src/cpp/common/channel_filter.cc diff --git a/BUILD b/BUILD index f049e3c4056..2940fed33f2 100644 --- a/BUILD +++ b/BUILD @@ -1247,6 +1247,7 @@ cc_library( "src/cpp/client/generic_stub.cc", "src/cpp/client/insecure_credentials.cc", "src/cpp/common/channel_arguments.cc", + "src/cpp/common/channel_filter.cc", "src/cpp/common/completion_queue.cc", "src/cpp/common/core_codegen.cc", "src/cpp/common/rpc_method.cc", @@ -1269,6 +1270,7 @@ cc_library( hdrs = [ "include/grpc++/alarm.h", "include/grpc++/channel.h", + "include/grpc++/channel_filter.h", "include/grpc++/client_context.h", "include/grpc++/completion_queue.h", "include/grpc++/create_channel.h", @@ -1473,6 +1475,7 @@ cc_library( "src/cpp/client/generic_stub.cc", "src/cpp/client/insecure_credentials.cc", "src/cpp/common/channel_arguments.cc", + "src/cpp/common/channel_filter.cc", "src/cpp/common/completion_queue.cc", "src/cpp/common/core_codegen.cc", "src/cpp/common/rpc_method.cc", @@ -1495,6 +1498,7 @@ cc_library( hdrs = [ "include/grpc++/alarm.h", "include/grpc++/channel.h", + "include/grpc++/channel_filter.h", "include/grpc++/client_context.h", "include/grpc++/completion_queue.h", "include/grpc++/create_channel.h", diff --git a/Makefile b/Makefile index 6eccd06952c..2f88411c95b 100644 --- a/Makefile +++ b/Makefile @@ -3463,6 +3463,7 @@ LIBGRPC++_SRC = \ src/cpp/client/generic_stub.cc \ src/cpp/client/insecure_credentials.cc \ src/cpp/common/channel_arguments.cc \ + src/cpp/common/channel_filter.cc \ src/cpp/common/completion_queue.cc \ src/cpp/common/core_codegen.cc \ src/cpp/common/rpc_method.cc \ @@ -3485,6 +3486,7 @@ LIBGRPC++_SRC = \ PUBLIC_HEADERS_CXX += \ include/grpc++/alarm.h \ include/grpc++/channel.h \ + include/grpc++/channel_filter.h \ include/grpc++/client_context.h \ include/grpc++/completion_queue.h \ include/grpc++/create_channel.h \ @@ -3950,6 +3952,7 @@ LIBGRPC++_UNSECURE_SRC = \ src/cpp/client/generic_stub.cc \ src/cpp/client/insecure_credentials.cc \ src/cpp/common/channel_arguments.cc \ + src/cpp/common/channel_filter.cc \ src/cpp/common/completion_queue.cc \ src/cpp/common/core_codegen.cc \ src/cpp/common/rpc_method.cc \ @@ -3972,6 +3975,7 @@ LIBGRPC++_UNSECURE_SRC = \ PUBLIC_HEADERS_CXX += \ include/grpc++/alarm.h \ include/grpc++/channel.h \ + include/grpc++/channel_filter.h \ include/grpc++/client_context.h \ include/grpc++/completion_queue.h \ include/grpc++/create_channel.h \ diff --git a/build.yaml b/build.yaml index a83ebc595ad..b6b1f758532 100644 --- a/build.yaml +++ b/build.yaml @@ -634,6 +634,7 @@ filegroups: public_headers: - include/grpc++/alarm.h - include/grpc++/channel.h + - include/grpc++/channel_filter.h - include/grpc++/client_context.h - include/grpc++/completion_queue.h - include/grpc++/create_channel.h @@ -693,6 +694,7 @@ filegroups: - src/cpp/client/generic_stub.cc - src/cpp/client/insecure_credentials.cc - src/cpp/common/channel_arguments.cc + - src/cpp/common/channel_filter.cc - src/cpp/common/completion_queue.cc - src/cpp/common/core_codegen.cc - src/cpp/common/rpc_method.cc diff --git a/include/grpc++/channel_filter.h b/include/grpc++/channel_filter.h new file mode 100644 index 00000000000..8067ca9c603 --- /dev/null +++ b/include/grpc++/channel_filter.h @@ -0,0 +1,211 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPCXX_CHANNEL_FILTER_H +#define GRPCXX_CHANNEL_FILTER_H + +#include + +#include + +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/surface/channel_init.h" + +// +// An interface to define filters. +// +// To define a filter, implement a subclass of each of CallData and +// ChannelData. Then register the filter like this: +// RegisterChannelFilter( +// "name-of-filter", GRPC_SERVER_CHANNEL, INT_MAX); +// + +namespace grpc { + +// Represents call data. +// Note: Must be copyable. +class CallData { + public: + // Do not override the destructor. Instead, put clean-up code in the + // Destroy() method. + virtual ~CallData() {} + + virtual void Destroy() {} + + virtual void StartTransportStreamOp( + grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_transport_stream_op *op); + + virtual void SetPollsetOrPollsetSet( + grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_polling_entity *pollent); + + virtual char* GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem); + + protected: + CallData() {} +}; + +// Represents channel data. +// Note: Must be copyable. +class ChannelData { + public: + // Do not override the destructor. Instead, put clean-up code in the + // Destroy() method. + virtual ~ChannelData() {} + + virtual void Destroy() {} + + virtual void StartTransportOp( + grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, + grpc_transport_op *op); + + protected: + ChannelData() {} +}; + +namespace internal { + +// Defines static members for passing to C core. +template +class ChannelFilter { + static const size_t call_data_size = sizeof(CallDataType); + + static void InitCallElement( + grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_call_element_args *args) { + CallDataType* call_data = elem->call_data; + *call_data = CallDataType(); + } + + static void DestroyCallElement( + grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + const grpc_call_stats *stats, void *and_free_memory) { + CallDataType* call_data = elem->call_data; + // Can't destroy the object here, since it's not allocated by + // itself; instead, it's part of a larger allocation managed by + // C-core. So instead, we call the Destroy() method. + call_data->Destroy(); + } + + static void StartTransportStreamOp( + grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_transport_stream_op *op) { + CallDataType* call_data = elem->call_data; + call_data->StartTransportStreamOp(exec_ctx, op); + } + + static void SetPollsetOrPollsetSet( + grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_polling_entity *pollent) { + CallDataType* call_data = elem->call_data; + call_data->SetPollsetOrPollsetSet(exec_ctx, pollent); + } + + static char* GetPeer( + grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { + CallDataType* call_data = elem->call_data; + return call_data->GetPeer(exec_ctx); + } + + static const size_t channel_data_size = sizeof(ChannelDataType); + + static void InitChannelElement( + grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, + grpc_channel_element_args *args) { + ChannelDataType* channel_data = elem->channel_data; + *channel_data = ChannelDataType(); + } + + static void DestroyChannelElement( + grpc_exec_ctx *exec_ctx, grpc_channel_element *elem) { + ChannelDataType* channel_data = elem->channel_data; + // Can't destroy the object here, since it's not allocated by + // itself; instead, it's part of a larger allocation managed by + // C-core. So instead, we call the Destroy() method. + channel_data->Destroy(); + } + + static void StartTransportOp( + grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, + grpc_transport_op *op) { + ChannelDataType* channel_data = elem->channel_data; + channel_data->StartTransportOp(exec_ctx, op); + } +}; + +struct FilterRecord { + grpc_channel_stack_type stack_type; + int priority; + grpc_channel_filter filter; +}; +extern std::vector* channel_filters; + +void ChannelFilterPluginInit(); +void ChannelFilterPluginShutdown() {} + +} // namespace internal + +// Registers a new filter. +// Must be called by only one thread at a time. +template +void RegisterChannelFilter(const char* name, + grpc_channel_stack_type stack_type, int priority) { + // If we haven't been called before, initialize channel_filters and + // call grpc_register_plugin(). + if (internal::channel_filters == nullptr) { + grpc_register_plugin(internal::ChannelFilterPluginInit, + internal::ChannelFilterPluginShutdown); + internal::channel_filters = new std::vector(); + } + // Add an entry to channel_filters. The filter will be added when the + // C-core initialization code calls ChannelFilterPluginInit(). + typedef internal::ChannelFilter FilterType; + internal::channel_filters->emplace_back({ + stack_type, priority, { + FilterType::StartTransportStreamOp, + FilterType::StartTransportOp, + FilterType::call_data_size, + FilterType::InitCallElement, + FilterType::SetPollsetOrPollsetSet, + FilterType::DestroyCallElement, + FilterType::channel_data_size, + FilterType::InitChannelElement, + FilterType::DestroyChannelElement, + FilterType::GetPeer, + name}}); +} + +} // namespace grpc + +#endif // GRPCXX_CHANNEL_FILTER_H diff --git a/src/cpp/common/channel_filter.cc b/src/cpp/common/channel_filter.cc new file mode 100644 index 00000000000..9a80195e867 --- /dev/null +++ b/src/cpp/common/channel_filter.cc @@ -0,0 +1,98 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#include "src/core/lib/channel/channel_stack.h" + +namespace grpc { + +// +// CallData +// + +void CallData::StartTransportStreamOp( + grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_transport_stream_op *op) { + grpc_call_next_op(exec_ctx, elem, op); +} + +void CallData::SetPollsetOrPollsetSet( + grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_polling_entity *pollent) { + grpc_call_stack_ignore_set_pollset_or_pollset_set(exec_ctx, elem, pollent); +} + +char* CallData::GetPeer( + grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { + return grpc_call_next_get_peer(exec_ctx, elem); +} + +// +// ChannelData +// + +void ChannelData::StartTransportOp( + grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, + grpc_transport_op *op) { + grpc_channel_next_op(exec_ctx, elem, op); +} + +// +// RegisterChannelFilter() +// + +namespace internal { + +std::vector* channel_filters = nullptr; + +namespace { + +bool AppendFilter(grpc_channel_stack_builder* builder, void* arg) { + return grpc_channel_stack_builder_append_filter( + builder, (const grpc_channel_filter *)arg, nullptr, nullptr); +} + +} // namespace + +void ChannelFilterPluginInit() { + for (size_t i = 0; i < channel_filters->size(); ++i) { + FilterRecord& filter = (*channel_filters)[i]; + grpc_channel_init_register_stage(filter.stack_type, filter.priority, + AppendFilter, (void*)&filter.filter); + } +} + +} // namespace internal + +} // namespace grpc diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 7f9d2df6f6c..e770574cb1f 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -762,6 +762,7 @@ WARN_LOGFILE = INPUT = include/grpc++/alarm.h \ include/grpc++/channel.h \ +include/grpc++/channel_filter.h \ include/grpc++/client_context.h \ include/grpc++/completion_queue.h \ include/grpc++/create_channel.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index dcf1a4c8c40..a3c4a109264 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -762,6 +762,7 @@ WARN_LOGFILE = INPUT = include/grpc++/alarm.h \ include/grpc++/channel.h \ +include/grpc++/channel_filter.h \ include/grpc++/client_context.h \ include/grpc++/completion_queue.h \ include/grpc++/create_channel.h \ @@ -880,6 +881,7 @@ src/cpp/client/credentials.cc \ src/cpp/client/generic_stub.cc \ src/cpp/client/insecure_credentials.cc \ src/cpp/common/channel_arguments.cc \ +src/cpp/common/channel_filter.cc \ src/cpp/common/completion_queue.cc \ src/cpp/common/core_codegen.cc \ src/cpp/common/rpc_method.cc \ diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 4aad52c69d0..00ea2fdc058 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -6497,6 +6497,7 @@ "headers": [ "include/grpc++/alarm.h", "include/grpc++/channel.h", + "include/grpc++/channel_filter.h", "include/grpc++/client_context.h", "include/grpc++/completion_queue.h", "include/grpc++/create_channel.h", @@ -6551,6 +6552,7 @@ "src": [ "include/grpc++/alarm.h", "include/grpc++/channel.h", + "include/grpc++/channel_filter.h", "include/grpc++/client_context.h", "include/grpc++/completion_queue.h", "include/grpc++/create_channel.h", @@ -6606,6 +6608,7 @@ "src/cpp/client/generic_stub.cc", "src/cpp/client/insecure_credentials.cc", "src/cpp/common/channel_arguments.cc", + "src/cpp/common/channel_filter.cc", "src/cpp/common/completion_queue.cc", "src/cpp/common/core_codegen.cc", "src/cpp/common/rpc_method.cc", diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj index cb9e41ea22f..b882c302bbb 100644 --- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj +++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj @@ -260,6 +260,7 @@ + @@ -397,6 +398,8 @@ + + diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters index a9051182b3c..08fffb74b2f 100644 --- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters @@ -46,6 +46,9 @@ src\cpp\common + + src\cpp\common + src\cpp\common @@ -108,6 +111,9 @@ include\grpc++ + + include\grpc++ + include\grpc++ diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj index 03be485b297..b5a27f624d1 100644 --- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj @@ -260,6 +260,7 @@ + @@ -383,6 +384,8 @@ + + diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters index ba99bc53c8c..68d9a47973d 100644 --- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters @@ -31,6 +31,9 @@ src\cpp\common + + src\cpp\common + src\cpp\common @@ -93,6 +96,9 @@ include\grpc++ + + include\grpc++ + include\grpc++ From c459ecf7c9beac5e861ade0dd4686348c1bbfdc6 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 16 Jun 2016 09:17:49 -0700 Subject: [PATCH 012/279] - fix build problems - make changes suggested by reviewer - add test (not working yet) --- Makefile | 47 +++ build.yaml | 13 + include/grpc++/channel_filter.h | 68 ++-- src/core/lib/channel/channel_stack.h | 8 + src/core/lib/channel/channel_stack_builder.h | 8 + src/core/lib/surface/channel_init.h | 8 + src/cpp/common/channel_filter.cc | 17 +- test/cpp/end2end/filter_end2end_test.cc | 327 ++++++++++++++++++ tools/run_tests/sources_and_headers.json | 18 + tools/run_tests/tests.json | 21 ++ .../filter_end2end_test.vcxproj | 207 +++++++++++ .../filter_end2end_test.vcxproj.filters | 21 ++ 12 files changed, 721 insertions(+), 42 deletions(-) create mode 100644 test/cpp/end2end/filter_end2end_test.cc create mode 100644 vsprojects/vcxproj/test/filter_end2end_test/filter_end2end_test.vcxproj create mode 100644 vsprojects/vcxproj/test/filter_end2end_test/filter_end2end_test.vcxproj.filters diff --git a/Makefile b/Makefile index 2f88411c95b..2556b749207 100644 --- a/Makefile +++ b/Makefile @@ -1014,6 +1014,7 @@ cxx_slice_test: $(BINDIR)/$(CONFIG)/cxx_slice_test cxx_string_ref_test: $(BINDIR)/$(CONFIG)/cxx_string_ref_test cxx_time_test: $(BINDIR)/$(CONFIG)/cxx_time_test end2end_test: $(BINDIR)/$(CONFIG)/end2end_test +filter_end2end_test: $(BINDIR)/$(CONFIG)/filter_end2end_test generic_end2end_test: $(BINDIR)/$(CONFIG)/generic_end2end_test golden_file_test: $(BINDIR)/$(CONFIG)/golden_file_test grpc_cli: $(BINDIR)/$(CONFIG)/grpc_cli @@ -1393,6 +1394,7 @@ buildtests_cxx: buildtests_zookeeper privatelibs_cxx \ $(BINDIR)/$(CONFIG)/cxx_string_ref_test \ $(BINDIR)/$(CONFIG)/cxx_time_test \ $(BINDIR)/$(CONFIG)/end2end_test \ + $(BINDIR)/$(CONFIG)/filter_end2end_test \ $(BINDIR)/$(CONFIG)/generic_end2end_test \ $(BINDIR)/$(CONFIG)/golden_file_test \ $(BINDIR)/$(CONFIG)/grpc_cli \ @@ -1721,6 +1723,8 @@ test_cxx: test_zookeeper buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/cxx_time_test || ( echo test cxx_time_test failed ; exit 1 ) $(E) "[RUN] Testing end2end_test" $(Q) $(BINDIR)/$(CONFIG)/end2end_test || ( echo test end2end_test failed ; exit 1 ) + $(E) "[RUN] Testing filter_end2end_test" + $(Q) $(BINDIR)/$(CONFIG)/filter_end2end_test || ( echo test filter_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing generic_end2end_test" $(Q) $(BINDIR)/$(CONFIG)/generic_end2end_test || ( echo test generic_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing golden_file_test" @@ -10851,6 +10855,49 @@ endif endif +FILTER_END2END_TEST_SRC = \ + test/cpp/end2end/filter_end2end_test.cc \ + +FILTER_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(FILTER_END2END_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/filter_end2end_test: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+. + +$(BINDIR)/$(CONFIG)/filter_end2end_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/filter_end2end_test: $(PROTOBUF_DEP) $(FILTER_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(FILTER_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/filter_end2end_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/filter_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_filter_end2end_test: $(FILTER_END2END_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(FILTER_END2END_TEST_OBJS:.o=.dep) +endif +endif + + GENERIC_END2END_TEST_SRC = \ test/cpp/end2end/generic_end2end_test.cc \ diff --git a/build.yaml b/build.yaml index b6b1f758532..ad1211f2192 100644 --- a/build.yaml +++ b/build.yaml @@ -2611,6 +2611,19 @@ targets: - grpc - gpr_test_util - gpr +- name: filter_end2end_test + gtest: true + build: test + language: c++ + src: + - test/cpp/end2end/filter_end2end_test.cc + deps: + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr_test_util + - gpr - name: generic_end2end_test gtest: true build: test diff --git a/include/grpc++/channel_filter.h b/include/grpc++/channel_filter.h index 8067ca9c603..b37d986a5ac 100644 --- a/include/grpc++/channel_filter.h +++ b/include/grpc++/channel_filter.h @@ -36,6 +36,7 @@ #include +#include #include #include "src/core/lib/channel/channel_stack.h" @@ -45,9 +46,9 @@ // An interface to define filters. // // To define a filter, implement a subclass of each of CallData and -// ChannelData. Then register the filter like this: +// ChannelData. Then register the filter using something like this: // RegisterChannelFilter( -// "name-of-filter", GRPC_SERVER_CHANNEL, INT_MAX); +// "name-of-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr); // namespace grpc { @@ -56,12 +57,8 @@ namespace grpc { // Note: Must be copyable. class CallData { public: - // Do not override the destructor. Instead, put clean-up code in the - // Destroy() method. virtual ~CallData() {} - virtual void Destroy() {} - virtual void StartTransportStreamOp( grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_transport_stream_op *op); @@ -80,12 +77,8 @@ class CallData { // Note: Must be copyable. class ChannelData { public: - // Do not override the destructor. Instead, put clean-up code in the - // Destroy() method. virtual ~ChannelData() {} - virtual void Destroy() {} - virtual void StartTransportOp( grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_transport_op *op); @@ -99,43 +92,40 @@ namespace internal { // Defines static members for passing to C core. template class ChannelFilter { + public: static const size_t call_data_size = sizeof(CallDataType); static void InitCallElement( grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { - CallDataType* call_data = elem->call_data; - *call_data = CallDataType(); + // Construct the object in the already-allocated memory. + new (elem->call_data) CallDataType(); } static void DestroyCallElement( grpc_exec_ctx *exec_ctx, grpc_call_element *elem, const grpc_call_stats *stats, void *and_free_memory) { - CallDataType* call_data = elem->call_data; - // Can't destroy the object here, since it's not allocated by - // itself; instead, it's part of a larger allocation managed by - // C-core. So instead, we call the Destroy() method. - call_data->Destroy(); + reinterpret_cast(elem->call_data)->~CallDataType(); } static void StartTransportStreamOp( grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_transport_stream_op *op) { - CallDataType* call_data = elem->call_data; - call_data->StartTransportStreamOp(exec_ctx, op); + CallDataType* call_data = (CallDataType*)elem->call_data; + call_data->StartTransportStreamOp(exec_ctx, elem, op); } static void SetPollsetOrPollsetSet( grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_polling_entity *pollent) { - CallDataType* call_data = elem->call_data; - call_data->SetPollsetOrPollsetSet(exec_ctx, pollent); + CallDataType* call_data = (CallDataType*)elem->call_data; + call_data->SetPollsetOrPollsetSet(exec_ctx, elem, pollent); } static char* GetPeer( grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { - CallDataType* call_data = elem->call_data; - return call_data->GetPeer(exec_ctx); + CallDataType* call_data = (CallDataType*)elem->call_data; + return call_data->GetPeer(exec_ctx, elem); } static const size_t channel_data_size = sizeof(ChannelDataType); @@ -143,44 +133,45 @@ class ChannelFilter { static void InitChannelElement( grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_channel_element_args *args) { - ChannelDataType* channel_data = elem->channel_data; - *channel_data = ChannelDataType(); + // Construct the object in the already-allocated memory. + new (elem->channel_data) ChannelDataType(); } static void DestroyChannelElement( grpc_exec_ctx *exec_ctx, grpc_channel_element *elem) { - ChannelDataType* channel_data = elem->channel_data; - // Can't destroy the object here, since it's not allocated by - // itself; instead, it's part of a larger allocation managed by - // C-core. So instead, we call the Destroy() method. - channel_data->Destroy(); + reinterpret_cast(elem->channel_data)->~ChannelDataType(); } static void StartTransportOp( grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_transport_op *op) { - ChannelDataType* channel_data = elem->channel_data; - channel_data->StartTransportOp(exec_ctx, op); + ChannelDataType* channel_data = (ChannelDataType*)elem->channel_data; + channel_data->StartTransportOp(exec_ctx, elem, op); } }; struct FilterRecord { grpc_channel_stack_type stack_type; int priority; + std::function include_filter; grpc_channel_filter filter; }; extern std::vector* channel_filters; void ChannelFilterPluginInit(); -void ChannelFilterPluginShutdown() {} +void ChannelFilterPluginShutdown(); } // namespace internal // Registers a new filter. // Must be called by only one thread at a time. +// The include_filter argument specifies a function that will be called +// to determine at run-time whether or not to add the filter. If the +// value is nullptr, the filter will be added unconditionally. template -void RegisterChannelFilter(const char* name, - grpc_channel_stack_type stack_type, int priority) { +void RegisterChannelFilter( + const char* name, grpc_channel_stack_type stack_type, int priority, + std::function include_filter) { // If we haven't been called before, initialize channel_filters and // call grpc_register_plugin(). if (internal::channel_filters == nullptr) { @@ -191,8 +182,8 @@ void RegisterChannelFilter(const char* name, // Add an entry to channel_filters. The filter will be added when the // C-core initialization code calls ChannelFilterPluginInit(). typedef internal::ChannelFilter FilterType; - internal::channel_filters->emplace_back({ - stack_type, priority, { + internal::FilterRecord filter_record = { + stack_type, priority, include_filter, { FilterType::StartTransportStreamOp, FilterType::StartTransportOp, FilterType::call_data_size, @@ -203,7 +194,8 @@ void RegisterChannelFilter(const char* name, FilterType::InitChannelElement, FilterType::DestroyChannelElement, FilterType::GetPeer, - name}}); + name}}; + internal::channel_filters->push_back(filter_record); } } // namespace grpc diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index 41dd4a0d8a1..535acde3934 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -51,6 +51,10 @@ #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/transport/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct grpc_channel_element grpc_channel_element; typedef struct grpc_call_element grpc_call_element; @@ -278,4 +282,8 @@ extern int grpc_trace_channel; #define GRPC_CALL_LOG_OP(sev, elem, op) \ if (grpc_trace_channel) grpc_call_log_op(sev, elem, op) +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_STACK_H */ diff --git a/src/core/lib/channel/channel_stack_builder.h b/src/core/lib/channel/channel_stack_builder.h index 0e6bfd9aa69..4a00f7bfdbd 100644 --- a/src/core/lib/channel/channel_stack_builder.h +++ b/src/core/lib/channel/channel_stack_builder.h @@ -39,6 +39,10 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" +#ifdef __cplusplus +extern "C" { +#endif + /// grpc_channel_stack_builder offers a programmatic interface to selected /// and order channel filters typedef struct grpc_channel_stack_builder grpc_channel_stack_builder; @@ -158,4 +162,8 @@ void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder); extern int grpc_trace_channel_stack_builder; +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_STACK_BUILDER_H */ diff --git a/src/core/lib/surface/channel_init.h b/src/core/lib/surface/channel_init.h index 3a18a61ddb8..b53f2aefb92 100644 --- a/src/core/lib/surface/channel_init.h +++ b/src/core/lib/surface/channel_init.h @@ -40,6 +40,10 @@ #define GRPC_CHANNEL_INIT_BUILTIN_PRIORITY 10000 +#ifdef __cplusplus +extern "C" { +#endif + /// This module provides a way for plugins (and the grpc core library itself) /// to register mutators for channel stacks. /// It also provides a universal entry path to run those mutators to build @@ -84,4 +88,8 @@ bool grpc_channel_init_create_stack(grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder, grpc_channel_stack_type type); +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_SURFACE_CHANNEL_INIT_H */ diff --git a/src/cpp/common/channel_filter.cc b/src/cpp/common/channel_filter.cc index 9a80195e867..b5e5e08976b 100644 --- a/src/cpp/common/channel_filter.cc +++ b/src/cpp/common/channel_filter.cc @@ -78,9 +78,16 @@ std::vector* channel_filters = nullptr; namespace { -bool AppendFilter(grpc_channel_stack_builder* builder, void* arg) { - return grpc_channel_stack_builder_append_filter( - builder, (const grpc_channel_filter *)arg, nullptr, nullptr); +bool MaybeAddFilter(grpc_channel_stack_builder* builder, void* arg) { + const FilterRecord& filter = *(FilterRecord*)arg; + if (filter.include_filter != nullptr) { + const grpc_channel_args *args = + grpc_channel_stack_builder_get_channel_arguments(builder); + if (!filter.include_filter(args)) + return true; + } + return grpc_channel_stack_builder_prepend_filter( + builder, &filter.filter, nullptr, nullptr); } } // namespace @@ -89,10 +96,12 @@ void ChannelFilterPluginInit() { for (size_t i = 0; i < channel_filters->size(); ++i) { FilterRecord& filter = (*channel_filters)[i]; grpc_channel_init_register_stage(filter.stack_type, filter.priority, - AppendFilter, (void*)&filter.filter); + MaybeAddFilter, (void*)&filter); } } +void ChannelFilterPluginShutdown() {} + } // namespace internal } // namespace grpc diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc new file mode 100644 index 00000000000..79a5287fbcf --- /dev/null +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -0,0 +1,327 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/util/byte_buffer_proto_helper.h" + +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; +using std::chrono::system_clock; + +namespace grpc { +namespace testing { +namespace { + +void* tag(int i) { return (void*)(intptr_t)i; } + +void verify_ok(CompletionQueue* cq, int i, bool expect_ok) { + bool ok; + void* got_tag; + EXPECT_TRUE(cq->Next(&got_tag, &ok)); + EXPECT_EQ(expect_ok, ok); + EXPECT_EQ(tag(i), got_tag); +} + +namespace { + +int global_num_calls = 0; +mutex global_mu; + +void IncrementCounter() { + unique_lock lock(global_mu); + ++global_num_calls; +} + +void ResetCounter() { + unique_lock lock(global_mu); + global_num_calls = 0; +} + +int GetCounterValue() { + unique_lock lock(global_mu); + return global_num_calls; +} + +} // namespace + +class CallDataImpl : public CallData { + public: + CallDataImpl() {} + virtual ~CallDataImpl() {} + + void StartTransportStreamOp( + grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_transport_stream_op *op) { + gpr_log(GPR_ERROR, "INCREMENTING"); + IncrementCounter(); + grpc_call_next_op(exec_ctx, elem, op); + } +}; + +class ChannelDataImpl : public ChannelData { + public: + ChannelDataImpl() {} + virtual ~ChannelDataImpl() {} +}; + +class FilterEnd2endTest : public ::testing::Test { + protected: + FilterEnd2endTest() : server_host_("localhost") {} + + void SetUp() GRPC_OVERRIDE { + RegisterChannelFilter( + "test-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr); + int port = grpc_pick_unused_port_or_die(); + server_address_ << server_host_ << ":" << port; + // Setup server + ServerBuilder builder; + builder.AddListeningPort(server_address_.str(), + InsecureServerCredentials()); + builder.RegisterAsyncGenericService(&generic_service_); + // Include a second call to RegisterAsyncGenericService to make sure that + // we get an error in the log, since it is not allowed to have 2 async + // generic services + builder.RegisterAsyncGenericService(&generic_service_); + srv_cq_ = builder.AddCompletionQueue(); + server_ = builder.BuildAndStart(); + } + + void TearDown() GRPC_OVERRIDE { + server_->Shutdown(); + void* ignored_tag; + bool ignored_ok; + cli_cq_.Shutdown(); + srv_cq_->Shutdown(); + while (cli_cq_.Next(&ignored_tag, &ignored_ok)) + ; + while (srv_cq_->Next(&ignored_tag, &ignored_ok)) + ; + } + + void ResetStub() { + std::shared_ptr channel = + CreateChannel(server_address_.str(), InsecureChannelCredentials()); + generic_stub_.reset(new GenericStub(channel)); + ResetCounter(); + } + + void server_ok(int i) { verify_ok(srv_cq_.get(), i, true); } + void client_ok(int i) { verify_ok(&cli_cq_, i, true); } + void server_fail(int i) { verify_ok(srv_cq_.get(), i, false); } + void client_fail(int i) { verify_ok(&cli_cq_, i, false); } + + void SendRpc(int num_rpcs) { + const grpc::string kMethodName("/grpc.cpp.test.util.EchoTestService/Echo"); + for (int i = 0; i < num_rpcs; i++) { + EchoRequest send_request; + EchoRequest recv_request; + EchoResponse send_response; + EchoResponse recv_response; + Status recv_status; + + ClientContext cli_ctx; + GenericServerContext srv_ctx; + GenericServerAsyncReaderWriter stream(&srv_ctx); + + // The string needs to be long enough to test heap-based slice. + send_request.set_message("Hello world. Hello world. Hello world."); + std::unique_ptr call = + generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1)); + client_ok(1); + std::unique_ptr send_buffer = + SerializeToByteBuffer(&send_request); + call->Write(*send_buffer, tag(2)); + // Send ByteBuffer can be destroyed after calling Write. + send_buffer.reset(); + client_ok(2); + call->WritesDone(tag(3)); + client_ok(3); + + generic_service_.RequestCall(&srv_ctx, &stream, srv_cq_.get(), + srv_cq_.get(), tag(4)); + + verify_ok(srv_cq_.get(), 4, true); + EXPECT_EQ(server_host_, srv_ctx.host().substr(0, server_host_.length())); + EXPECT_EQ(kMethodName, srv_ctx.method()); + ByteBuffer recv_buffer; + stream.Read(&recv_buffer, tag(5)); + server_ok(5); + EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); + EXPECT_EQ(send_request.message(), recv_request.message()); + + send_response.set_message(recv_request.message()); + send_buffer = SerializeToByteBuffer(&send_response); + stream.Write(*send_buffer, tag(6)); + send_buffer.reset(); + server_ok(6); + + stream.Finish(Status::OK, tag(7)); + server_ok(7); + + recv_buffer.Clear(); + call->Read(&recv_buffer, tag(8)); + client_ok(8); + EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_response)); + + call->Finish(&recv_status, tag(9)); + client_ok(9); + + EXPECT_EQ(send_response.message(), recv_response.message()); + EXPECT_TRUE(recv_status.ok()); + } + } + + CompletionQueue cli_cq_; + std::unique_ptr srv_cq_; + std::unique_ptr stub_; + std::unique_ptr generic_stub_; + std::unique_ptr server_; + AsyncGenericService generic_service_; + const grpc::string server_host_; + std::ostringstream server_address_; +}; + +TEST_F(FilterEnd2endTest, SimpleRpc) { + ResetStub(); + EXPECT_EQ(0, GetCounterValue()); + SendRpc(1); + EXPECT_EQ(1, GetCounterValue()); +} + +TEST_F(FilterEnd2endTest, SequentialRpcs) { + ResetStub(); + EXPECT_EQ(0, GetCounterValue()); + SendRpc(10); + EXPECT_EQ(10, GetCounterValue()); +} + +// One ping, one pong. +TEST_F(FilterEnd2endTest, SimpleBidiStreaming) { + ResetStub(); + EXPECT_EQ(0, GetCounterValue()); + + const grpc::string kMethodName( + "/grpc.cpp.test.util.EchoTestService/BidiStream"); + EchoRequest send_request; + EchoRequest recv_request; + EchoResponse send_response; + EchoResponse recv_response; + Status recv_status; + ClientContext cli_ctx; + GenericServerContext srv_ctx; + GenericServerAsyncReaderWriter srv_stream(&srv_ctx); + + cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP); + send_request.set_message("Hello"); + std::unique_ptr cli_stream = + generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1)); + client_ok(1); + + generic_service_.RequestCall(&srv_ctx, &srv_stream, srv_cq_.get(), + srv_cq_.get(), tag(2)); + + verify_ok(srv_cq_.get(), 2, true); + EXPECT_EQ(server_host_, srv_ctx.host().substr(0, server_host_.length())); + EXPECT_EQ(kMethodName, srv_ctx.method()); + + std::unique_ptr send_buffer = + SerializeToByteBuffer(&send_request); + cli_stream->Write(*send_buffer, tag(3)); + send_buffer.reset(); + client_ok(3); + + ByteBuffer recv_buffer; + srv_stream.Read(&recv_buffer, tag(4)); + server_ok(4); + EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); + EXPECT_EQ(send_request.message(), recv_request.message()); + + send_response.set_message(recv_request.message()); + send_buffer = SerializeToByteBuffer(&send_response); + srv_stream.Write(*send_buffer, tag(5)); + send_buffer.reset(); + server_ok(5); + + cli_stream->Read(&recv_buffer, tag(6)); + client_ok(6); + EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_response)); + EXPECT_EQ(send_response.message(), recv_response.message()); + + cli_stream->WritesDone(tag(7)); + client_ok(7); + + srv_stream.Read(&recv_buffer, tag(8)); + server_fail(8); + + srv_stream.Finish(Status::OK, tag(9)); + server_ok(9); + + cli_stream->Finish(&recv_status, tag(10)); + client_ok(10); + + EXPECT_EQ(send_response.message(), recv_response.message()); + EXPECT_TRUE(recv_status.ok()); + + EXPECT_EQ(1, GetCounterValue()); +} + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 00ea2fdc058..ee6cda804a7 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -2062,6 +2062,24 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc++", + "grpc++_test_util", + "grpc_test_util" + ], + "headers": [], + "language": "c++", + "name": "filter_end2end_test", + "src": [ + "test/cpp/end2end/filter_end2end_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index 5a84a41b638..5744261c99b 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -2210,6 +2210,27 @@ "windows" ] }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "filter_end2end_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, { "args": [], "ci_platforms": [ diff --git a/vsprojects/vcxproj/test/filter_end2end_test/filter_end2end_test.vcxproj b/vsprojects/vcxproj/test/filter_end2end_test/filter_end2end_test.vcxproj new file mode 100644 index 00000000000..99c000e4fa9 --- /dev/null +++ b/vsprojects/vcxproj/test/filter_end2end_test/filter_end2end_test.vcxproj @@ -0,0 +1,207 @@ + + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {1D42975A-18A5-09D0-30B1-2AE6A97FB9DE} + true + $(SolutionDir)IntDir\$(MSBuildProjectName)\ + + + + v100 + + + v110 + + + v120 + + + v140 + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + + + filter_end2end_test + static + Debug + static + Debug + + + filter_end2end_test + static + Release + static + Release + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + + + + + {0BE77741-552A-929B-A497-4EF7ECE17A64} + + + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} + + + {C187A093-A0FE-489D-A40A-6E33DE0F9FEB} + + + {29D16885-7228-4C31-81ED-5F9187C7F2A9} + + + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + + + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + diff --git a/vsprojects/vcxproj/test/filter_end2end_test/filter_end2end_test.vcxproj.filters b/vsprojects/vcxproj/test/filter_end2end_test/filter_end2end_test.vcxproj.filters new file mode 100644 index 00000000000..c68442365c5 --- /dev/null +++ b/vsprojects/vcxproj/test/filter_end2end_test/filter_end2end_test.vcxproj.filters @@ -0,0 +1,21 @@ + + + + + test\cpp\end2end + + + + + + {f7581160-220d-1118-f29e-6b37e45671c9} + + + {63784d35-03cc-1a7e-0c95-a9451bc1daf4} + + + {d2a01682-970e-d23d-1eb8-ef020e3a1ca3} + + + + From 8a1a5976c7eced718e2385b7f36046d6e73017af Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 16 Jun 2016 10:22:26 -0700 Subject: [PATCH 013/279] Fixed test. --- test/cpp/end2end/filter_end2end_test.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc index 79a5287fbcf..be6988c6baf 100644 --- a/test/cpp/end2end/filter_end2end_test.cc +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -103,8 +103,8 @@ class CallDataImpl : public CallData { void StartTransportStreamOp( grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_transport_stream_op *op) { - gpr_log(GPR_ERROR, "INCREMENTING"); - IncrementCounter(); + if (op->recv_initial_metadata != nullptr) + IncrementCounter(); grpc_call_next_op(exec_ctx, elem, op); } }; @@ -120,8 +120,6 @@ class FilterEnd2endTest : public ::testing::Test { FilterEnd2endTest() : server_host_("localhost") {} void SetUp() GRPC_OVERRIDE { - RegisterChannelFilter( - "test-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr); int port = grpc_pick_unused_port_or_die(); server_address_ << server_host_ << ":" << port; // Setup server @@ -323,5 +321,8 @@ TEST_F(FilterEnd2endTest, SimpleBidiStreaming) { int main(int argc, char** argv) { grpc_test_init(argc, argv); ::testing::InitGoogleTest(&argc, argv); + grpc::RegisterChannelFilter( + "test-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr); return RUN_ALL_TESTS(); } From c008b33c18f1d2c49ee1b6683c2d13a85e2c2432 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 16 Jun 2016 10:39:39 -0700 Subject: [PATCH 014/279] Pass channel args to ChannelData ctor and ChannelData to CallData ctor. --- include/grpc++/channel_filter.h | 79 +++++++++++++------------ src/cpp/common/channel_filter.cc | 2 +- test/cpp/end2end/filter_end2end_test.cc | 15 ++--- 3 files changed, 49 insertions(+), 47 deletions(-) diff --git a/include/grpc++/channel_filter.h b/include/grpc++/channel_filter.h index b37d986a5ac..8731a5e9651 100644 --- a/include/grpc++/channel_filter.h +++ b/include/grpc++/channel_filter.h @@ -53,6 +53,20 @@ namespace grpc { +// Represents channel data. +// Note: Must be copyable. +class ChannelData { + public: + virtual ~ChannelData() {} + + virtual void StartTransportOp( + grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, + grpc_transport_op *op); + + protected: + explicit ChannelData(const grpc_channel_args&) {} +}; + // Represents call data. // Note: Must be copyable. class CallData { @@ -70,21 +84,7 @@ class CallData { virtual char* GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem); protected: - CallData() {} -}; - -// Represents channel data. -// Note: Must be copyable. -class ChannelData { - public: - virtual ~ChannelData() {} - - virtual void StartTransportOp( - grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, - grpc_transport_op *op); - - protected: - ChannelData() {} + explicit CallData(const ChannelData&) {} }; namespace internal { @@ -93,13 +93,35 @@ namespace internal { template class ChannelFilter { public: + static const size_t channel_data_size = sizeof(ChannelDataType); + + static void InitChannelElement( + grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, + grpc_channel_element_args *args) { + // Construct the object in the already-allocated memory. + new (elem->channel_data) ChannelDataType(*args->channel_args); + } + + static void DestroyChannelElement( + grpc_exec_ctx *exec_ctx, grpc_channel_element *elem) { + reinterpret_cast(elem->channel_data)->~ChannelDataType(); + } + + static void StartTransportOp( + grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, + grpc_transport_op *op) { + ChannelDataType* channel_data = (ChannelDataType*)elem->channel_data; + channel_data->StartTransportOp(exec_ctx, elem, op); + } + static const size_t call_data_size = sizeof(CallDataType); static void InitCallElement( grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { + const ChannelDataType& channel_data = *(ChannelDataType*)elem->channel_data; // Construct the object in the already-allocated memory. - new (elem->call_data) CallDataType(); + new (elem->call_data) CallDataType(channel_data); } static void DestroyCallElement( @@ -127,33 +149,12 @@ class ChannelFilter { CallDataType* call_data = (CallDataType*)elem->call_data; return call_data->GetPeer(exec_ctx, elem); } - - static const size_t channel_data_size = sizeof(ChannelDataType); - - static void InitChannelElement( - grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, - grpc_channel_element_args *args) { - // Construct the object in the already-allocated memory. - new (elem->channel_data) ChannelDataType(); - } - - static void DestroyChannelElement( - grpc_exec_ctx *exec_ctx, grpc_channel_element *elem) { - reinterpret_cast(elem->channel_data)->~ChannelDataType(); - } - - static void StartTransportOp( - grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, - grpc_transport_op *op) { - ChannelDataType* channel_data = (ChannelDataType*)elem->channel_data; - channel_data->StartTransportOp(exec_ctx, elem, op); - } }; struct FilterRecord { grpc_channel_stack_type stack_type; int priority; - std::function include_filter; + std::function include_filter; grpc_channel_filter filter; }; extern std::vector* channel_filters; @@ -171,7 +172,7 @@ void ChannelFilterPluginShutdown(); template void RegisterChannelFilter( const char* name, grpc_channel_stack_type stack_type, int priority, - std::function include_filter) { + std::function include_filter) { // If we haven't been called before, initialize channel_filters and // call grpc_register_plugin(). if (internal::channel_filters == nullptr) { diff --git a/src/cpp/common/channel_filter.cc b/src/cpp/common/channel_filter.cc index b5e5e08976b..77b2a26e8cc 100644 --- a/src/cpp/common/channel_filter.cc +++ b/src/cpp/common/channel_filter.cc @@ -83,7 +83,7 @@ bool MaybeAddFilter(grpc_channel_stack_builder* builder, void* arg) { if (filter.include_filter != nullptr) { const grpc_channel_args *args = grpc_channel_stack_builder_get_channel_arguments(builder); - if (!filter.include_filter(args)) + if (!filter.include_filter(*args)) return true; } return grpc_channel_stack_builder_prepend_filter( diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc index be6988c6baf..16151c21b84 100644 --- a/test/cpp/end2end/filter_end2end_test.cc +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -95,9 +95,16 @@ int GetCounterValue() { } // namespace +class ChannelDataImpl : public ChannelData { + public: + explicit ChannelDataImpl(const grpc_channel_args& args) : ChannelData(args) {} + virtual ~ChannelDataImpl() {} +}; + class CallDataImpl : public CallData { public: - CallDataImpl() {} + explicit CallDataImpl(const ChannelDataImpl& channel_data) + : CallData(channel_data) {} virtual ~CallDataImpl() {} void StartTransportStreamOp( @@ -109,12 +116,6 @@ class CallDataImpl : public CallData { } }; -class ChannelDataImpl : public ChannelData { - public: - ChannelDataImpl() {} - virtual ~ChannelDataImpl() {} -}; - class FilterEnd2endTest : public ::testing::Test { protected: FilterEnd2endTest() : server_host_("localhost") {} From f9c1f7a412619e78a93a116068fe0fe373e172e1 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 16 Jun 2016 10:57:28 -0700 Subject: [PATCH 015/279] clang-format --- include/grpc++/channel_filter.h | 114 ++++++++++++------------ src/cpp/common/channel_filter.cc | 38 ++++---- test/cpp/end2end/filter_end2end_test.cc | 8 +- 3 files changed, 76 insertions(+), 84 deletions(-) diff --git a/include/grpc++/channel_filter.h b/include/grpc++/channel_filter.h index 8731a5e9651..f73abe8e6c1 100644 --- a/include/grpc++/channel_filter.h +++ b/include/grpc++/channel_filter.h @@ -59,12 +59,12 @@ class ChannelData { public: virtual ~ChannelData() {} - virtual void StartTransportOp( - grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, - grpc_transport_op *op); + virtual void StartTransportOp(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_transport_op *op); protected: - explicit ChannelData(const grpc_channel_args&) {} + explicit ChannelData(const grpc_channel_args &) {} }; // Represents call data. @@ -73,80 +73,80 @@ class CallData { public: virtual ~CallData() {} - virtual void StartTransportStreamOp( - grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_transport_stream_op *op); + virtual void StartTransportStreamOp(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_transport_stream_op *op); - virtual void SetPollsetOrPollsetSet( - grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_polling_entity *pollent); + virtual void SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_polling_entity *pollent); - virtual char* GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem); + virtual char *GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem); protected: - explicit CallData(const ChannelData&) {} + explicit CallData(const ChannelData &) {} }; namespace internal { // Defines static members for passing to C core. -template +template class ChannelFilter { public: static const size_t channel_data_size = sizeof(ChannelDataType); - static void InitChannelElement( - grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, - grpc_channel_element_args *args) { + static void InitChannelElement(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_channel_element_args *args) { // Construct the object in the already-allocated memory. new (elem->channel_data) ChannelDataType(*args->channel_args); } - static void DestroyChannelElement( - grpc_exec_ctx *exec_ctx, grpc_channel_element *elem) { - reinterpret_cast(elem->channel_data)->~ChannelDataType(); + static void DestroyChannelElement(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem) { + reinterpret_cast(elem->channel_data)->~ChannelDataType(); } - static void StartTransportOp( - grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, - grpc_transport_op *op) { - ChannelDataType* channel_data = (ChannelDataType*)elem->channel_data; + static void StartTransportOp(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_transport_op *op) { + ChannelDataType *channel_data = (ChannelDataType *)elem->channel_data; channel_data->StartTransportOp(exec_ctx, elem, op); } static const size_t call_data_size = sizeof(CallDataType); - static void InitCallElement( - grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { - const ChannelDataType& channel_data = *(ChannelDataType*)elem->channel_data; + static void InitCallElement(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_call_element_args *args) { + const ChannelDataType &channel_data = + *(ChannelDataType *)elem->channel_data; // Construct the object in the already-allocated memory. new (elem->call_data) CallDataType(channel_data); } - static void DestroyCallElement( - grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - const grpc_call_stats *stats, void *and_free_memory) { - reinterpret_cast(elem->call_data)->~CallDataType(); + static void DestroyCallElement(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + const grpc_call_stats *stats, + void *and_free_memory) { + reinterpret_cast(elem->call_data)->~CallDataType(); } - static void StartTransportStreamOp( - grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_transport_stream_op *op) { - CallDataType* call_data = (CallDataType*)elem->call_data; + static void StartTransportStreamOp(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_transport_stream_op *op) { + CallDataType *call_data = (CallDataType *)elem->call_data; call_data->StartTransportStreamOp(exec_ctx, elem, op); } - static void SetPollsetOrPollsetSet( - grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_polling_entity *pollent) { - CallDataType* call_data = (CallDataType*)elem->call_data; + static void SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_polling_entity *pollent) { + CallDataType *call_data = (CallDataType *)elem->call_data; call_data->SetPollsetOrPollsetSet(exec_ctx, elem, pollent); } - static char* GetPeer( - grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { - CallDataType* call_data = (CallDataType*)elem->call_data; + static char *GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { + CallDataType *call_data = (CallDataType *)elem->call_data; return call_data->GetPeer(exec_ctx, elem); } }; @@ -154,10 +154,10 @@ class ChannelFilter { struct FilterRecord { grpc_channel_stack_type stack_type; int priority; - std::function include_filter; + std::function include_filter; grpc_channel_filter filter; }; -extern std::vector* channel_filters; +extern std::vector *channel_filters; void ChannelFilterPluginInit(); void ChannelFilterPluginShutdown(); @@ -169,10 +169,10 @@ void ChannelFilterPluginShutdown(); // The include_filter argument specifies a function that will be called // to determine at run-time whether or not to add the filter. If the // value is nullptr, the filter will be added unconditionally. -template +template void RegisterChannelFilter( - const char* name, grpc_channel_stack_type stack_type, int priority, - std::function include_filter) { + const char *name, grpc_channel_stack_type stack_type, int priority, + std::function include_filter) { // If we haven't been called before, initialize channel_filters and // call grpc_register_plugin(). if (internal::channel_filters == nullptr) { @@ -184,18 +184,14 @@ void RegisterChannelFilter( // C-core initialization code calls ChannelFilterPluginInit(). typedef internal::ChannelFilter FilterType; internal::FilterRecord filter_record = { - stack_type, priority, include_filter, { - FilterType::StartTransportStreamOp, - FilterType::StartTransportOp, - FilterType::call_data_size, - FilterType::InitCallElement, - FilterType::SetPollsetOrPollsetSet, - FilterType::DestroyCallElement, - FilterType::channel_data_size, - FilterType::InitChannelElement, - FilterType::DestroyChannelElement, - FilterType::GetPeer, - name}}; + stack_type, + priority, + include_filter, + {FilterType::StartTransportStreamOp, FilterType::StartTransportOp, + FilterType::call_data_size, FilterType::InitCallElement, + FilterType::SetPollsetOrPollsetSet, FilterType::DestroyCallElement, + FilterType::channel_data_size, FilterType::InitChannelElement, + FilterType::DestroyChannelElement, FilterType::GetPeer, name}}; internal::channel_filters->push_back(filter_record); } diff --git a/src/cpp/common/channel_filter.cc b/src/cpp/common/channel_filter.cc index 77b2a26e8cc..86df47903fd 100644 --- a/src/cpp/common/channel_filter.cc +++ b/src/cpp/common/channel_filter.cc @@ -41,20 +41,19 @@ namespace grpc { // CallData // -void CallData::StartTransportStreamOp( - grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_transport_stream_op *op) { +void CallData::StartTransportStreamOp(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_transport_stream_op *op) { grpc_call_next_op(exec_ctx, elem, op); } -void CallData::SetPollsetOrPollsetSet( - grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_polling_entity *pollent) { +void CallData::SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_polling_entity *pollent) { grpc_call_stack_ignore_set_pollset_or_pollset_set(exec_ctx, elem, pollent); } -char* CallData::GetPeer( - grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { +char *CallData::GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { return grpc_call_next_get_peer(exec_ctx, elem); } @@ -62,9 +61,9 @@ char* CallData::GetPeer( // ChannelData // -void ChannelData::StartTransportOp( - grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, - grpc_transport_op *op) { +void ChannelData::StartTransportOp(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_transport_op *op) { grpc_channel_next_op(exec_ctx, elem, op); } @@ -74,29 +73,28 @@ void ChannelData::StartTransportOp( namespace internal { -std::vector* channel_filters = nullptr; +std::vector *channel_filters = nullptr; namespace { -bool MaybeAddFilter(grpc_channel_stack_builder* builder, void* arg) { - const FilterRecord& filter = *(FilterRecord*)arg; +bool MaybeAddFilter(grpc_channel_stack_builder *builder, void *arg) { + const FilterRecord &filter = *(FilterRecord *)arg; if (filter.include_filter != nullptr) { const grpc_channel_args *args = grpc_channel_stack_builder_get_channel_arguments(builder); - if (!filter.include_filter(*args)) - return true; + if (!filter.include_filter(*args)) return true; } - return grpc_channel_stack_builder_prepend_filter( - builder, &filter.filter, nullptr, nullptr); + return grpc_channel_stack_builder_prepend_filter(builder, &filter.filter, + nullptr, nullptr); } } // namespace void ChannelFilterPluginInit() { for (size_t i = 0; i < channel_filters->size(); ++i) { - FilterRecord& filter = (*channel_filters)[i]; + FilterRecord &filter = (*channel_filters)[i]; grpc_channel_init_register_stage(filter.stack_type, filter.priority, - MaybeAddFilter, (void*)&filter); + MaybeAddFilter, (void *)&filter); } } diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc index 16151c21b84..d72e8100d74 100644 --- a/test/cpp/end2end/filter_end2end_test.cc +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -107,11 +107,9 @@ class CallDataImpl : public CallData { : CallData(channel_data) {} virtual ~CallDataImpl() {} - void StartTransportStreamOp( - grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_transport_stream_op *op) { - if (op->recv_initial_metadata != nullptr) - IncrementCounter(); + void StartTransportStreamOp(grpc_exec_ctx* exec_ctx, grpc_call_element* elem, + grpc_transport_stream_op* op) { + if (op->recv_initial_metadata != nullptr) IncrementCounter(); grpc_call_next_op(exec_ctx, elem, op); } }; From 905227049b494d6ecd3e8bf4ae0f00e3f499f0cf Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 16 Jun 2016 11:40:25 -0700 Subject: [PATCH 016/279] Remove unnecessary code from test. --- test/cpp/end2end/filter_end2end_test.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc index d72e8100d74..7cb77be42d4 100644 --- a/test/cpp/end2end/filter_end2end_test.cc +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -126,10 +126,6 @@ class FilterEnd2endTest : public ::testing::Test { builder.AddListeningPort(server_address_.str(), InsecureServerCredentials()); builder.RegisterAsyncGenericService(&generic_service_); - // Include a second call to RegisterAsyncGenericService to make sure that - // we get an error in the log, since it is not allowed to have 2 async - // generic services - builder.RegisterAsyncGenericService(&generic_service_); srv_cq_ = builder.AddCompletionQueue(); server_ = builder.BuildAndStart(); } From f5bbff9c8e314e29e12e9891c75908f60d941a5f Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 16 Jun 2016 12:56:07 -0700 Subject: [PATCH 017/279] Fix portability issues. --- src/cpp/common/channel_filter.cc | 5 +++-- test/cpp/end2end/filter_end2end_test.cc | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cpp/common/channel_filter.cc b/src/cpp/common/channel_filter.cc index 86df47903fd..f81a01c62d2 100644 --- a/src/cpp/common/channel_filter.cc +++ b/src/cpp/common/channel_filter.cc @@ -73,13 +73,14 @@ void ChannelData::StartTransportOp(grpc_exec_ctx *exec_ctx, namespace internal { -std::vector *channel_filters = nullptr; +// Note: Implicitly initialized to nullptr due to static lifetime. +std::vector *channel_filters; namespace { bool MaybeAddFilter(grpc_channel_stack_builder *builder, void *arg) { const FilterRecord &filter = *(FilterRecord *)arg; - if (filter.include_filter != nullptr) { + if (filter.include_filter) { const grpc_channel_args *args = grpc_channel_stack_builder_get_channel_arguments(builder); if (!filter.include_filter(*args)) return true; diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc index 7cb77be42d4..4ba3b9e0d1c 100644 --- a/test/cpp/end2end/filter_end2end_test.cc +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -108,7 +108,7 @@ class CallDataImpl : public CallData { virtual ~CallDataImpl() {} void StartTransportStreamOp(grpc_exec_ctx* exec_ctx, grpc_call_element* elem, - grpc_transport_stream_op* op) { + grpc_transport_stream_op* op) GRPC_OVERRIDE { if (op->recv_initial_metadata != nullptr) IncrementCounter(); grpc_call_next_op(exec_ctx, elem, op); } From 9fe5ef5f9d17289f57ee1d5436314c3153b80975 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 16 Jun 2016 14:26:04 -0700 Subject: [PATCH 018/279] Removed unnecessary comments. Added connection counter to test. --- include/grpc++/channel_filter.h | 2 - src/cpp/common/channel_filter.cc | 20 ++++----- test/cpp/end2end/filter_end2end_test.cc | 54 ++++++++++++++++++------- 3 files changed, 50 insertions(+), 26 deletions(-) diff --git a/include/grpc++/channel_filter.h b/include/grpc++/channel_filter.h index f73abe8e6c1..542e6a0f35d 100644 --- a/include/grpc++/channel_filter.h +++ b/include/grpc++/channel_filter.h @@ -54,7 +54,6 @@ namespace grpc { // Represents channel data. -// Note: Must be copyable. class ChannelData { public: virtual ~ChannelData() {} @@ -68,7 +67,6 @@ class ChannelData { }; // Represents call data. -// Note: Must be copyable. class CallData { public: virtual ~CallData() {} diff --git a/src/cpp/common/channel_filter.cc b/src/cpp/common/channel_filter.cc index f81a01c62d2..f473d63a257 100644 --- a/src/cpp/common/channel_filter.cc +++ b/src/cpp/common/channel_filter.cc @@ -37,6 +37,16 @@ namespace grpc { +// +// ChannelData +// + +void ChannelData::StartTransportOp(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_transport_op *op) { + grpc_channel_next_op(exec_ctx, elem, op); +} + // // CallData // @@ -57,16 +67,6 @@ char *CallData::GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { return grpc_call_next_get_peer(exec_ctx, elem); } -// -// ChannelData -// - -void ChannelData::StartTransportOp(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem, - grpc_transport_op *op) { - grpc_channel_next_op(exec_ctx, elem, op); -} - // // RegisterChannelFilter() // diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc index 4ba3b9e0d1c..b21d377d5dd 100644 --- a/test/cpp/end2end/filter_end2end_test.cc +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -75,20 +75,36 @@ void verify_ok(CompletionQueue* cq, int i, bool expect_ok) { namespace { +int global_num_connections = 0; int global_num_calls = 0; mutex global_mu; -void IncrementCounter() { +void IncrementConnectionCounter() { + unique_lock lock(global_mu); + ++global_num_connections; +} + +void ResetConnectionCounter() { + unique_lock lock(global_mu); + global_num_connections = 0; +} + +int GetConnectionCounterValue() { + unique_lock lock(global_mu); + return global_num_connections; +} + +void IncrementCallCounter() { unique_lock lock(global_mu); ++global_num_calls; } -void ResetCounter() { +void ResetCallCounter() { unique_lock lock(global_mu); global_num_calls = 0; } -int GetCounterValue() { +int GetCallCounterValue() { unique_lock lock(global_mu); return global_num_calls; } @@ -97,19 +113,22 @@ int GetCounterValue() { class ChannelDataImpl : public ChannelData { public: - explicit ChannelDataImpl(const grpc_channel_args& args) : ChannelData(args) {} - virtual ~ChannelDataImpl() {} + ChannelDataImpl(const grpc_channel_args& args, const char* peer) + : ChannelData(args, peer) { + IncrementConnectionCounter(); + } }; class CallDataImpl : public CallData { public: explicit CallDataImpl(const ChannelDataImpl& channel_data) : CallData(channel_data) {} - virtual ~CallDataImpl() {} void StartTransportStreamOp(grpc_exec_ctx* exec_ctx, grpc_call_element* elem, grpc_transport_stream_op* op) GRPC_OVERRIDE { - if (op->recv_initial_metadata != nullptr) IncrementCounter(); + // Incrementing the counter could be done from the ctor, but we want + // to test that the individual methods are actually called correctly. + if (op->recv_initial_metadata != nullptr) IncrementCallCounter(); grpc_call_next_op(exec_ctx, elem, op); } }; @@ -146,7 +165,8 @@ class FilterEnd2endTest : public ::testing::Test { std::shared_ptr channel = CreateChannel(server_address_.str(), InsecureChannelCredentials()); generic_stub_.reset(new GenericStub(channel)); - ResetCounter(); + ResetConnectionCounter(); + ResetCallCounter(); } void server_ok(int i) { verify_ok(srv_cq_.get(), i, true); } @@ -227,22 +247,27 @@ class FilterEnd2endTest : public ::testing::Test { TEST_F(FilterEnd2endTest, SimpleRpc) { ResetStub(); - EXPECT_EQ(0, GetCounterValue()); + EXPECT_EQ(0, GetConnectionCounterValue()); + EXPECT_EQ(0, GetCallCounterValue()); SendRpc(1); - EXPECT_EQ(1, GetCounterValue()); + EXPECT_EQ(1, GetConnectionCounterValue()); + EXPECT_EQ(1, GetCallCounterValue()); } TEST_F(FilterEnd2endTest, SequentialRpcs) { ResetStub(); - EXPECT_EQ(0, GetCounterValue()); + EXPECT_EQ(0, GetConnectionCounterValue()); + EXPECT_EQ(0, GetCallCounterValue()); SendRpc(10); - EXPECT_EQ(10, GetCounterValue()); + EXPECT_EQ(1, GetConnectionCounterValue()); + EXPECT_EQ(10, GetCallCounterValue()); } // One ping, one pong. TEST_F(FilterEnd2endTest, SimpleBidiStreaming) { ResetStub(); - EXPECT_EQ(0, GetCounterValue()); + EXPECT_EQ(0, GetConnectionCounterValue()); + EXPECT_EQ(0, GetCallCounterValue()); const grpc::string kMethodName( "/grpc.cpp.test.util.EchoTestService/BidiStream"); @@ -306,7 +331,8 @@ TEST_F(FilterEnd2endTest, SimpleBidiStreaming) { EXPECT_EQ(send_response.message(), recv_response.message()); EXPECT_TRUE(recv_status.ok()); - EXPECT_EQ(1, GetCounterValue()); + EXPECT_EQ(1, GetCallCounterValue()); + EXPECT_EQ(1, GetConnectionCounterValue()); } } // namespace From 035cb3a3d4fe9634834b5814827e49adc9cf6b69 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 16 Jun 2016 14:52:41 -0700 Subject: [PATCH 019/279] Pass peer string to ChannelData ctor when available. --- include/grpc++/channel_filter.h | 13 +++++++++++-- src/core/lib/transport/transport.h | 8 ++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/include/grpc++/channel_filter.h b/include/grpc++/channel_filter.h index 542e6a0f35d..53e42a7cb81 100644 --- a/include/grpc++/channel_filter.h +++ b/include/grpc++/channel_filter.h @@ -62,8 +62,13 @@ class ChannelData { grpc_channel_element *elem, grpc_transport_op *op); + const char* peer() const { return peer_; } + protected: - explicit ChannelData(const grpc_channel_args &) {} + ChannelData(const grpc_channel_args &args, const char *peer) : peer_(peer) {} + + private: + const char *peer_; // Do not own. }; // Represents call data. @@ -96,8 +101,12 @@ class ChannelFilter { static void InitChannelElement(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_channel_element_args *args) { + const char* peer = args->optional_transport + ? grpc_transport_get_peer(exec_ctx, + args->optional_transport) + : nullptr; // Construct the object in the already-allocated memory. - new (elem->channel_data) ChannelDataType(*args->channel_args); + new (elem->channel_data) ChannelDataType(*args->channel_args, peer); } static void DestroyChannelElement(grpc_exec_ctx *exec_ctx, diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index ed06fc3ed21..107bb802f66 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -43,6 +43,10 @@ #include "src/core/lib/transport/byte_stream.h" #include "src/core/lib/transport/metadata_batch.h" +#ifdef __cplusplus +extern "C" { +#endif + /* forward declarations */ typedef struct grpc_transport grpc_transport; @@ -264,4 +268,8 @@ void grpc_transport_destroy(grpc_exec_ctx *exec_ctx, grpc_transport *transport); char *grpc_transport_get_peer(grpc_exec_ctx *exec_ctx, grpc_transport *transport); +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_TRANSPORT_TRANSPORT_H */ From 4fd2134dafc61af764b18dacee0acd8ef307dcc4 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 20 Jun 2016 09:23:55 -0700 Subject: [PATCH 020/279] Make another .h file accessible from C++. --- src/core/lib/security/context/security_context.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/core/lib/security/context/security_context.h b/src/core/lib/security/context/security_context.h index ef0c06b1fb6..4e7666dfe31 100644 --- a/src/core/lib/security/context/security_context.h +++ b/src/core/lib/security/context/security_context.h @@ -37,6 +37,10 @@ #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/security/credentials/credentials.h" +#ifdef __cplusplus +extern "C" { +#endif + /* --- grpc_auth_context --- High level authentication context object. Can optionally be chained. */ @@ -111,4 +115,8 @@ grpc_auth_context *grpc_auth_context_from_arg(const grpc_arg *arg); grpc_auth_context *grpc_find_auth_context_in_args( const grpc_channel_args *args); +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_SECURITY_CONTEXT_SECURITY_CONTEXT_H */ From 3da684dcacac1b5d523897b76a00d5e62e1163bd Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 20 Jun 2016 13:27:12 -0700 Subject: [PATCH 021/279] Add "final" to ChannelFilter class, so that compiler can un-indirect the filter method calls. --- include/grpc++/channel_filter.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/grpc++/channel_filter.h b/include/grpc++/channel_filter.h index 53e42a7cb81..262739929a0 100644 --- a/include/grpc++/channel_filter.h +++ b/include/grpc++/channel_filter.h @@ -35,6 +35,7 @@ #define GRPCXX_CHANNEL_FILTER_H #include +#include #include #include @@ -94,7 +95,7 @@ namespace internal { // Defines static members for passing to C core. template -class ChannelFilter { +class ChannelFilter GRPC_FINAL { public: static const size_t channel_data_size = sizeof(ChannelDataType); From 083afc225d298db97b37c28034dad1d024bfb0f5 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 20 Jun 2016 13:33:11 -0700 Subject: [PATCH 022/279] Add comments indicating what the grpc_call_context_element values are for each array index. --- src/core/lib/channel/context.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/core/lib/channel/context.h b/src/core/lib/channel/context.h index c50e84279d4..22f4cb62f3b 100644 --- a/src/core/lib/channel/context.h +++ b/src/core/lib/channel/context.h @@ -34,10 +34,19 @@ #ifndef GRPC_CORE_LIB_CHANNEL_CONTEXT_H #define GRPC_CORE_LIB_CHANNEL_CONTEXT_H -/* Call object context pointers */ +// Call object context pointers. + +// Call context is represented as an array of grpc_call_context_elements. +// This enum represents the indexes into the array, where each index +// contains a different type of value. typedef enum { + // Value is either a grpc_client_security_context or a + // grpc_server_security_context. GRPC_CONTEXT_SECURITY = 0, + + // Value is a census_context. GRPC_CONTEXT_TRACING, + GRPC_CONTEXT_COUNT } grpc_context_index; From 7e5d46496b6ad47aa84583260cf7886f7f51da5f Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 22 Jun 2016 08:17:27 -0700 Subject: [PATCH 023/279] Better distribution --- test/cpp/qps/driver.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 147c540840e..2efdc1288ff 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -345,9 +345,7 @@ std::unique_ptr RunScenario( // Reduce channel count so that total channels specified is held regardless // of the number of clients available size_t num_channels = - (i == num_clients - 1) - ? channels_allocated - client_config.client_channels() - : client_config.client_channels() / num_clients; + (client_channels - channels_allocated) / (num_clients - i); channels_allocated += num_channels; per_client_config.set_client_channels(num_channels); From 5856dee7d6728bcdd0aaf8ac98abef4690252d4b Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 22 Jun 2016 16:30:22 -0700 Subject: [PATCH 024/279] Fix compile --- test/cpp/qps/driver.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 6b31225f20a..b59c1efe127 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -31,6 +31,7 @@ * */ +#include #include #include #include @@ -345,9 +346,11 @@ std::unique_ptr RunScenario( // Reduce channel count so that total channels specified is held regardless // of the number of clients available size_t num_channels = - (client_channels - channels_allocated) / (num_clients - i); + (client_config.client_channels() - channels_allocated) / + (num_clients - i); channels_allocated += num_channels; - gpr_log(GPR_DEBUG, "Client %d gets %d channels", i, num_channels); + gpr_log(GPR_DEBUG, "Client %" PRIdPTR " gets %" PRIdPTR " channels", i, + num_channels); per_client_config.set_client_channels(num_channels); ClientArgs args; From 0badbe8b119c7375dfb0f8e6f853180009a2ffb7 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 23 Jun 2016 10:15:12 -0700 Subject: [PATCH 025/279] Change grpc_channel_filter init_call_elem() method to return grpc_error. --- src/core/ext/census/grpc_filter.c | 14 ++++++++------ src/core/ext/client_config/client_channel.c | 6 ++++-- src/core/ext/client_config/subchannel.c | 7 +++++-- .../load_reporting/load_reporting_filter.c | 6 ++++-- src/core/lib/channel/channel_stack.c | 19 ++++++++++++------- src/core/lib/channel/channel_stack.h | 18 ++++++++++-------- src/core/lib/channel/compress_filter.c | 7 +++++-- src/core/lib/channel/connected_channel.c | 13 +++++++------ src/core/lib/channel/http_client_filter.c | 6 ++++-- src/core/lib/channel/http_server_filter.c | 6 ++++-- .../security/transport/client_auth_filter.c | 6 ++++-- .../security/transport/server_auth_filter.c | 7 +++++-- src/core/lib/surface/call.c | 9 ++++++--- src/core/lib/surface/lame_client.c | 7 +++++-- src/core/lib/surface/server.c | 6 ++++-- test/core/channel/channel_stack_test.c | 12 ++++++++---- test/core/end2end/tests/filter_causes_close.c | 7 +++++-- 17 files changed, 100 insertions(+), 56 deletions(-) diff --git a/src/core/ext/census/grpc_filter.c b/src/core/ext/census/grpc_filter.c index 72e4e5427eb..dd2e2e01244 100644 --- a/src/core/ext/census/grpc_filter.c +++ b/src/core/ext/census/grpc_filter.c @@ -124,13 +124,14 @@ static void server_start_transport_op(grpc_exec_ctx *exec_ctx, grpc_call_next_op(exec_ctx, elem, op); } -static void client_init_call_elem(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error* client_init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { call_data *d = elem->call_data; GPR_ASSERT(d != NULL); memset(d, 0, sizeof(*d)); d->start_ts = gpr_now(GPR_CLOCK_REALTIME); + return GRPC_ERROR_NONE; } static void client_destroy_call_elem(grpc_exec_ctx *exec_ctx, @@ -142,15 +143,16 @@ static void client_destroy_call_elem(grpc_exec_ctx *exec_ctx, /* TODO(hongyu): record rpc client stats and census_rpc_end_op here */ } -static void server_init_call_elem(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error* server_init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { call_data *d = elem->call_data; GPR_ASSERT(d != NULL); memset(d, 0, sizeof(*d)); d->start_ts = gpr_now(GPR_CLOCK_REALTIME); /* TODO(hongyu): call census_tracing_start_op here. */ grpc_closure_init(&d->finish_recv, server_on_done_recv, elem); + return GRPC_ERROR_NONE; } static void server_destroy_call_elem(grpc_exec_ctx *exec_ctx, diff --git a/src/core/ext/client_config/client_channel.c b/src/core/ext/client_config/client_channel.c index 1d5a7d52246..b0a09dab932 100644 --- a/src/core/ext/client_config/client_channel.c +++ b/src/core/ext/client_config/client_channel.c @@ -430,10 +430,12 @@ static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp, } /* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { grpc_subchannel_call_holder_init(elem->call_data, cc_pick_subchannel, elem, args->call_stack); + return GRPC_ERROR_NONE; } /* Destructor for call_data */ diff --git a/src/core/ext/client_config/subchannel.c b/src/core/ext/client_config/subchannel.c index 468067ea57c..2e9cf7d7d4e 100644 --- a/src/core/ext/client_config/subchannel.c +++ b/src/core/ext/client_config/subchannel.c @@ -709,8 +709,11 @@ grpc_subchannel_call *grpc_connected_subchannel_create_call( grpc_call_stack *callstk = SUBCHANNEL_CALL_TO_CALL_STACK(call); call->connection = con; GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call"); - grpc_call_stack_init(exec_ctx, chanstk, 1, subchannel_call_destroy, call, - NULL, NULL, callstk); + grpc_error* error = grpc_call_stack_init(exec_ctx, chanstk, 1, + subchannel_call_destroy, call, + NULL, NULL, callstk); +// FIXME: handle error (probably requires changing this function's API) +GPR_ASSERT(error == GRPC_ERROR_NONE); grpc_call_stack_set_pollset_or_pollset_set(exec_ctx, callstk, pollent); return call; } diff --git a/src/core/ext/load_reporting/load_reporting_filter.c b/src/core/ext/load_reporting/load_reporting_filter.c index f372f88c3a6..cfe752d6e2b 100644 --- a/src/core/ext/load_reporting/load_reporting_filter.c +++ b/src/core/ext/load_reporting/load_reporting_filter.c @@ -56,10 +56,12 @@ static void invoke_lr_fn_locked(grpc_load_reporting_config *lrc, } /* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { call_data *calld = elem->call_data; memset(calld, 0, sizeof(call_data)); + return GRPC_ERROR_NONE; } /* Destructor for call_data */ diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c index bbba85d80ba..0613f94c299 100644 --- a/src/core/lib/channel/channel_stack.c +++ b/src/core/lib/channel/channel_stack.c @@ -157,12 +157,13 @@ void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx, } } -void grpc_call_stack_init(grpc_exec_ctx *exec_ctx, - grpc_channel_stack *channel_stack, int initial_refs, - grpc_iomgr_cb_func destroy, void *destroy_arg, - grpc_call_context_element *context, - const void *transport_server_data, - grpc_call_stack *call_stack) { +grpc_error* grpc_call_stack_init(grpc_exec_ctx *exec_ctx, + grpc_channel_stack *channel_stack, + int initial_refs, grpc_iomgr_cb_func destroy, + void *destroy_arg, + grpc_call_context_element *context, + const void *transport_server_data, + grpc_call_stack *call_stack) { grpc_channel_element *channel_elems = CHANNEL_ELEMS_FROM_STACK(channel_stack); grpc_call_element_args args; size_t count = channel_stack->count; @@ -185,10 +186,14 @@ void grpc_call_stack_init(grpc_exec_ctx *exec_ctx, call_elems[i].filter = channel_elems[i].filter; call_elems[i].channel_data = channel_elems[i].channel_data; call_elems[i].call_data = user_data; - call_elems[i].filter->init_call_elem(exec_ctx, &call_elems[i], &args); + grpc_error* error = call_elems[i].filter->init_call_elem( + exec_ctx, &call_elems[i], &args); + if (error != GRPC_ERROR_NONE) + return error; user_data += ROUND_UP_TO_ALIGNMENT_SIZE(call_elems[i].filter->sizeof_call_data); } + return GRPC_ERROR_NONE; } void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index 41dd4a0d8a1..f56c6540674 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -110,8 +110,9 @@ typedef struct { on a client; if it is non-NULL, then it points to memory owned by the transport and is on the server. Most filters want to ignore this argument. */ - void (*init_call_elem)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args); + grpc_error* (*init_call_elem)(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args); void (*set_pollset_or_pollset_set)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_polling_entity *pollent); @@ -209,12 +210,13 @@ void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx, /* Initialize a call stack given a channel stack. transport_server_data is expected to be NULL on a client, or an opaque transport owned pointer on the server. */ -void grpc_call_stack_init(grpc_exec_ctx *exec_ctx, - grpc_channel_stack *channel_stack, int initial_refs, - grpc_iomgr_cb_func destroy, void *destroy_arg, - grpc_call_context_element *context, - const void *transport_server_data, - grpc_call_stack *call_stack); +grpc_error* grpc_call_stack_init(grpc_exec_ctx *exec_ctx, + grpc_channel_stack *channel_stack, + int initial_refs, grpc_iomgr_cb_func destroy, + void *destroy_arg, + grpc_call_context_element *context, + const void *transport_server_data, + grpc_call_stack *call_stack); /* Set a pollset or a pollset_set for a call stack: must occur before the first * op is started */ void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c index 32ebe53ee64..bcc8e17a9db 100644 --- a/src/core/lib/channel/compress_filter.c +++ b/src/core/lib/channel/compress_filter.c @@ -256,8 +256,9 @@ static void compress_start_transport_stream_op(grpc_exec_ctx *exec_ctx, } /* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { /* grab pointers to our data from the call element */ call_data *calld = elem->call_data; @@ -266,6 +267,8 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, calld->has_compression_algorithm = 0; grpc_closure_init(&calld->got_slice, got_slice, elem); grpc_closure_init(&calld->send_done, send_done, elem); + + return GRPC_ERROR_NONE; } /* Destructor for call_data */ diff --git a/src/core/lib/channel/connected_channel.c b/src/core/lib/channel/connected_channel.c index 0a7d27a1dc5..8dde688df2c 100644 --- a/src/core/lib/channel/connected_channel.c +++ b/src/core/lib/channel/connected_channel.c @@ -81,16 +81,17 @@ static void con_start_transport_op(grpc_exec_ctx *exec_ctx, } /* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; - int r; - - r = grpc_transport_init_stream( + int r = grpc_transport_init_stream( exec_ctx, chand->transport, TRANSPORT_STREAM_FROM_CALL_DATA(calld), &args->call_stack->refcount, args->server_transport_data); - GPR_ASSERT(r == 0); + return r == 0 + ? GRPC_ERROR_NONE + : GRPC_ERROR_CREATE("transport initialization failed"); } static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c index ab6c6c9ef00..30f4ed1f6fc 100644 --- a/src/core/lib/channel/http_client_filter.c +++ b/src/core/lib/channel/http_client_filter.c @@ -169,11 +169,13 @@ static void hc_start_transport_op(grpc_exec_ctx *exec_ctx, } /* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { call_data *calld = elem->call_data; calld->on_done_recv = NULL; grpc_closure_init(&calld->hc_on_recv, hc_on_recv, elem); + return GRPC_ERROR_NONE; } /* Destructor for call_data */ diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/lib/channel/http_server_filter.c index d0beebd817f..960d1ce45e5 100644 --- a/src/core/lib/channel/http_server_filter.c +++ b/src/core/lib/channel/http_server_filter.c @@ -224,13 +224,15 @@ static void hs_start_transport_op(grpc_exec_ctx *exec_ctx, } /* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { /* grab pointers to our data from the call element */ call_data *calld = elem->call_data; /* initialize members */ memset(calld, 0, sizeof(*calld)); grpc_closure_init(&calld->hs_on_recv, hs_on_recv, elem); + return GRPC_ERROR_NONE; } /* Destructor for call_data */ diff --git a/src/core/lib/security/transport/client_auth_filter.c b/src/core/lib/security/transport/client_auth_filter.c index 76be2acd728..6179b9e18cf 100644 --- a/src/core/lib/security/transport/client_auth_filter.c +++ b/src/core/lib/security/transport/client_auth_filter.c @@ -264,10 +264,12 @@ static void auth_start_transport_op(grpc_exec_ctx *exec_ctx, } /* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { call_data *calld = elem->call_data; memset(calld, 0, sizeof(*calld)); + return GRPC_ERROR_NONE; } static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, diff --git a/src/core/lib/security/transport/server_auth_filter.c b/src/core/lib/security/transport/server_auth_filter.c index 12e789bde92..379247131b6 100644 --- a/src/core/lib/security/transport/server_auth_filter.c +++ b/src/core/lib/security/transport/server_auth_filter.c @@ -199,8 +199,9 @@ static void auth_start_transport_op(grpc_exec_ctx *exec_ctx, } /* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { /* grab pointers to our data from the call element */ call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; @@ -222,6 +223,8 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, args->context[GRPC_CONTEXT_SECURITY].value = server_ctx; args->context[GRPC_CONTEXT_SECURITY].destroy = grpc_server_security_context_destroy; + + return GRPC_ERROR_NONE; } /* Destructor for call_data */ diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 04291b0ee0a..d64ca64a15f 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -262,9 +262,12 @@ grpc_call *grpc_call_create( call->send_deadline = send_deadline; GRPC_CHANNEL_INTERNAL_REF(channel, "call"); /* initial refcount dropped by grpc_call_destroy */ - grpc_call_stack_init(&exec_ctx, channel_stack, 1, destroy_call, call, - call->context, server_transport_data, - CALL_STACK_FROM_CALL(call)); + grpc_error* error = grpc_call_stack_init(&exec_ctx, channel_stack, 1, + destroy_call, call, call->context, + server_transport_data, + CALL_STACK_FROM_CALL(call)); +// FIXME: handle error (probably requires changing this function's API) +GPR_ASSERT(error == GRPC_ERROR_NONE); if (cq != NULL) { GPR_ASSERT( pollset_set_alternative == NULL && diff --git a/src/core/lib/surface/lame_client.c b/src/core/lib/surface/lame_client.c index 5ea4cba5d1a..7d9168f2e0b 100644 --- a/src/core/lib/surface/lame_client.c +++ b/src/core/lib/surface/lame_client.c @@ -107,8 +107,11 @@ static void lame_start_transport_op(grpc_exec_ctx *exec_ctx, GRPC_ERROR_UNREF(op->disconnect_with_error); } -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) {} +static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { + return GRPC_ERROR_NONE; +} static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, const grpc_call_stats *stats, diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c index def6e5068b0..0a0c224b4d6 100644 --- a/src/core/lib/surface/server.c +++ b/src/core/lib/surface/server.c @@ -848,8 +848,9 @@ static void channel_connectivity_changed(grpc_exec_ctx *exec_ctx, void *cd, } } -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; memset(calld, 0, sizeof(call_data)); @@ -861,6 +862,7 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, server_on_recv_initial_metadata, elem); server_ref(chand->server); + return GRPC_ERROR_NONE; } static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c index f9561bed707..9c6a47eb520 100644 --- a/test/core/channel/channel_stack_test.c +++ b/test/core/channel/channel_stack_test.c @@ -53,10 +53,12 @@ static void channel_init_func(grpc_exec_ctx *exec_ctx, *(int *)(elem->channel_data) = 0; } -static void call_init_func(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error* call_init_func(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { ++*(int *)(elem->channel_data); *(int *)(elem->call_data) = 0; + return GRPC_ERROR_NONE; } static void channel_destroy_func(grpc_exec_ctx *exec_ctx, @@ -132,8 +134,10 @@ static void test_create_channel_stack(void) { GPR_ASSERT(*channel_data == 0); call_stack = gpr_malloc(channel_stack->call_stack_size); - grpc_call_stack_init(&exec_ctx, channel_stack, 1, free_call, call_stack, NULL, - NULL, call_stack); + grpc_error* error = grpc_call_stack_init(&exec_ctx, channel_stack, 1, + free_call, call_stack, NULL, NULL, + call_stack); + GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(call_stack->count == 1); call_elem = grpc_call_stack_element(call_stack, 0); GPR_ASSERT(call_elem->filter == channel_elem->filter); diff --git a/test/core/end2end/tests/filter_causes_close.c b/test/core/end2end/tests/filter_causes_close.c index 526c05ca3e8..3ff0abed637 100644 --- a/test/core/end2end/tests/filter_causes_close.c +++ b/test/core/end2end/tests/filter_causes_close.c @@ -233,8 +233,11 @@ static void start_transport_stream_op(grpc_exec_ctx *exec_ctx, grpc_call_next_op(exec_ctx, elem, op); } -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) {} +static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { + return GRPC_ERROR_NONE; +} static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, const grpc_call_stats *stats, From 9f97cca37b21fbac12d840fa2337f1fba251e77c Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 23 Jun 2016 10:47:05 -0700 Subject: [PATCH 026/279] Fix error handling in grpc_call_create(). --- src/core/lib/surface/call.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index d64ca64a15f..2e89393815f 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -266,8 +266,18 @@ grpc_call *grpc_call_create( destroy_call, call, call->context, server_transport_data, CALL_STACK_FROM_CALL(call)); -// FIXME: handle error (probably requires changing this function's API) -GPR_ASSERT(error == GRPC_ERROR_NONE); + if (error != GRPC_ERROR_NONE) { + intptr_t status; + if (!grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &status)) + status = GRPC_STATUS_UNKNOWN; + const char* error_string = grpc_error_string(error); + received_status* status_struct = &call->status[STATUS_FROM_CORE]; + status_struct->is_set = true; + status_struct->code = status; + status_struct->details = grpc_mdstr_from_string(error_string); + grpc_error_free_string(error_string); + grpc_error_unref(error); + } if (cq != NULL) { GPR_ASSERT( pollset_set_alternative == NULL && From 09e669878f57e4e4a56bb920d4e3e48615fde55d Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 23 Jun 2016 11:14:18 -0700 Subject: [PATCH 027/279] Propagate error up through grpc_connected_subchannel_create_call(). --- src/core/ext/client_config/subchannel.c | 23 ++++++----- src/core/ext/client_config/subchannel.h | 4 +- .../client_config/subchannel_call_holder.c | 38 ++++++++++++++----- 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/src/core/ext/client_config/subchannel.c b/src/core/ext/client_config/subchannel.c index 2e9cf7d7d4e..80cf154f96a 100644 --- a/src/core/ext/client_config/subchannel.c +++ b/src/core/ext/client_config/subchannel.c @@ -700,22 +700,25 @@ grpc_connected_subchannel *grpc_subchannel_get_connected_subchannel( return GET_CONNECTED_SUBCHANNEL(c, acq); } -grpc_subchannel_call *grpc_connected_subchannel_create_call( +grpc_error *grpc_connected_subchannel_create_call( grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con, - grpc_polling_entity *pollent) { + grpc_polling_entity *pollent, grpc_subchannel_call **call) { grpc_channel_stack *chanstk = CHANNEL_STACK_FROM_CONNECTION(con); - grpc_subchannel_call *call = - gpr_malloc(sizeof(grpc_subchannel_call) + chanstk->call_stack_size); - grpc_call_stack *callstk = SUBCHANNEL_CALL_TO_CALL_STACK(call); - call->connection = con; + *call = gpr_malloc(sizeof(grpc_subchannel_call) + chanstk->call_stack_size); + grpc_call_stack *callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call); + (*call)->connection = con; GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call"); grpc_error* error = grpc_call_stack_init(exec_ctx, chanstk, 1, - subchannel_call_destroy, call, + subchannel_call_destroy, *call, NULL, NULL, callstk); -// FIXME: handle error (probably requires changing this function's API) -GPR_ASSERT(error == GRPC_ERROR_NONE); + if (error != GRPC_ERROR_NONE) { + const char* error_string = grpc_error_string(error); + gpr_log(GPR_ERROR, "error: %s", error_string); + grpc_error_free_string(error_string); + return error; + } grpc_call_stack_set_pollset_or_pollset_set(exec_ctx, callstk, pollent); - return call; + return GRPC_ERROR_NONE; } grpc_call_stack *grpc_subchannel_call_get_call_stack( diff --git a/src/core/ext/client_config/subchannel.h b/src/core/ext/client_config/subchannel.h index b6d39f5dc52..21454cb7a4d 100644 --- a/src/core/ext/client_config/subchannel.h +++ b/src/core/ext/client_config/subchannel.h @@ -108,9 +108,9 @@ void grpc_subchannel_call_unref(grpc_exec_ctx *exec_ctx, GRPC_SUBCHANNEL_REF_EXTRA_ARGS); /** construct a subchannel call */ -grpc_subchannel_call *grpc_connected_subchannel_create_call( +grpc_error *grpc_connected_subchannel_create_call( grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *connected_subchannel, - grpc_polling_entity *pollent); + grpc_polling_entity *pollent, grpc_subchannel_call** subchannel_call); /** process a transport level op */ void grpc_connected_subchannel_process_transport_op( diff --git a/src/core/ext/client_config/subchannel_call_holder.c b/src/core/ext/client_config/subchannel_call_holder.c index e31800edd98..25bd9798f0a 100644 --- a/src/core/ext/client_config/subchannel_call_holder.c +++ b/src/core/ext/client_config/subchannel_call_holder.c @@ -84,6 +84,11 @@ void grpc_subchannel_call_holder_destroy(grpc_exec_ctx *exec_ctx, gpr_free(holder->waiting_ops); } +// The logic here is fairly complicated, due to (a) the fact that we +// need to handle the case where we receive the send op before the +// initial metadata op, and (b) the need for efficiency, especially in +// the streaming case. +// TODO(ctiller): Explain this more thoroughly. void grpc_subchannel_call_holder_perform_op(grpc_exec_ctx *exec_ctx, grpc_subchannel_call_holder *holder, grpc_transport_stream_op *op) { @@ -121,7 +126,8 @@ retry: } /* if this is a cancellation, then we can raise our cancelled flag */ if (op->cancel_with_status != GRPC_STATUS_OK) { - if (!gpr_atm_rel_cas(&holder->subchannel_call, 0, 1)) { + if (!gpr_atm_rel_cas(&holder->subchannel_call, 0, + (gpr_atm)(uintptr_t)CANCELLED_CALL)) { goto retry; } else { switch (holder->creation_phase) { @@ -161,10 +167,17 @@ retry: /* if we've got a subchannel, then let's ask it to create a call */ if (holder->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING && holder->connected_subchannel != NULL) { - gpr_atm_rel_store( - &holder->subchannel_call, - (gpr_atm)(uintptr_t)grpc_connected_subchannel_create_call( - exec_ctx, holder->connected_subchannel, holder->pollent)); + grpc_subchannel_call* subchannel_call = NULL; + grpc_error* error = grpc_connected_subchannel_create_call( + exec_ctx, holder->connected_subchannel, holder->pollent, + &subchannel_call); + if (error != GRPC_ERROR_NONE) { + subchannel_call = CANCELLED_CALL; + fail_locked(exec_ctx, holder, error); + grpc_transport_stream_op_finish_with_failure(exec_ctx, op, error); + } + gpr_atm_rel_store(&holder->subchannel_call, + (gpr_atm)(uintptr_t)subchannel_call); retry_waiting_locked(exec_ctx, holder); goto retry; } @@ -192,10 +205,17 @@ static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg, GRPC_ERROR_CREATE_REFERENCING( "Cancelled before creating subchannel", &error, 1)); } else { - gpr_atm_rel_store( - &holder->subchannel_call, - (gpr_atm)(uintptr_t)grpc_connected_subchannel_create_call( - exec_ctx, holder->connected_subchannel, holder->pollent)); + grpc_subchannel_call* subchannel_call = NULL; + grpc_error* new_error = grpc_connected_subchannel_create_call( + exec_ctx, holder->connected_subchannel, holder->pollent, + &subchannel_call); + if (new_error != GRPC_ERROR_NONE) { + grpc_error_add_child(new_error, error); + subchannel_call = CANCELLED_CALL; + fail_locked(exec_ctx, holder, new_error); + } + gpr_atm_rel_store(&holder->subchannel_call, + (gpr_atm)(uintptr_t)subchannel_call); retry_waiting_locked(exec_ctx, holder); } gpr_mu_unlock(&holder->mu); From 5d11e43ce34b371fb0ab1fa69e541a4d513025b8 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 23 Jun 2016 13:14:05 -0700 Subject: [PATCH 028/279] Added test for filter whose call initialization fails, and fixed bugs uncovered by the test. --- Makefile | 2 + src/core/lib/channel/channel_stack.c | 7 +- src/core/lib/iomgr/error.c | 6 + src/core/lib/iomgr/error.h | 3 + src/core/lib/surface/call.c | 10 +- test/core/end2end/end2end_nosec_tests.c | 8 + test/core/end2end/end2end_tests.c | 8 + test/core/end2end/gen_build_yaml.py | 1 + .../end2end/tests/filter_call_init_fails.c | 263 ++++++++ tools/run_tests/sources_and_headers.json | 2 + tools/run_tests/tests.json | 627 +++++++++++++++++- .../end2end_nosec_tests.vcxproj | 2 + .../end2end_nosec_tests.vcxproj.filters | 3 + .../tests/end2end_tests/end2end_tests.vcxproj | 2 + .../end2end_tests.vcxproj.filters | 3 + 15 files changed, 929 insertions(+), 18 deletions(-) create mode 100644 test/core/end2end/tests/filter_call_init_fails.c diff --git a/Makefile b/Makefile index 9be3e5784cc..8e5d0102c3f 100644 --- a/Makefile +++ b/Makefile @@ -6366,6 +6366,7 @@ LIBEND2END_TESTS_SRC = \ test/core/end2end/tests/default_host.c \ test/core/end2end/tests/disappearing_server.c \ test/core/end2end/tests/empty_batch.c \ + test/core/end2end/tests/filter_call_init_fails.c \ test/core/end2end/tests/filter_causes_close.c \ test/core/end2end/tests/graceful_server_shutdown.c \ test/core/end2end/tests/high_initial_seqno.c \ @@ -6443,6 +6444,7 @@ LIBEND2END_NOSEC_TESTS_SRC = \ test/core/end2end/tests/default_host.c \ test/core/end2end/tests/disappearing_server.c \ test/core/end2end/tests/empty_batch.c \ + test/core/end2end/tests/filter_call_init_fails.c \ test/core/end2end/tests/filter_causes_close.c \ test/core/end2end/tests/graceful_server_shutdown.c \ test/core/end2end/tests/high_initial_seqno.c \ diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c index 0613f94c299..715f6316254 100644 --- a/src/core/lib/channel/channel_stack.c +++ b/src/core/lib/channel/channel_stack.c @@ -179,6 +179,7 @@ grpc_error* grpc_call_stack_init(grpc_exec_ctx *exec_ctx, ROUND_UP_TO_ALIGNMENT_SIZE(count * sizeof(grpc_call_element)); /* init per-filter data */ + grpc_error* first_error = GRPC_ERROR_NONE; for (i = 0; i < count; i++) { args.call_stack = call_stack; args.server_transport_data = transport_server_data; @@ -188,12 +189,12 @@ grpc_error* grpc_call_stack_init(grpc_exec_ctx *exec_ctx, call_elems[i].call_data = user_data; grpc_error* error = call_elems[i].filter->init_call_elem( exec_ctx, &call_elems[i], &args); - if (error != GRPC_ERROR_NONE) - return error; + if (error != GRPC_ERROR_NONE && first_error == GRPC_ERROR_NONE) + first_error = error; user_data += ROUND_UP_TO_ALIGNMENT_SIZE(call_elems[i].filter->sizeof_call_data); } - return GRPC_ERROR_NONE; + return first_error; } void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, diff --git a/src/core/lib/iomgr/error.c b/src/core/lib/iomgr/error.c index 540fb4fa7e4..1b15963e57d 100644 --- a/src/core/lib/iomgr/error.c +++ b/src/core/lib/iomgr/error.c @@ -286,6 +286,12 @@ grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which, return new; } +const char *grpc_error_get_str(grpc_error *error, grpc_error_strs which) { + void *s = NULL; + gpr_avl_maybe_get(error->strs, (void *)(uintptr_t)which, &s); + return s; +} + grpc_error *grpc_error_add_child(grpc_error *src, grpc_error *child) { grpc_error *new = copy_error_and_unref(src); new->errs = gpr_avl_add(new->errs, (void *)(new->next_err++), child); diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index 69cdf3028e4..4bff591fe31 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -169,6 +169,9 @@ grpc_error *grpc_error_set_time(grpc_error *src, grpc_error_times which, gpr_timespec value); grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which, const char *value); +/// Returns NULL if the specified string is not set. +/// Caller does NOT own return value. +const char *grpc_error_get_str(grpc_error *error, grpc_error_strs which); /// Add a child error: an error that is believed to have contributed to this /// error occurring. Allows root causing high level errors from lower level /// errors that contributed to them. diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 2e89393815f..d68afff39f7 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -270,12 +270,10 @@ grpc_call *grpc_call_create( intptr_t status; if (!grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &status)) status = GRPC_STATUS_UNKNOWN; - const char* error_string = grpc_error_string(error); - received_status* status_struct = &call->status[STATUS_FROM_CORE]; - status_struct->is_set = true; - status_struct->code = status; - status_struct->details = grpc_mdstr_from_string(error_string); - grpc_error_free_string(error_string); + const char* error_str = grpc_error_get_str(error, + GRPC_ERROR_STR_DESCRIPTION); + close_with_status(&exec_ctx, call, status, + error_str == NULL ? "unknown error" : error_str); grpc_error_unref(error); } if (cq != NULL) { diff --git a/test/core/end2end/end2end_nosec_tests.c b/test/core/end2end/end2end_nosec_tests.c index 2893bddc43c..03959308987 100644 --- a/test/core/end2end/end2end_nosec_tests.c +++ b/test/core/end2end/end2end_nosec_tests.c @@ -69,6 +69,8 @@ extern void disappearing_server(grpc_end2end_test_config config); extern void disappearing_server_pre_init(void); extern void empty_batch(grpc_end2end_test_config config); extern void empty_batch_pre_init(void); +extern void filter_call_init_fails(grpc_end2end_test_config config); +extern void filter_call_init_fails_pre_init(void); extern void filter_causes_close(grpc_end2end_test_config config); extern void filter_causes_close_pre_init(void); extern void graceful_server_shutdown(grpc_end2end_test_config config); @@ -136,6 +138,7 @@ void grpc_end2end_tests_pre_init(void) { default_host_pre_init(); disappearing_server_pre_init(); empty_batch_pre_init(); + filter_call_init_fails_pre_init(); filter_causes_close_pre_init(); graceful_server_shutdown_pre_init(); high_initial_seqno_pre_init(); @@ -183,6 +186,7 @@ void grpc_end2end_tests(int argc, char **argv, default_host(config); disappearing_server(config); empty_batch(config); + filter_call_init_fails(config); filter_causes_close(config); graceful_server_shutdown(config); high_initial_seqno(config); @@ -264,6 +268,10 @@ void grpc_end2end_tests(int argc, char **argv, empty_batch(config); continue; } + if (0 == strcmp("filter_call_init_fails", argv[i])) { + filter_call_init_fails(config); + continue; + } if (0 == strcmp("filter_causes_close", argv[i])) { filter_causes_close(config); continue; diff --git a/test/core/end2end/end2end_tests.c b/test/core/end2end/end2end_tests.c index 96a38e76dcc..1d6ada72540 100644 --- a/test/core/end2end/end2end_tests.c +++ b/test/core/end2end/end2end_tests.c @@ -71,6 +71,8 @@ extern void disappearing_server(grpc_end2end_test_config config); extern void disappearing_server_pre_init(void); extern void empty_batch(grpc_end2end_test_config config); extern void empty_batch_pre_init(void); +extern void filter_call_init_fails(grpc_end2end_test_config config); +extern void filter_call_init_fails_pre_init(void); extern void filter_causes_close(grpc_end2end_test_config config); extern void filter_causes_close_pre_init(void); extern void graceful_server_shutdown(grpc_end2end_test_config config); @@ -139,6 +141,7 @@ void grpc_end2end_tests_pre_init(void) { default_host_pre_init(); disappearing_server_pre_init(); empty_batch_pre_init(); + filter_call_init_fails_pre_init(); filter_causes_close_pre_init(); graceful_server_shutdown_pre_init(); high_initial_seqno_pre_init(); @@ -187,6 +190,7 @@ void grpc_end2end_tests(int argc, char **argv, default_host(config); disappearing_server(config); empty_batch(config); + filter_call_init_fails(config); filter_causes_close(config); graceful_server_shutdown(config); high_initial_seqno(config); @@ -272,6 +276,10 @@ void grpc_end2end_tests(int argc, char **argv, empty_batch(config); continue; } + if (0 == strcmp("filter_call_init_fails", argv[i])) { + filter_call_init_fails(config); + continue; + } if (0 == strcmp("filter_causes_close", argv[i])) { filter_causes_close(config); continue; diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index 6d3d8f8d3c4..5037559fea0 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -102,6 +102,7 @@ END2END_TESTS = { 'disappearing_server': connectivity_test_options, 'empty_batch': default_test_options, 'filter_causes_close': default_test_options, + 'filter_call_init_fails': default_test_options, 'graceful_server_shutdown': default_test_options._replace(cpu_cost=LOWCPU), 'hpack_size': default_test_options._replace(proxyable=False, traceable=False), diff --git a/test/core/end2end/tests/filter_call_init_fails.c b/test/core/end2end/tests/filter_call_init_fails.c new file mode 100644 index 00000000000..d97369fa98b --- /dev/null +++ b/test/core/end2end/tests/filter_call_init_fails.c @@ -0,0 +1,263 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "test/core/end2end/end2end_tests.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include "src/core/lib/channel/channel_stack_builder.h" +#include "src/core/lib/surface/channel_init.h" +#include "test/core/end2end/cq_verifier.h" + +enum { TIMEOUT = 200000 }; + +static bool g_enable_filter = false; + +static void *tag(intptr_t t) { return (void *)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char *test_name, + grpc_channel_args *client_args, + grpc_channel_args *server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "%s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_time(int n) { + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); +} + +static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } + +static void drain_cq(grpc_completion_queue *cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture *f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = NULL; +} + +static void shutdown_client(grpc_end2end_test_fixture *f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = NULL; +} + +static void end_test(grpc_end2end_test_fixture *f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); +} + +// Simple request via a server filter that always fails to initialize +// the call. +static void test_request(grpc_end2end_test_config config) { + grpc_call *c; + grpc_call *s; + gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world"); + grpc_byte_buffer *request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + gpr_timespec deadline = five_seconds_time(); + grpc_end2end_test_fixture f = + begin_test(config, "filter_call_init_fails", NULL, NULL); + cq_verifier *cqv = cq_verifier_create(f.cq); + grpc_op ops[6]; + grpc_op *op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_byte_buffer *request_payload_recv = NULL; + grpc_call_details call_details; + grpc_status_code status; + grpc_call_error error; + char *details = NULL; + size_t details_capacity = 0; + + c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, + "/foo", "foo.test.google.fr", deadline, NULL); + GPR_ASSERT(c); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->data.send_initial_metadata.metadata = NULL; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message = request_payload; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op->data.recv_status_on_client.status_details_capacity = &details_capacity; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + + cq_expect_completion(cqv, tag(1), 1); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED); + GPR_ASSERT(0 == strcmp(details, "access denied")); + + gpr_free(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + + grpc_call_destroy(c); + + cq_verifier_destroy(cqv); + + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(request_payload_recv); + + end_test(&f); + config.tear_down_data(&f); +} + +/******************************************************************************* + * Test filter - always fails to initialize a call + */ + +static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { + return grpc_error_set_int(GRPC_ERROR_CREATE("access denied"), + GRPC_ERROR_INT_GRPC_STATUS, + GRPC_STATUS_PERMISSION_DENIED); +} + +static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + const grpc_call_stats *stats, + void *and_free_memory) {} + +static void init_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_channel_element_args *args) {} + +static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem) {} + +static const grpc_channel_filter test_filter = { + grpc_call_next_op, + grpc_channel_next_op, + 0, + init_call_elem, + grpc_call_stack_ignore_set_pollset_or_pollset_set, + destroy_call_elem, + 0, + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + "filter_call_init_fails"}; + +/******************************************************************************* + * Registration + */ + +static bool maybe_add_filter(grpc_channel_stack_builder *builder, void *arg) { + if (g_enable_filter) { + return grpc_channel_stack_builder_prepend_filter(builder, &test_filter, + NULL, NULL); + } else { + return true; + } +} + +static void init_plugin(void) { + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, 0, maybe_add_filter, + NULL); +} + +static void destroy_plugin(void) {} + +void filter_call_init_fails(grpc_end2end_test_config config) { + g_enable_filter = true; + test_request(config); + g_enable_filter = false; +} + +void filter_call_init_fails_pre_init(void) { + grpc_register_plugin(init_plugin, destroy_plugin); +} diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 00018834af9..2bea121baad 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -5377,6 +5377,7 @@ "test/core/end2end/tests/default_host.c", "test/core/end2end/tests/disappearing_server.c", "test/core/end2end/tests/empty_batch.c", + "test/core/end2end/tests/filter_call_init_fails.c", "test/core/end2end/tests/filter_causes_close.c", "test/core/end2end/tests/graceful_server_shutdown.c", "test/core/end2end/tests/high_initial_seqno.c", @@ -5436,6 +5437,7 @@ "test/core/end2end/tests/default_host.c", "test/core/end2end/tests/disappearing_server.c", "test/core/end2end/tests/empty_batch.c", + "test/core/end2end/tests/filter_call_init_fails.c", "test/core/end2end/tests/filter_causes_close.c", "test/core/end2end/tests/graceful_server_shutdown.c", "test/core/end2end/tests/high_initial_seqno.c", diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index c62058ede4e..381931db0fa 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -4680,6 +4680,28 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_census_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -5538,6 +5560,28 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_compress_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -6382,6 +6426,27 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_fakesec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -7127,6 +7192,26 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_fd_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -7895,6 +7980,28 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_full_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -8669,6 +8776,22 @@ "linux" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_full+pipe_test", + "platforms": [ + "linux" + ] + }, { "args": [ "filter_causes_close" @@ -9377,6 +9500,28 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_full+trace_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -10213,6 +10358,28 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_loadreporting_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -11057,6 +11224,27 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_oauth2_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -11834,6 +12022,27 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_proxy_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -12506,6 +12715,27 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_sockpair_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -13220,6 +13450,27 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_sockpair+trace_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -13915,7 +14166,7 @@ }, { "args": [ - "filter_causes_close" + "filter_call_init_fails" ], "ci_platforms": [ "windows", @@ -13936,14 +14187,14 @@ }, { "args": [ - "graceful_server_shutdown" + "filter_causes_close" ], "ci_platforms": [ "windows", "linux", "posix" ], - "cpu_cost": 0.1, + "cpu_cost": 1.0, "exclude_configs": [], "flaky": false, "language": "c", @@ -13957,14 +14208,14 @@ }, { "args": [ - "high_initial_seqno" + "graceful_server_shutdown" ], "ci_platforms": [ "windows", "linux", "posix" ], - "cpu_cost": 1.0, + "cpu_cost": 0.1, "exclude_configs": [], "flaky": false, "language": "c", @@ -13978,7 +14229,7 @@ }, { "args": [ - "hpack_size" + "high_initial_seqno" ], "ci_platforms": [ "windows", @@ -13999,7 +14250,7 @@ }, { "args": [ - "idempotent_request" + "hpack_size" ], "ci_platforms": [ "windows", @@ -14020,7 +14271,7 @@ }, { "args": [ - "invoke_large_request" + "idempotent_request" ], "ci_platforms": [ "windows", @@ -14041,7 +14292,28 @@ }, { "args": [ - "large_metadata" + "invoke_large_request" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_sockpair_1byte_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "large_metadata" ], "ci_platforms": [ "windows", @@ -14704,6 +14976,28 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -15562,6 +15856,28 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cert_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -16364,6 +16680,27 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_proxy_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -17065,6 +17402,26 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -17851,6 +18208,28 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_census_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -18687,6 +19066,28 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_compress_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -19437,6 +19838,26 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_fd_nosec_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -20183,6 +20604,28 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_full_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -20941,6 +21384,22 @@ "linux" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_full+pipe_nosec_test", + "platforms": [ + "linux" + ] + }, { "args": [ "filter_causes_close" @@ -21627,6 +22086,28 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_full+trace_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -22441,6 +22922,28 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_loadreporting_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -23222,6 +23725,27 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_proxy_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -23873,6 +24397,27 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_sockpair_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -24566,6 +25111,27 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_sockpair+trace_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -25258,6 +25824,29 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [ + "msan" + ], + "flaky": false, + "language": "c", + "name": "h2_sockpair_1byte_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" @@ -26027,6 +26616,26 @@ "posix" ] }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_uds_nosec_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_causes_close" diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj index 923c1d1ab41..eb5f285c663 100644 --- a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj +++ b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj @@ -179,6 +179,8 @@ + + diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters index 6533eaa057b..9995b92ae56 100644 --- a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters +++ b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters @@ -43,6 +43,9 @@ test\core\end2end\tests + + test\core\end2end\tests + test\core\end2end\tests diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj index 0b859e25ce4..33132e1138f 100644 --- a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj +++ b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj @@ -181,6 +181,8 @@ + + diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters index ea1c5e3c237..484fb0c9cc5 100644 --- a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters +++ b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters @@ -46,6 +46,9 @@ test\core\end2end\tests + + test\core\end2end\tests + test\core\end2end\tests From 76d24420d7a6471dc3b135b62318277991ebdb08 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 23 Jun 2016 13:22:10 -0700 Subject: [PATCH 029/279] clang-format --- src/core/ext/census/grpc_filter.c | 4 ++-- src/core/ext/client_config/client_channel.c | 2 +- src/core/ext/client_config/subchannel.c | 8 ++++---- src/core/ext/client_config/subchannel.h | 2 +- src/core/ext/client_config/subchannel_call_holder.c | 8 ++++---- src/core/ext/load_reporting/load_reporting_filter.c | 2 +- src/core/lib/channel/channel_stack.c | 8 ++++---- src/core/lib/channel/channel_stack.h | 4 ++-- src/core/lib/channel/compress_filter.c | 2 +- src/core/lib/channel/connected_channel.c | 7 +++---- src/core/lib/channel/http_client_filter.c | 2 +- src/core/lib/channel/http_server_filter.c | 2 +- .../lib/security/transport/client_auth_filter.c | 2 +- .../lib/security/transport/server_auth_filter.c | 2 +- src/core/lib/surface/call.c | 13 ++++++------- src/core/lib/surface/lame_client.c | 2 +- src/core/lib/surface/server.c | 2 +- test/core/channel/channel_stack_test.c | 8 ++++---- test/core/end2end/tests/filter_call_init_fails.c | 2 +- test/core/end2end/tests/filter_causes_close.c | 2 +- 20 files changed, 41 insertions(+), 43 deletions(-) diff --git a/src/core/ext/census/grpc_filter.c b/src/core/ext/census/grpc_filter.c index dd2e2e01244..c5a6e6d3dc2 100644 --- a/src/core/ext/census/grpc_filter.c +++ b/src/core/ext/census/grpc_filter.c @@ -124,7 +124,7 @@ static void server_start_transport_op(grpc_exec_ctx *exec_ctx, grpc_call_next_op(exec_ctx, elem, op); } -static grpc_error* client_init_call_elem(grpc_exec_ctx *exec_ctx, +static grpc_error *client_init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { call_data *d = elem->call_data; @@ -143,7 +143,7 @@ static void client_destroy_call_elem(grpc_exec_ctx *exec_ctx, /* TODO(hongyu): record rpc client stats and census_rpc_end_op here */ } -static grpc_error* server_init_call_elem(grpc_exec_ctx *exec_ctx, +static grpc_error *server_init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { call_data *d = elem->call_data; diff --git a/src/core/ext/client_config/client_channel.c b/src/core/ext/client_config/client_channel.c index b0a09dab932..84e3fb4da65 100644 --- a/src/core/ext/client_config/client_channel.c +++ b/src/core/ext/client_config/client_channel.c @@ -430,7 +430,7 @@ static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp, } /* Constructor for call_data */ -static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { grpc_subchannel_call_holder_init(elem->call_data, cc_pick_subchannel, elem, diff --git a/src/core/ext/client_config/subchannel.c b/src/core/ext/client_config/subchannel.c index 80cf154f96a..8a1ac68c6e3 100644 --- a/src/core/ext/client_config/subchannel.c +++ b/src/core/ext/client_config/subchannel.c @@ -708,11 +708,11 @@ grpc_error *grpc_connected_subchannel_create_call( grpc_call_stack *callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call); (*call)->connection = con; GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call"); - grpc_error* error = grpc_call_stack_init(exec_ctx, chanstk, 1, - subchannel_call_destroy, *call, - NULL, NULL, callstk); + grpc_error *error = + grpc_call_stack_init(exec_ctx, chanstk, 1, subchannel_call_destroy, *call, + NULL, NULL, callstk); if (error != GRPC_ERROR_NONE) { - const char* error_string = grpc_error_string(error); + const char *error_string = grpc_error_string(error); gpr_log(GPR_ERROR, "error: %s", error_string); grpc_error_free_string(error_string); return error; diff --git a/src/core/ext/client_config/subchannel.h b/src/core/ext/client_config/subchannel.h index 21454cb7a4d..ae1d96e6400 100644 --- a/src/core/ext/client_config/subchannel.h +++ b/src/core/ext/client_config/subchannel.h @@ -110,7 +110,7 @@ void grpc_subchannel_call_unref(grpc_exec_ctx *exec_ctx, /** construct a subchannel call */ grpc_error *grpc_connected_subchannel_create_call( grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *connected_subchannel, - grpc_polling_entity *pollent, grpc_subchannel_call** subchannel_call); + grpc_polling_entity *pollent, grpc_subchannel_call **subchannel_call); /** process a transport level op */ void grpc_connected_subchannel_process_transport_op( diff --git a/src/core/ext/client_config/subchannel_call_holder.c b/src/core/ext/client_config/subchannel_call_holder.c index 25bd9798f0a..5b542331538 100644 --- a/src/core/ext/client_config/subchannel_call_holder.c +++ b/src/core/ext/client_config/subchannel_call_holder.c @@ -167,8 +167,8 @@ retry: /* if we've got a subchannel, then let's ask it to create a call */ if (holder->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING && holder->connected_subchannel != NULL) { - grpc_subchannel_call* subchannel_call = NULL; - grpc_error* error = grpc_connected_subchannel_create_call( + grpc_subchannel_call *subchannel_call = NULL; + grpc_error *error = grpc_connected_subchannel_create_call( exec_ctx, holder->connected_subchannel, holder->pollent, &subchannel_call); if (error != GRPC_ERROR_NONE) { @@ -205,8 +205,8 @@ static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg, GRPC_ERROR_CREATE_REFERENCING( "Cancelled before creating subchannel", &error, 1)); } else { - grpc_subchannel_call* subchannel_call = NULL; - grpc_error* new_error = grpc_connected_subchannel_create_call( + grpc_subchannel_call *subchannel_call = NULL; + grpc_error *new_error = grpc_connected_subchannel_create_call( exec_ctx, holder->connected_subchannel, holder->pollent, &subchannel_call); if (new_error != GRPC_ERROR_NONE) { diff --git a/src/core/ext/load_reporting/load_reporting_filter.c b/src/core/ext/load_reporting/load_reporting_filter.c index cfe752d6e2b..b584e31c5dd 100644 --- a/src/core/ext/load_reporting/load_reporting_filter.c +++ b/src/core/ext/load_reporting/load_reporting_filter.c @@ -56,7 +56,7 @@ static void invoke_lr_fn_locked(grpc_load_reporting_config *lrc, } /* Constructor for call_data */ -static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { call_data *calld = elem->call_data; diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c index 715f6316254..ff824c781f1 100644 --- a/src/core/lib/channel/channel_stack.c +++ b/src/core/lib/channel/channel_stack.c @@ -157,7 +157,7 @@ void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx, } } -grpc_error* grpc_call_stack_init(grpc_exec_ctx *exec_ctx, +grpc_error *grpc_call_stack_init(grpc_exec_ctx *exec_ctx, grpc_channel_stack *channel_stack, int initial_refs, grpc_iomgr_cb_func destroy, void *destroy_arg, @@ -179,7 +179,7 @@ grpc_error* grpc_call_stack_init(grpc_exec_ctx *exec_ctx, ROUND_UP_TO_ALIGNMENT_SIZE(count * sizeof(grpc_call_element)); /* init per-filter data */ - grpc_error* first_error = GRPC_ERROR_NONE; + grpc_error *first_error = GRPC_ERROR_NONE; for (i = 0; i < count; i++) { args.call_stack = call_stack; args.server_transport_data = transport_server_data; @@ -187,8 +187,8 @@ grpc_error* grpc_call_stack_init(grpc_exec_ctx *exec_ctx, call_elems[i].filter = channel_elems[i].filter; call_elems[i].channel_data = channel_elems[i].channel_data; call_elems[i].call_data = user_data; - grpc_error* error = call_elems[i].filter->init_call_elem( - exec_ctx, &call_elems[i], &args); + grpc_error *error = + call_elems[i].filter->init_call_elem(exec_ctx, &call_elems[i], &args); if (error != GRPC_ERROR_NONE && first_error == GRPC_ERROR_NONE) first_error = error; user_data += diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index f56c6540674..ba7baeb23fc 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -110,7 +110,7 @@ typedef struct { on a client; if it is non-NULL, then it points to memory owned by the transport and is on the server. Most filters want to ignore this argument. */ - grpc_error* (*init_call_elem)(grpc_exec_ctx *exec_ctx, + grpc_error *(*init_call_elem)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args); void (*set_pollset_or_pollset_set)(grpc_exec_ctx *exec_ctx, @@ -210,7 +210,7 @@ void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx, /* Initialize a call stack given a channel stack. transport_server_data is expected to be NULL on a client, or an opaque transport owned pointer on the server. */ -grpc_error* grpc_call_stack_init(grpc_exec_ctx *exec_ctx, +grpc_error *grpc_call_stack_init(grpc_exec_ctx *exec_ctx, grpc_channel_stack *channel_stack, int initial_refs, grpc_iomgr_cb_func destroy, void *destroy_arg, diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c index bcc8e17a9db..5be32929dad 100644 --- a/src/core/lib/channel/compress_filter.c +++ b/src/core/lib/channel/compress_filter.c @@ -256,7 +256,7 @@ static void compress_start_transport_stream_op(grpc_exec_ctx *exec_ctx, } /* Constructor for call_data */ -static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { /* grab pointers to our data from the call element */ diff --git a/src/core/lib/channel/connected_channel.c b/src/core/lib/channel/connected_channel.c index 8dde688df2c..ecafcc99c79 100644 --- a/src/core/lib/channel/connected_channel.c +++ b/src/core/lib/channel/connected_channel.c @@ -81,7 +81,7 @@ static void con_start_transport_op(grpc_exec_ctx *exec_ctx, } /* Constructor for call_data */ -static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { call_data *calld = elem->call_data; @@ -89,9 +89,8 @@ static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, int r = grpc_transport_init_stream( exec_ctx, chand->transport, TRANSPORT_STREAM_FROM_CALL_DATA(calld), &args->call_stack->refcount, args->server_transport_data); - return r == 0 - ? GRPC_ERROR_NONE - : GRPC_ERROR_CREATE("transport initialization failed"); + return r == 0 ? GRPC_ERROR_NONE + : GRPC_ERROR_CREATE("transport initialization failed"); } static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c index 30f4ed1f6fc..7f8ca1dc9f4 100644 --- a/src/core/lib/channel/http_client_filter.c +++ b/src/core/lib/channel/http_client_filter.c @@ -169,7 +169,7 @@ static void hc_start_transport_op(grpc_exec_ctx *exec_ctx, } /* Constructor for call_data */ -static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { call_data *calld = elem->call_data; diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/lib/channel/http_server_filter.c index 960d1ce45e5..e1f76510b63 100644 --- a/src/core/lib/channel/http_server_filter.c +++ b/src/core/lib/channel/http_server_filter.c @@ -224,7 +224,7 @@ static void hs_start_transport_op(grpc_exec_ctx *exec_ctx, } /* Constructor for call_data */ -static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { /* grab pointers to our data from the call element */ diff --git a/src/core/lib/security/transport/client_auth_filter.c b/src/core/lib/security/transport/client_auth_filter.c index 6179b9e18cf..bccb8f755e5 100644 --- a/src/core/lib/security/transport/client_auth_filter.c +++ b/src/core/lib/security/transport/client_auth_filter.c @@ -264,7 +264,7 @@ static void auth_start_transport_op(grpc_exec_ctx *exec_ctx, } /* Constructor for call_data */ -static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { call_data *calld = elem->call_data; diff --git a/src/core/lib/security/transport/server_auth_filter.c b/src/core/lib/security/transport/server_auth_filter.c index 379247131b6..86d4d616371 100644 --- a/src/core/lib/security/transport/server_auth_filter.c +++ b/src/core/lib/security/transport/server_auth_filter.c @@ -199,7 +199,7 @@ static void auth_start_transport_op(grpc_exec_ctx *exec_ctx, } /* Constructor for call_data */ -static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { /* grab pointers to our data from the call element */ diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index d68afff39f7..f862e8dee99 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -262,18 +262,17 @@ grpc_call *grpc_call_create( call->send_deadline = send_deadline; GRPC_CHANNEL_INTERNAL_REF(channel, "call"); /* initial refcount dropped by grpc_call_destroy */ - grpc_error* error = grpc_call_stack_init(&exec_ctx, channel_stack, 1, - destroy_call, call, call->context, - server_transport_data, - CALL_STACK_FROM_CALL(call)); + grpc_error *error = grpc_call_stack_init( + &exec_ctx, channel_stack, 1, destroy_call, call, call->context, + server_transport_data, CALL_STACK_FROM_CALL(call)); if (error != GRPC_ERROR_NONE) { intptr_t status; if (!grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &status)) status = GRPC_STATUS_UNKNOWN; - const char* error_str = grpc_error_get_str(error, - GRPC_ERROR_STR_DESCRIPTION); + const char *error_str = + grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION); close_with_status(&exec_ctx, call, status, - error_str == NULL ? "unknown error" : error_str); + error_str == NULL ? "unknown error" : error_str); grpc_error_unref(error); } if (cq != NULL) { diff --git a/src/core/lib/surface/lame_client.c b/src/core/lib/surface/lame_client.c index 7d9168f2e0b..1cf18ba0605 100644 --- a/src/core/lib/surface/lame_client.c +++ b/src/core/lib/surface/lame_client.c @@ -107,7 +107,7 @@ static void lame_start_transport_op(grpc_exec_ctx *exec_ctx, GRPC_ERROR_UNREF(op->disconnect_with_error); } -static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { return GRPC_ERROR_NONE; diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c index 0a0c224b4d6..165d8aa647a 100644 --- a/src/core/lib/surface/server.c +++ b/src/core/lib/surface/server.c @@ -848,7 +848,7 @@ static void channel_connectivity_changed(grpc_exec_ctx *exec_ctx, void *cd, } } -static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { call_data *calld = elem->call_data; diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c index 9c6a47eb520..d6c8a9a1428 100644 --- a/test/core/channel/channel_stack_test.c +++ b/test/core/channel/channel_stack_test.c @@ -53,7 +53,7 @@ static void channel_init_func(grpc_exec_ctx *exec_ctx, *(int *)(elem->channel_data) = 0; } -static grpc_error* call_init_func(grpc_exec_ctx *exec_ctx, +static grpc_error *call_init_func(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { ++*(int *)(elem->channel_data); @@ -134,9 +134,9 @@ static void test_create_channel_stack(void) { GPR_ASSERT(*channel_data == 0); call_stack = gpr_malloc(channel_stack->call_stack_size); - grpc_error* error = grpc_call_stack_init(&exec_ctx, channel_stack, 1, - free_call, call_stack, NULL, NULL, - call_stack); + grpc_error *error = + grpc_call_stack_init(&exec_ctx, channel_stack, 1, free_call, call_stack, + NULL, NULL, call_stack); GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(call_stack->count == 1); call_elem = grpc_call_stack_element(call_stack, 0); diff --git a/test/core/end2end/tests/filter_call_init_fails.c b/test/core/end2end/tests/filter_call_init_fails.c index d97369fa98b..e8ceb33eb7e 100644 --- a/test/core/end2end/tests/filter_call_init_fails.c +++ b/test/core/end2end/tests/filter_call_init_fails.c @@ -200,7 +200,7 @@ static void test_request(grpc_end2end_test_config config) { * Test filter - always fails to initialize a call */ -static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { return grpc_error_set_int(GRPC_ERROR_CREATE("access denied"), diff --git a/test/core/end2end/tests/filter_causes_close.c b/test/core/end2end/tests/filter_causes_close.c index 3ff0abed637..8b0c8dba61d 100644 --- a/test/core/end2end/tests/filter_causes_close.c +++ b/test/core/end2end/tests/filter_causes_close.c @@ -233,7 +233,7 @@ static void start_transport_stream_op(grpc_exec_ctx *exec_ctx, grpc_call_next_op(exec_ctx, elem, op); } -static grpc_error* init_call_elem(grpc_exec_ctx *exec_ctx, +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { return GRPC_ERROR_NONE; From 7f8db257974a81e16d6865e8bf030a0bd69c10d3 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 24 Jun 2016 08:24:15 -0700 Subject: [PATCH 030/279] Bool-ify a couple of fields in grpc_transport_op. --- src/core/lib/surface/channel.c | 2 +- src/core/lib/surface/server.c | 12 +++++++----- src/core/lib/transport/transport.h | 4 ++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c index f0b3c2e15d1..905b4a97dd5 100644 --- a/src/core/lib/surface/channel.c +++ b/src/core/lib/surface/channel.c @@ -336,7 +336,7 @@ void grpc_channel_destroy(grpc_channel *channel) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; GRPC_API_TRACE("grpc_channel_destroy(channel=%p)", 1, (channel)); memset(&op, 0, sizeof(op)); - op.disconnect = 1; + op.disconnect = true; elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CHANNEL(channel), 0); elem->filter->start_transport_op(&exec_ctx, elem, &op); diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c index 88d898bc1c0..6677e65c4c8 100644 --- a/src/core/lib/surface/server.c +++ b/src/core/lib/surface/server.c @@ -270,7 +270,7 @@ static void shutdown_cleanup(grpc_exec_ctx *exec_ctx, void *arg, } static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel, - int send_goaway, int send_disconnect) { + bool send_goaway, bool send_disconnect) { grpc_transport_op op; struct shutdown_cleanup_args *sc; grpc_channel_element *elem; @@ -291,8 +291,8 @@ static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel, static void channel_broadcaster_shutdown(grpc_exec_ctx *exec_ctx, channel_broadcaster *cb, - int send_goaway, - int force_disconnect) { + bool send_goaway, + bool force_disconnect) { size_t i; for (i = 0; i < cb->num_channels; i++) { @@ -1217,7 +1217,8 @@ void grpc_server_shutdown_and_notify(grpc_server *server, l->destroy(&exec_ctx, server, l->arg, &l->destroy_done); } - channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 1, 0); + channel_broadcaster_shutdown(&exec_ctx, &broadcaster, true /* send_goaway */, + false /* force_disconnect */); done: grpc_exec_ctx_finish(&exec_ctx); @@ -1233,7 +1234,8 @@ void grpc_server_cancel_all_calls(grpc_server *server) { channel_broadcaster_init(server, &broadcaster); gpr_mu_unlock(&server->mu_global); - channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 0, 1); + channel_broadcaster_shutdown(&exec_ctx, &broadcaster, false /* send_goaway */, + true /* force_disconnect */); grpc_exec_ctx_finish(&exec_ctx); } diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index 107bb802f66..b170014dc59 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -159,11 +159,11 @@ typedef struct grpc_transport_op { grpc_closure *on_connectivity_state_change; grpc_connectivity_state *connectivity_state; /** should the transport be disconnected */ - int disconnect; + bool disconnect; /** should we send a goaway? after a goaway is sent, once there are no more active calls on the transport, the transport should disconnect */ - int send_goaway; + bool send_goaway; /** what should the goaway contain? */ grpc_status_code goaway_status; gpr_slice *goaway_message; From 13e343464bd8abd01cec1df2b43f624906552055 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 24 Jun 2016 10:24:43 -0700 Subject: [PATCH 031/279] Another boolification. --- src/core/lib/transport/metadata_batch.c | 3 ++- src/core/lib/transport/metadata_batch.h | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/core/lib/transport/metadata_batch.c b/src/core/lib/transport/metadata_batch.c index e4398abeb78..84b5a74d513 100644 --- a/src/core/lib/transport/metadata_batch.c +++ b/src/core/lib/transport/metadata_batch.c @@ -33,6 +33,7 @@ #include "src/core/lib/transport/metadata_batch.h" +#include #include #include @@ -187,7 +188,7 @@ void grpc_metadata_batch_clear(grpc_metadata_batch *batch) { grpc_metadata_batch_filter(batch, no_metadata_for_you, NULL); } -int grpc_metadata_batch_is_empty(grpc_metadata_batch *batch) { +bool grpc_metadata_batch_is_empty(grpc_metadata_batch *batch) { return batch->list.head == NULL && gpr_time_cmp(gpr_inf_future(batch->deadline.clock_type), batch->deadline) == 0; diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h index 7af823f7ca4..dad0cc55100 100644 --- a/src/core/lib/transport/metadata_batch.h +++ b/src/core/lib/transport/metadata_batch.h @@ -34,6 +34,8 @@ #ifndef GRPC_CORE_LIB_TRANSPORT_METADATA_BATCH_H #define GRPC_CORE_LIB_TRANSPORT_METADATA_BATCH_H +#include + #include #include #include @@ -64,7 +66,7 @@ typedef struct grpc_metadata_batch { void grpc_metadata_batch_init(grpc_metadata_batch *batch); void grpc_metadata_batch_destroy(grpc_metadata_batch *batch); void grpc_metadata_batch_clear(grpc_metadata_batch *batch); -int grpc_metadata_batch_is_empty(grpc_metadata_batch *batch); +bool grpc_metadata_batch_is_empty(grpc_metadata_batch *batch); /* Returns the transport size of the batch. */ size_t grpc_metadata_batch_size(grpc_metadata_batch *batch); From 34d07d6f2a0b7d4c938aaf3502151eebba8b04b5 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 27 Jun 2016 09:53:59 -0700 Subject: [PATCH 032/279] Update comments. --- src/core/lib/transport/byte_stream.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/core/lib/transport/byte_stream.h b/src/core/lib/transport/byte_stream.h index 95519a9eaf7..e64dce62837 100644 --- a/src/core/lib/transport/byte_stream.h +++ b/src/core/lib/transport/byte_stream.h @@ -59,13 +59,9 @@ struct grpc_byte_stream { * on_complete will not be called), 0 if the bytes will be available * asynchronously. * - * on entry, *remaining can be set as a hint as to the maximum number + * max_size_hint can be set as a hint as to the maximum number * of bytes that would be acceptable to read. * - * fills *buffer, *length, *remaining with the bytes, length of bytes - * and length of data remaining to be read before either returning 1 - * or calling on_complete. - * * once a slice is returned into *slice, it is owned by the caller. */ int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx, From 07cd9c9e064e636c432500724bf5f91ad15d041a Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 27 Jun 2016 10:14:38 -0700 Subject: [PATCH 033/279] Initial attempt at a C++ wrapper for the C grpc_transport_op and grpc_transport_stream_op structs. --- include/grpc++/channel_filter.h | 167 +++++++++++++++++++++++- src/core/lib/transport/metadata.h | 8 ++ src/core/lib/transport/metadata_batch.h | 8 ++ src/cpp/common/channel_filter.cc | 23 +++- test/cpp/end2end/filter_end2end_test.cc | 6 +- third_party/protobuf | 2 +- 6 files changed, 200 insertions(+), 14 deletions(-) diff --git a/include/grpc++/channel_filter.h b/include/grpc++/channel_filter.h index 262739929a0..2fa4ad31d81 100644 --- a/include/grpc++/channel_filter.h +++ b/include/grpc++/channel_filter.h @@ -35,13 +35,16 @@ #define GRPCXX_CHANNEL_FILTER_H #include +#include #include #include #include #include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/security/context/security_context.h" #include "src/core/lib/surface/channel_init.h" +#include "src/core/lib/transport/metadata_batch.h" // // An interface to define filters. @@ -54,16 +57,164 @@ namespace grpc { +// A C++ wrapper for the grpc_metadata_batch struct. +class MetadataBatch { + public: + explicit MetadataBatch(grpc_metadata_batch* batch) : batch_(batch) {} + + grpc_metadata_batch* batch() const { return batch_; } + + // Adds metadata and returns the newly allocated storage. + // The caller takes ownership of the result, which must exist for the + // lifetime of the gRPC call. + grpc_linked_mdelem* AddMetadata(const string& key, const string& value); + + class const_iterator : public std::iterator { + public: + const grpc_mdelem& operator*() const { return *elem_->md; } + const grpc_mdelem* operator->() const { return elem_->md; } + + const_iterator& operator++() { + elem_ = elem_->next; + return *this; + } + const_iterator operator++(int) { + const_iterator tmp(*this); + operator++(); + return tmp; + } + const_iterator& operator--() { + elem_ = elem_->prev; + return *this; + } + const_iterator operator--(int) { + const_iterator tmp(*this); + operator--(); + return tmp; + } + + bool operator==(const const_iterator& other) const { + return elem_ == other.elem_; + } + bool operator!=(const const_iterator& other) const { + return elem_ != other.elem_; + } + + private: + friend class MetadataBatch; + explicit const_iterator(grpc_linked_mdelem* elem) : elem_(elem) {} + + grpc_linked_mdelem* elem_; + }; + + const_iterator begin() const { return const_iterator(batch_->list.head); } + const_iterator end() const { return const_iterator(nullptr); } + + private: + grpc_metadata_batch* batch_; +}; + +// A C++ wrapper for the grpc_transport_op struct. +class TransportOp { + public: + explicit TransportOp(grpc_transport_op* op) : op_(op) {} + + grpc_transport_op* op() const { return op_; } + + bool disconnect() const { return op_->disconnect; } + bool send_goaway() const { return op_->send_goaway; } + + // TODO(roth): Add methods for additional fields as needed. + + private: + grpc_transport_op* op_; // Do not own. +}; + +// A C++ wrapper for the grpc_transport_stream_op struct. +class TransportStreamOp { + public: + explicit TransportStreamOp(grpc_transport_stream_op* op) + : op_(op), + send_initial_metadata_(op->send_initial_metadata), + send_trailing_metadata_(op->send_trailing_metadata), + recv_initial_metadata_(op->recv_initial_metadata), + recv_trailing_metadata_(op->recv_trailing_metadata) {} + + grpc_transport_stream_op* op() const { return op_; } + + grpc_closure* on_complete() const { return op_->on_complete; } + void set_on_complete(grpc_closure* closure) { + op_->on_complete = closure; + } + + MetadataBatch* send_initial_metadata() { + return op_->send_initial_metadata == nullptr + ? nullptr : &send_initial_metadata_; + } + MetadataBatch* send_trailing_metadata() { + return op_->send_trailing_metadata == nullptr + ? nullptr : &send_trailing_metadata_; + } + MetadataBatch* recv_initial_metadata() { + return op_->recv_initial_metadata == nullptr + ? nullptr : &recv_initial_metadata_; + } + MetadataBatch* recv_trailing_metadata() { + return op_->recv_trailing_metadata == nullptr + ? nullptr : &recv_trailing_metadata_; + } + + uint32_t* send_initial_metadata_flags() const { + return &op_->send_initial_metadata_flags; + } + + grpc_closure* recv_initial_metadata_ready() const { + return op_->recv_initial_metadata_ready; + } + void set_recv_initial_metadata_ready(grpc_closure* closure) { + op_->recv_initial_metadata_ready = closure; + } + + grpc_byte_stream* send_message() const { return op_->send_message; } + void set_send_message(grpc_byte_stream* send_message) { + op_->send_message = send_message; + } + + // To be called only on clients and servers, respectively. + grpc_client_security_context* client_security_context() const { + return (grpc_client_security_context*)op_->context[ + GRPC_CONTEXT_SECURITY].value; + } + grpc_server_security_context* server_security_context() const { + return (grpc_server_security_context*)op_->context[ + GRPC_CONTEXT_SECURITY].value; + } + + census_context* get_census_context() const { + return (census_context*)op_->context[GRPC_CONTEXT_TRACING].value; + } + + private: + grpc_transport_stream_op* op_; // Do not own. + MetadataBatch send_initial_metadata_; + MetadataBatch send_trailing_metadata_; + MetadataBatch recv_initial_metadata_; + MetadataBatch recv_trailing_metadata_; +}; + // Represents channel data. class ChannelData { public: virtual ~ChannelData() {} + const char* peer() const { return peer_; } + +// FIXME: find a way to avoid passing elem into these methods +// (same for CallData below) virtual void StartTransportOp(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, - grpc_transport_op *op); - - const char* peer() const { return peer_; } + TransportOp *op); protected: ChannelData(const grpc_channel_args &args, const char *peer) : peer_(peer) {} @@ -79,7 +230,7 @@ class CallData { virtual void StartTransportStreamOp(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_transport_stream_op *op); + TransportStreamOp *op); virtual void SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, @@ -88,6 +239,8 @@ class CallData { virtual char *GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem); protected: +// FIXME: once PR #7024 has been merged, update this API to provide a +// way to return an error from call initialization explicit CallData(const ChannelData &) {} }; @@ -119,7 +272,8 @@ class ChannelFilter GRPC_FINAL { grpc_channel_element *elem, grpc_transport_op *op) { ChannelDataType *channel_data = (ChannelDataType *)elem->channel_data; - channel_data->StartTransportOp(exec_ctx, elem, op); + TransportOp op_wrapper(op); + channel_data->StartTransportOp(exec_ctx, elem, &op_wrapper); } static const size_t call_data_size = sizeof(CallDataType); @@ -143,7 +297,8 @@ class ChannelFilter GRPC_FINAL { grpc_call_element *elem, grpc_transport_stream_op *op) { CallDataType *call_data = (CallDataType *)elem->call_data; - call_data->StartTransportStreamOp(exec_ctx, elem, op); + TransportStreamOp op_wrapper(op); + call_data->StartTransportStreamOp(exec_ctx, elem, &op_wrapper); } static void SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx, diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 6d82f4d6819..2b0921c8d74 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -37,6 +37,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /* This file provides a mechanism for tracking metadata through the grpc stack. It's not intended for consumption outside of the library. @@ -164,4 +168,8 @@ void grpc_mdctx_global_shutdown(void); extern gpr_slice (*grpc_chttp2_base64_encode_and_huffman_compress)( gpr_slice input); +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_H */ diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h index dad0cc55100..0424b4db986 100644 --- a/src/core/lib/transport/metadata_batch.h +++ b/src/core/lib/transport/metadata_batch.h @@ -42,6 +42,10 @@ #include #include "src/core/lib/transport/metadata.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct grpc_linked_mdelem { grpc_mdelem *md; struct grpc_linked_mdelem *next; @@ -127,4 +131,8 @@ void grpc_metadata_batch_assert_ok(grpc_metadata_batch *comd); } while (0) #endif +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_BATCH_H */ diff --git a/src/cpp/common/channel_filter.cc b/src/cpp/common/channel_filter.cc index f473d63a257..b2fe3038f52 100644 --- a/src/cpp/common/channel_filter.cc +++ b/src/cpp/common/channel_filter.cc @@ -33,18 +33,33 @@ #include +#include + #include "src/core/lib/channel/channel_stack.h" namespace grpc { +// +// MetadataBatch +// + +grpc_linked_mdelem* MetadataBatch::AddMetadata( + const string& key, const string& value) { + grpc_linked_mdelem *storage = new grpc_linked_mdelem; + memset(storage, 0, sizeof(grpc_linked_mdelem)); + storage->md = grpc_mdelem_from_strings(key.c_str(), value.c_str()); + grpc_metadata_batch_link_head(batch_, storage); + return storage; +} + // // ChannelData // void ChannelData::StartTransportOp(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, - grpc_transport_op *op) { - grpc_channel_next_op(exec_ctx, elem, op); + TransportOp *op) { + grpc_channel_next_op(exec_ctx, elem, op->op()); } // @@ -53,8 +68,8 @@ void ChannelData::StartTransportOp(grpc_exec_ctx *exec_ctx, void CallData::StartTransportStreamOp(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_transport_stream_op *op) { - grpc_call_next_op(exec_ctx, elem, op); + TransportStreamOp *op) { + grpc_call_next_op(exec_ctx, elem, op->op()); } void CallData::SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx, diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc index b21d377d5dd..dcaca10c7f4 100644 --- a/test/cpp/end2end/filter_end2end_test.cc +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -125,11 +125,11 @@ class CallDataImpl : public CallData { : CallData(channel_data) {} void StartTransportStreamOp(grpc_exec_ctx* exec_ctx, grpc_call_element* elem, - grpc_transport_stream_op* op) GRPC_OVERRIDE { + TransportStreamOp* op) GRPC_OVERRIDE { // Incrementing the counter could be done from the ctor, but we want // to test that the individual methods are actually called correctly. - if (op->recv_initial_metadata != nullptr) IncrementCallCounter(); - grpc_call_next_op(exec_ctx, elem, op); + if (op->recv_initial_metadata() != nullptr) IncrementCallCounter(); + grpc_call_next_op(exec_ctx, elem, op->op()); } }; diff --git a/third_party/protobuf b/third_party/protobuf index 3470b6895aa..d4d13a4349e 160000 --- a/third_party/protobuf +++ b/third_party/protobuf @@ -1 +1 @@ -Subproject commit 3470b6895aa659b7559ed678e029a5338e535f14 +Subproject commit d4d13a4349e4e59d67f311185ddcc1890d956d7a From 7f3f7076f3160e0da7990c6478eb9de0e1db8afa Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 29 Jun 2016 07:58:33 -0700 Subject: [PATCH 034/279] Fix C++ API to support returning an error from call data initialization. --- include/grpc++/channel_filter.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/include/grpc++/channel_filter.h b/include/grpc++/channel_filter.h index 0a327b82229..b474722c342 100644 --- a/include/grpc++/channel_filter.h +++ b/include/grpc++/channel_filter.h @@ -231,6 +231,8 @@ class CallData { public: virtual ~CallData() {} + virtual grpc_error* Init() { return GRPC_ERROR_NONE; } + virtual void StartTransportStreamOp(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, TransportStreamOp *op); @@ -242,8 +244,6 @@ class CallData { virtual char *GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem); protected: -// FIXME: once PR #7024 has been merged, update this API to provide a -// way to return an error from call initialization explicit CallData(const ChannelData &) {} }; @@ -281,12 +281,14 @@ class ChannelFilter GRPC_FINAL { static const size_t call_data_size = sizeof(CallDataType); - static void InitCallElement(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { + static grpc_error* InitCallElement(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { const ChannelDataType &channel_data = *(ChannelDataType *)elem->channel_data; // Construct the object in the already-allocated memory. - new (elem->call_data) CallDataType(channel_data); + CallDataType* call_data = new (elem->call_data) CallDataType(channel_data); + return call_data->Init(); } static void DestroyCallElement(grpc_exec_ctx *exec_ctx, From bd3e3189d66b8f091e937380fb044aa3e19ca93e Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 29 Jun 2016 08:01:55 -0700 Subject: [PATCH 035/279] clang-format --- include/grpc++/channel_filter.h | 123 +++++++++++++++---------------- src/cpp/common/channel_filter.cc | 4 +- 2 files changed, 62 insertions(+), 65 deletions(-) diff --git a/include/grpc++/channel_filter.h b/include/grpc++/channel_filter.h index b474722c342..e0703076551 100644 --- a/include/grpc++/channel_filter.h +++ b/include/grpc++/channel_filter.h @@ -34,9 +34,9 @@ #ifndef GRPCXX_CHANNEL_FILTER_H #define GRPCXX_CHANNEL_FILTER_H -#include -#include #include +#include +#include #include #include @@ -60,22 +60,22 @@ namespace grpc { // A C++ wrapper for the grpc_metadata_batch struct. class MetadataBatch { public: - explicit MetadataBatch(grpc_metadata_batch* batch) : batch_(batch) {} + explicit MetadataBatch(grpc_metadata_batch *batch) : batch_(batch) {} - grpc_metadata_batch* batch() const { return batch_; } + grpc_metadata_batch *batch() const { return batch_; } // Adds metadata and returns the newly allocated storage. // The caller takes ownership of the result, which must exist for the // lifetime of the gRPC call. - grpc_linked_mdelem* AddMetadata(const string& key, const string& value); + grpc_linked_mdelem *AddMetadata(const string &key, const string &value); class const_iterator : public std::iterator { public: - const grpc_mdelem& operator*() const { return *elem_->md; } - const grpc_mdelem* operator->() const { return elem_->md; } + const grpc_mdelem &operator*() const { return *elem_->md; } + const grpc_mdelem *operator->() const { return elem_->md; } - const_iterator& operator++() { + const_iterator &operator++() { elem_ = elem_->next; return *this; } @@ -84,7 +84,7 @@ class MetadataBatch { operator++(); return tmp; } - const_iterator& operator--() { + const_iterator &operator--() { elem_ = elem_->prev; return *this; } @@ -94,36 +94,36 @@ class MetadataBatch { return tmp; } - bool operator==(const const_iterator& other) const { + bool operator==(const const_iterator &other) const { return elem_ == other.elem_; } - bool operator!=(const const_iterator& other) const { + bool operator!=(const const_iterator &other) const { return elem_ != other.elem_; } private: friend class MetadataBatch; - explicit const_iterator(grpc_linked_mdelem* elem) : elem_(elem) {} + explicit const_iterator(grpc_linked_mdelem *elem) : elem_(elem) {} - grpc_linked_mdelem* elem_; + grpc_linked_mdelem *elem_; }; const_iterator begin() const { return const_iterator(batch_->list.head); } const_iterator end() const { return const_iterator(nullptr); } private: - grpc_metadata_batch* batch_; + grpc_metadata_batch *batch_; }; // A C++ wrapper for the grpc_transport_op struct. class TransportOp { public: - explicit TransportOp(grpc_transport_op* op) : op_(op) {} + explicit TransportOp(grpc_transport_op *op) : op_(op) {} - grpc_transport_op* op() const { return op_; } + grpc_transport_op *op() const { return op_; } -// FIXME: add a C++ wrapper for grpc_error? - grpc_error* disconnect_with_error() const { + // FIXME: add a C++ wrapper for grpc_error? + grpc_error *disconnect_with_error() const { return op_->disconnect_with_error; } bool send_goaway() const { return op_->send_goaway; } @@ -131,75 +131,73 @@ class TransportOp { // TODO(roth): Add methods for additional fields as needed. private: - grpc_transport_op* op_; // Do not own. + grpc_transport_op *op_; // Do not own. }; // A C++ wrapper for the grpc_transport_stream_op struct. class TransportStreamOp { public: - explicit TransportStreamOp(grpc_transport_stream_op* op) + explicit TransportStreamOp(grpc_transport_stream_op *op) : op_(op), send_initial_metadata_(op->send_initial_metadata), send_trailing_metadata_(op->send_trailing_metadata), recv_initial_metadata_(op->recv_initial_metadata), recv_trailing_metadata_(op->recv_trailing_metadata) {} - grpc_transport_stream_op* op() const { return op_; } + grpc_transport_stream_op *op() const { return op_; } - grpc_closure* on_complete() const { return op_->on_complete; } - void set_on_complete(grpc_closure* closure) { - op_->on_complete = closure; - } + grpc_closure *on_complete() const { return op_->on_complete; } + void set_on_complete(grpc_closure *closure) { op_->on_complete = closure; } - MetadataBatch* send_initial_metadata() { - return op_->send_initial_metadata == nullptr - ? nullptr : &send_initial_metadata_; + MetadataBatch *send_initial_metadata() { + return op_->send_initial_metadata == nullptr ? nullptr + : &send_initial_metadata_; } - MetadataBatch* send_trailing_metadata() { - return op_->send_trailing_metadata == nullptr - ? nullptr : &send_trailing_metadata_; + MetadataBatch *send_trailing_metadata() { + return op_->send_trailing_metadata == nullptr ? nullptr + : &send_trailing_metadata_; } - MetadataBatch* recv_initial_metadata() { - return op_->recv_initial_metadata == nullptr - ? nullptr : &recv_initial_metadata_; + MetadataBatch *recv_initial_metadata() { + return op_->recv_initial_metadata == nullptr ? nullptr + : &recv_initial_metadata_; } - MetadataBatch* recv_trailing_metadata() { - return op_->recv_trailing_metadata == nullptr - ? nullptr : &recv_trailing_metadata_; + MetadataBatch *recv_trailing_metadata() { + return op_->recv_trailing_metadata == nullptr ? nullptr + : &recv_trailing_metadata_; } - uint32_t* send_initial_metadata_flags() const { + uint32_t *send_initial_metadata_flags() const { return &op_->send_initial_metadata_flags; } - grpc_closure* recv_initial_metadata_ready() const { + grpc_closure *recv_initial_metadata_ready() const { return op_->recv_initial_metadata_ready; } - void set_recv_initial_metadata_ready(grpc_closure* closure) { + void set_recv_initial_metadata_ready(grpc_closure *closure) { op_->recv_initial_metadata_ready = closure; } - grpc_byte_stream* send_message() const { return op_->send_message; } - void set_send_message(grpc_byte_stream* send_message) { + grpc_byte_stream *send_message() const { return op_->send_message; } + void set_send_message(grpc_byte_stream *send_message) { op_->send_message = send_message; } // To be called only on clients and servers, respectively. - grpc_client_security_context* client_security_context() const { - return (grpc_client_security_context*)op_->context[ - GRPC_CONTEXT_SECURITY].value; + grpc_client_security_context *client_security_context() const { + return (grpc_client_security_context *)op_->context[GRPC_CONTEXT_SECURITY] + .value; } - grpc_server_security_context* server_security_context() const { - return (grpc_server_security_context*)op_->context[ - GRPC_CONTEXT_SECURITY].value; + grpc_server_security_context *server_security_context() const { + return (grpc_server_security_context *)op_->context[GRPC_CONTEXT_SECURITY] + .value; } - census_context* get_census_context() const { - return (census_context*)op_->context[GRPC_CONTEXT_TRACING].value; + census_context *get_census_context() const { + return (census_context *)op_->context[GRPC_CONTEXT_TRACING].value; } private: - grpc_transport_stream_op* op_; // Do not own. + grpc_transport_stream_op *op_; // Do not own. MetadataBatch send_initial_metadata_; MetadataBatch send_trailing_metadata_; MetadataBatch recv_initial_metadata_; @@ -211,13 +209,12 @@ class ChannelData { public: virtual ~ChannelData() {} - const char* peer() const { return peer_; } + const char *peer() const { return peer_; } -// FIXME: find a way to avoid passing elem into these methods -// (same for CallData below) + // FIXME: find a way to avoid passing elem into these methods + // (same for CallData below) virtual void StartTransportOp(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem, - TransportOp *op); + grpc_channel_element *elem, TransportOp *op); protected: ChannelData(const grpc_channel_args &args, const char *peer) : peer_(peer) {} @@ -231,7 +228,7 @@ class CallData { public: virtual ~CallData() {} - virtual grpc_error* Init() { return GRPC_ERROR_NONE; } + virtual grpc_error *Init() { return GRPC_ERROR_NONE; } virtual void StartTransportStreamOp(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, @@ -258,10 +255,10 @@ class ChannelFilter GRPC_FINAL { static void InitChannelElement(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_channel_element_args *args) { - const char* peer = args->optional_transport - ? grpc_transport_get_peer(exec_ctx, - args->optional_transport) - : nullptr; + const char *peer = + args->optional_transport + ? grpc_transport_get_peer(exec_ctx, args->optional_transport) + : nullptr; // Construct the object in the already-allocated memory. new (elem->channel_data) ChannelDataType(*args->channel_args, peer); } @@ -281,13 +278,13 @@ class ChannelFilter GRPC_FINAL { static const size_t call_data_size = sizeof(CallDataType); - static grpc_error* InitCallElement(grpc_exec_ctx *exec_ctx, + static grpc_error *InitCallElement(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { const ChannelDataType &channel_data = *(ChannelDataType *)elem->channel_data; // Construct the object in the already-allocated memory. - CallDataType* call_data = new (elem->call_data) CallDataType(channel_data); + CallDataType *call_data = new (elem->call_data) CallDataType(channel_data); return call_data->Init(); } diff --git a/src/cpp/common/channel_filter.cc b/src/cpp/common/channel_filter.cc index b2fe3038f52..ab43b8ac3c8 100644 --- a/src/cpp/common/channel_filter.cc +++ b/src/cpp/common/channel_filter.cc @@ -43,8 +43,8 @@ namespace grpc { // MetadataBatch // -grpc_linked_mdelem* MetadataBatch::AddMetadata( - const string& key, const string& value) { +grpc_linked_mdelem *MetadataBatch::AddMetadata(const string &key, + const string &value) { grpc_linked_mdelem *storage = new grpc_linked_mdelem; memset(storage, 0, sizeof(grpc_linked_mdelem)); storage->md = grpc_mdelem_from_strings(key.c_str(), value.c_str()); From acfb34333d09b2182c79ff2df7f5e0a6102c7b80 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 29 Jun 2016 13:02:56 -0700 Subject: [PATCH 036/279] Fix msan/asan/tsan build failure. --- src/core/lib/surface/call.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index f862e8dee99..cdb896909a5 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -271,7 +271,7 @@ grpc_call *grpc_call_create( status = GRPC_STATUS_UNKNOWN; const char *error_str = grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION); - close_with_status(&exec_ctx, call, status, + close_with_status(&exec_ctx, call, (grpc_status_code)status, error_str == NULL ? "unknown error" : error_str); grpc_error_unref(error); } From afa864244d921626480abc6e4408a2aa183396c3 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 29 Jun 2016 14:38:37 -0700 Subject: [PATCH 037/279] When call creation fails, free the allocated call. --- src/core/ext/client_config/subchannel.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/ext/client_config/subchannel.c b/src/core/ext/client_config/subchannel.c index 8a1ac68c6e3..495ca46cc87 100644 --- a/src/core/ext/client_config/subchannel.c +++ b/src/core/ext/client_config/subchannel.c @@ -706,8 +706,7 @@ grpc_error *grpc_connected_subchannel_create_call( grpc_channel_stack *chanstk = CHANNEL_STACK_FROM_CONNECTION(con); *call = gpr_malloc(sizeof(grpc_subchannel_call) + chanstk->call_stack_size); grpc_call_stack *callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call); - (*call)->connection = con; - GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call"); + (*call)->connection = con; // Ref is added below. grpc_error *error = grpc_call_stack_init(exec_ctx, chanstk, 1, subchannel_call_destroy, *call, NULL, NULL, callstk); @@ -715,8 +714,10 @@ grpc_error *grpc_connected_subchannel_create_call( const char *error_string = grpc_error_string(error); gpr_log(GPR_ERROR, "error: %s", error_string); grpc_error_free_string(error_string); + gpr_free(*call); return error; } + GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call"); grpc_call_stack_set_pollset_or_pollset_set(exec_ctx, callstk, pollent); return GRPC_ERROR_NONE; } From ab950ee7c5211cc8e1cfc47f5adf716496899c32 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 29 Jun 2016 14:51:53 -0700 Subject: [PATCH 038/279] Move channel_filter.h from include/ tree to src/ tree. --- BUILD | 4 ++-- Makefile | 3 +-- build.yaml | 2 +- src/cpp/common/channel_filter.cc | 3 +-- {include/grpc++ => src/cpp/common}/channel_filter.h | 7 ++++--- test/cpp/end2end/filter_end2end_test.cc | 2 +- tools/doxygen/Doxyfile.c++ | 1 - tools/doxygen/Doxyfile.c++.internal | 2 +- tools/run_tests/sources_and_headers.json | 4 ++-- vsprojects/vcxproj/grpc++/grpc++.vcxproj | 2 +- vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters | 6 +++--- vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj | 2 +- .../grpc++_unsecure/grpc++_unsecure.vcxproj.filters | 6 +++--- 13 files changed, 21 insertions(+), 23 deletions(-) rename {include/grpc++ => src/cpp/common}/channel_filter.h (98%) diff --git a/BUILD b/BUILD index ce324887e32..86725b6f1cb 100644 --- a/BUILD +++ b/BUILD @@ -1224,6 +1224,7 @@ cc_library( "src/cpp/common/secure_auth_context.h", "src/cpp/server/secure_server_credentials.h", "src/cpp/client/create_channel_internal.h", + "src/cpp/common/channel_filter.h", "src/cpp/server/dynamic_thread_pool.h", "src/cpp/server/thread_pool_interface.h", "src/cpp/client/secure_credentials.cc", @@ -1264,7 +1265,6 @@ cc_library( hdrs = [ "include/grpc++/alarm.h", "include/grpc++/channel.h", - "include/grpc++/channel_filter.h", "include/grpc++/client_context.h", "include/grpc++/completion_queue.h", "include/grpc++/create_channel.h", @@ -1457,6 +1457,7 @@ cc_library( name = "grpc++_unsecure", srcs = [ "src/cpp/client/create_channel_internal.h", + "src/cpp/common/channel_filter.h", "src/cpp/server/dynamic_thread_pool.h", "src/cpp/server/thread_pool_interface.h", "src/cpp/common/insecure_create_auth_context.cc", @@ -1492,7 +1493,6 @@ cc_library( hdrs = [ "include/grpc++/alarm.h", "include/grpc++/channel.h", - "include/grpc++/channel_filter.h", "include/grpc++/client_context.h", "include/grpc++/completion_queue.h", "include/grpc++/create_channel.h", diff --git a/Makefile b/Makefile index 1a4a303ad3e..d2c263cc976 100644 --- a/Makefile +++ b/Makefile @@ -1489,6 +1489,7 @@ buildtests_cxx: buildtests_zookeeper privatelibs_cxx \ $(BINDIR)/$(CONFIG)/cxx_string_ref_test \ $(BINDIR)/$(CONFIG)/cxx_time_test \ $(BINDIR)/$(CONFIG)/end2end_test \ + $(BINDIR)/$(CONFIG)/filter_end2end_test \ $(BINDIR)/$(CONFIG)/generic_end2end_test \ $(BINDIR)/$(CONFIG)/golden_file_test \ $(BINDIR)/$(CONFIG)/grpc_cli \ @@ -3497,7 +3498,6 @@ LIBGRPC++_SRC = \ PUBLIC_HEADERS_CXX += \ include/grpc++/alarm.h \ include/grpc++/channel.h \ - include/grpc++/channel_filter.h \ include/grpc++/client_context.h \ include/grpc++/completion_queue.h \ include/grpc++/create_channel.h \ @@ -3986,7 +3986,6 @@ LIBGRPC++_UNSECURE_SRC = \ PUBLIC_HEADERS_CXX += \ include/grpc++/alarm.h \ include/grpc++/channel.h \ - include/grpc++/channel_filter.h \ include/grpc++/client_context.h \ include/grpc++/completion_queue.h \ include/grpc++/create_channel.h \ diff --git a/build.yaml b/build.yaml index b1a11d503d6..0a78e52775c 100644 --- a/build.yaml +++ b/build.yaml @@ -638,7 +638,6 @@ filegroups: public_headers: - include/grpc++/alarm.h - include/grpc++/channel.h - - include/grpc++/channel_filter.h - include/grpc++/client_context.h - include/grpc++/completion_queue.h - include/grpc++/create_channel.h @@ -686,6 +685,7 @@ filegroups: - include/grpc++/support/time.h headers: - src/cpp/client/create_channel_internal.h + - src/cpp/common/channel_filter.h - src/cpp/server/dynamic_thread_pool.h - src/cpp/server/thread_pool_interface.h src: diff --git a/src/cpp/common/channel_filter.cc b/src/cpp/common/channel_filter.cc index ab43b8ac3c8..8a4149bbcae 100644 --- a/src/cpp/common/channel_filter.cc +++ b/src/cpp/common/channel_filter.cc @@ -31,11 +31,10 @@ * */ -#include - #include #include "src/core/lib/channel/channel_stack.h" +#include "src/cpp/common/channel_filter.h" namespace grpc { diff --git a/include/grpc++/channel_filter.h b/src/cpp/common/channel_filter.h similarity index 98% rename from include/grpc++/channel_filter.h rename to src/cpp/common/channel_filter.h index e0703076551..437c7a27595 100644 --- a/include/grpc++/channel_filter.h +++ b/src/cpp/common/channel_filter.h @@ -122,7 +122,7 @@ class TransportOp { grpc_transport_op *op() const { return op_; } - // FIXME: add a C++ wrapper for grpc_error? + // TODO(roth): Add a C++ wrapper for grpc_error? grpc_error *disconnect_with_error() const { return op_->disconnect_with_error; } @@ -211,8 +211,7 @@ class ChannelData { const char *peer() const { return peer_; } - // FIXME: find a way to avoid passing elem into these methods - // (same for CallData below) + // TODO(roth): Find a way to avoid passing elem into these methods. virtual void StartTransportOp(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, TransportOp *op); @@ -230,6 +229,8 @@ class CallData { virtual grpc_error *Init() { return GRPC_ERROR_NONE; } + // TODO(roth): Find a way to avoid passing elem into these methods. + virtual void StartTransportStreamOp(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, TransportStreamOp *op); diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc index dcaca10c7f4..576d440c9bd 100644 --- a/test/cpp/end2end/filter_end2end_test.cc +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -35,7 +35,6 @@ #include #include -#include #include #include #include @@ -50,6 +49,7 @@ #include #include +#include "src/cpp/common/channel_filter.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index e770574cb1f..7f9d2df6f6c 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -762,7 +762,6 @@ WARN_LOGFILE = INPUT = include/grpc++/alarm.h \ include/grpc++/channel.h \ -include/grpc++/channel_filter.h \ include/grpc++/client_context.h \ include/grpc++/completion_queue.h \ include/grpc++/create_channel.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index a3c4a109264..3c81c48d4a0 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -762,7 +762,6 @@ WARN_LOGFILE = INPUT = include/grpc++/alarm.h \ include/grpc++/channel.h \ -include/grpc++/channel_filter.h \ include/grpc++/client_context.h \ include/grpc++/completion_queue.h \ include/grpc++/create_channel.h \ @@ -864,6 +863,7 @@ src/cpp/client/secure_credentials.h \ src/cpp/common/secure_auth_context.h \ src/cpp/server/secure_server_credentials.h \ src/cpp/client/create_channel_internal.h \ +src/cpp/common/channel_filter.h \ src/cpp/server/dynamic_thread_pool.h \ src/cpp/server/thread_pool_interface.h \ src/cpp/client/secure_credentials.cc \ diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 7d16d15eb45..e55d8a0997d 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -6537,7 +6537,6 @@ "headers": [ "include/grpc++/alarm.h", "include/grpc++/channel.h", - "include/grpc++/channel_filter.h", "include/grpc++/client_context.h", "include/grpc++/completion_queue.h", "include/grpc++/create_channel.h", @@ -6584,6 +6583,7 @@ "include/grpc++/support/sync_stream.h", "include/grpc++/support/time.h", "src/cpp/client/create_channel_internal.h", + "src/cpp/common/channel_filter.h", "src/cpp/server/dynamic_thread_pool.h", "src/cpp/server/thread_pool_interface.h" ], @@ -6592,7 +6592,6 @@ "src": [ "include/grpc++/alarm.h", "include/grpc++/channel.h", - "include/grpc++/channel_filter.h", "include/grpc++/client_context.h", "include/grpc++/completion_queue.h", "include/grpc++/create_channel.h", @@ -6649,6 +6648,7 @@ "src/cpp/client/insecure_credentials.cc", "src/cpp/common/channel_arguments.cc", "src/cpp/common/channel_filter.cc", + "src/cpp/common/channel_filter.h", "src/cpp/common/completion_queue.cc", "src/cpp/common/core_codegen.cc", "src/cpp/common/rpc_method.cc", diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj index b882c302bbb..835e2527c99 100644 --- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj +++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj @@ -260,7 +260,6 @@ - @@ -364,6 +363,7 @@ + diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters index 08fffb74b2f..883e66e1dfd 100644 --- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters @@ -111,9 +111,6 @@ include\grpc++ - - include\grpc++ - include\grpc++ @@ -419,6 +416,9 @@ src\cpp\client + + src\cpp\common + src\cpp\server diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj index b5a27f624d1..e71180feb05 100644 --- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj @@ -260,7 +260,6 @@ - @@ -360,6 +359,7 @@ + diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters index 68d9a47973d..a9aa147e56d 100644 --- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters @@ -96,9 +96,6 @@ include\grpc++ - - include\grpc++ - include\grpc++ @@ -392,6 +389,9 @@ src\cpp\client + + src\cpp\common + src\cpp\server From 97b173dfb8d10bc68dcffa135762d2d152723bc6 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 29 Jun 2016 15:07:35 -0700 Subject: [PATCH 039/279] Addressed reviewer comments. --- src/cpp/common/channel_filter.h | 55 +++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h index 437c7a27595..f3cbdb6224c 100644 --- a/src/cpp/common/channel_filter.h +++ b/src/cpp/common/channel_filter.h @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -46,18 +47,20 @@ #include "src/core/lib/surface/channel_init.h" #include "src/core/lib/transport/metadata_batch.h" -// -// An interface to define filters. -// -// To define a filter, implement a subclass of each of CallData and -// ChannelData. Then register the filter using something like this: -// RegisterChannelFilter( -// "name-of-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr); -// +/// +/// An interface to define filters. +/// +/// To define a filter, implement a subclass of each of \c CallData and +/// \c ChannelData. Then register the filter using something like this: +/// \code{.cpp} +/// RegisterChannelFilter( +/// "name-of-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr); +/// \endcode +/// namespace grpc { -// A C++ wrapper for the grpc_metadata_batch struct. +/// A C++ wrapper for the \c grpc_metadata_batch struct. class MetadataBatch { public: explicit MetadataBatch(grpc_metadata_batch *batch) : batch_(batch) {} @@ -112,10 +115,10 @@ class MetadataBatch { const_iterator end() const { return const_iterator(nullptr); } private: - grpc_metadata_batch *batch_; + grpc_metadata_batch *batch_; // Not owned. }; -// A C++ wrapper for the grpc_transport_op struct. +/// A C++ wrapper for the \c grpc_transport_op struct. class TransportOp { public: explicit TransportOp(grpc_transport_op *op) : op_(op) {} @@ -131,10 +134,10 @@ class TransportOp { // TODO(roth): Add methods for additional fields as needed. private: - grpc_transport_op *op_; // Do not own. + grpc_transport_op *op_; // Not owned. }; -// A C++ wrapper for the grpc_transport_stream_op struct. +/// A C++ wrapper for the \c grpc_transport_stream_op struct. class TransportStreamOp { public: explicit TransportStreamOp(grpc_transport_stream_op *op) @@ -197,18 +200,21 @@ class TransportStreamOp { } private: - grpc_transport_stream_op *op_; // Do not own. + grpc_transport_stream_op *op_; // Not owned. MetadataBatch send_initial_metadata_; MetadataBatch send_trailing_metadata_; MetadataBatch recv_initial_metadata_; MetadataBatch recv_trailing_metadata_; }; -// Represents channel data. +/// Represents channel data. class ChannelData { public: - virtual ~ChannelData() {} + virtual ~ChannelData() { + if (peer_) gpr_free((void *)peer_); + } + // Caller does NOT take ownership of result. const char *peer() const { return peer_; } // TODO(roth): Find a way to avoid passing elem into these methods. @@ -216,13 +222,14 @@ class ChannelData { grpc_channel_element *elem, TransportOp *op); protected: + /// Takes ownership of \a peer. ChannelData(const grpc_channel_args &args, const char *peer) : peer_(peer) {} private: - const char *peer_; // Do not own. + const char *peer_; }; -// Represents call data. +/// Represents call data. class CallData { public: virtual ~CallData() {} @@ -330,11 +337,11 @@ void ChannelFilterPluginShutdown(); } // namespace internal -// Registers a new filter. -// Must be called by only one thread at a time. -// The include_filter argument specifies a function that will be called -// to determine at run-time whether or not to add the filter. If the -// value is nullptr, the filter will be added unconditionally. +/// Registers a new filter. +/// Must be called by only one thread at a time. +/// The \a include_filter argument specifies a function that will be called +/// to determine at run-time whether or not to add the filter. If the +/// value is nullptr, the filter will be added unconditionally. template void RegisterChannelFilter( const char *name, grpc_channel_stack_type stack_type, int priority, @@ -346,7 +353,7 @@ void RegisterChannelFilter( internal::ChannelFilterPluginShutdown); internal::channel_filters = new std::vector(); } - // Add an entry to channel_filters. The filter will be added when the + // Add an entry to channel_filters. The filter will be added when the // C-core initialization code calls ChannelFilterPluginInit(). typedef internal::ChannelFilter FilterType; internal::FilterRecord filter_record = { From c4326ef25a5280b4254ab1c97c9f28d68f6ce852 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 1 Jul 2016 15:20:51 -0700 Subject: [PATCH 040/279] Make Node code generator work properly with nested types --- src/compiler/node_generator.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/compiler/node_generator.cc b/src/compiler/node_generator.cc index 1fe090d17af..2ac5e772acb 100644 --- a/src/compiler/node_generator.cc +++ b/src/compiler/node_generator.cc @@ -111,8 +111,8 @@ map GetAllMessages(const FileDescriptor *file) const MethodDescriptor* method = service->method(method_num); const Descriptor* input_type = method->input_type(); const Descriptor* output_type = method->output_type(); - message_types[input_type->name()] = input_type; - message_types[output_type->name()] = output_type; + message_types[input_type->full_name()] = input_type; + message_types[output_type->full_name()] = output_type; } } return message_types; @@ -124,7 +124,7 @@ grpc::string MessageIdentifierName(const grpc::string& name) { grpc::string NodeObjectPath(const Descriptor *descriptor) { grpc::string module_alias = ModuleAlias(descriptor->file()->name()); - grpc::string name = descriptor->name(); + grpc::string name = descriptor->full_name(); grpc_generator::StripPrefix(&name, descriptor->file()->package() + "."); return module_alias + "." + name; } @@ -132,8 +132,9 @@ grpc::string NodeObjectPath(const Descriptor *descriptor) { // Prints out the message serializer and deserializer functions void PrintMessageTransformer(const Descriptor *descriptor, Printer *out) { map template_vars; - template_vars["identifier_name"] = MessageIdentifierName(descriptor->name()); - template_vars["name"] = descriptor->name(); + grpc::string full_name = descriptor->full_name(); + template_vars["identifier_name"] = MessageIdentifierName(full_name); + template_vars["name"] = full_name; template_vars["node_name"] = NodeObjectPath(descriptor); // Print the serializer out->Print(template_vars, "function serialize_$identifier_name$(arg) {\n"); @@ -166,9 +167,9 @@ void PrintMethod(const MethodDescriptor *method, Printer *out) { vars["service_name"] = method->service()->full_name(); vars["name"] = method->name(); vars["input_type"] = NodeObjectPath(input_type); - vars["input_type_id"] = MessageIdentifierName(input_type->name()); + vars["input_type_id"] = MessageIdentifierName(input_type->full_name()); vars["output_type"] = NodeObjectPath(output_type); - vars["output_type_id"] = MessageIdentifierName(output_type->name()); + vars["output_type_id"] = MessageIdentifierName(output_type->full_name()); vars["client_stream"] = method->client_streaming() ? "true" : "false"; vars["server_stream"] = method->server_streaming() ? "true" : "false"; out->Print("{\n"); From d716e24c5c97b2afb51ee4066a149c7316154584 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Thu, 7 Jul 2016 01:40:33 +0200 Subject: [PATCH 041/279] Stop using image aliases, as this is getting deprecated. --- tools/gce/create_linux_worker.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/gce/create_linux_worker.sh b/tools/gce/create_linux_worker.sh index c41e4d299bf..8a2df40859b 100755 --- a/tools/gce/create_linux_worker.sh +++ b/tools/gce/create_linux_worker.sh @@ -43,7 +43,8 @@ gcloud compute instances create $INSTANCE_NAME \ --project="$CLOUD_PROJECT" \ --zone "$ZONE" \ --machine-type n1-standard-8 \ - --image ubuntu-15-10 \ + --image-family=ubuntu-1510 \ + --image-project=ubuntu-os-cloud \ --boot-disk-size 1000 echo 'Created GCE instance, waiting 60 seconds for it to come online.' From 6c54078d2ee377a1c12ded8e031353ee5125ac2f Mon Sep 17 00:00:00 2001 From: Dan Born Date: Tue, 28 Jun 2016 16:34:41 -0700 Subject: [PATCH 042/279] Set siblings for server clones properly. --- src/core/lib/iomgr/tcp_server_posix.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c index a1a463550ae..5d2ebe2e7cf 100644 --- a/src/core/lib/iomgr/tcp_server_posix.c +++ b/src/core/lib/iomgr/tcp_server_posix.c @@ -512,8 +512,9 @@ static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) { sp->port = port; sp->port_index = listener->port_index; sp->fd_index = listener->fd_index + count - i; + listener->sibling = sp; sp->is_sibling = 1; - sp->sibling = listener->is_sibling ? listener->sibling : listener; + sp->sibling = listener->sibling; GPR_ASSERT(sp->emfd); while (listener->server->tail->next != NULL) { listener->server->tail = listener->server->tail->next; From ad1f31ff8198b1956284f55f14c6229a12d4d513 Mon Sep 17 00:00:00 2001 From: Dan Born Date: Fri, 8 Jul 2016 13:24:49 -0700 Subject: [PATCH 043/279] Code comments for siblings. --- src/core/lib/iomgr/tcp_server_posix.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c index 5d2ebe2e7cf..684bb73e21e 100644 --- a/src/core/lib/iomgr/tcp_server_posix.c +++ b/src/core/lib/iomgr/tcp_server_posix.c @@ -90,10 +90,12 @@ struct grpc_tcp_listener { grpc_closure read_closure; grpc_closure destroyed_closure; struct grpc_tcp_listener *next; - /* When we add a listener, more than one can be created, mainly because of - IPv6. A sibling will still be in the normal list, but will be flagged - as such. Any action, such as ref or unref, will affect all of the - siblings in the list. */ + /* sibling is a linked list of all listeners for a given port. add_port and + clone_port place all new listeners in the same sibling list. A member of + the 'sibling' list is also a member of the 'next' list. The head of each + sibling list has is_sibling==0, and subsequent members of sibling lists + have is_sibling==1. is_sibling allows separate sibling lists to be + identified while iterating through 'next'. */ struct grpc_tcp_listener *sibling; int is_sibling; }; @@ -479,6 +481,9 @@ static grpc_error *add_socket_to_server(grpc_tcp_server *s, int fd, return err; } +/* Insert count new listeners after listener. Every new listener will have the + same listen address as listener (SO_REUSEPORT must be enabled). Every new + listener is a sibling of listener. */ static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) { grpc_tcp_listener *sp = NULL; char *addr_str; @@ -504,6 +509,11 @@ static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) { sp = gpr_malloc(sizeof(grpc_tcp_listener)); sp->next = listener->next; listener->next = sp; + /* sp (the new listener) is a sibling of 'listener' (the original + listener). */ + sp->is_sibling = 1; + sp->sibling = listener->sibling; + listener->sibling = sp; sp->server = listener->server; sp->fd = fd; sp->emfd = grpc_fd_create(fd, name); @@ -512,9 +522,6 @@ static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) { sp->port = port; sp->port_index = listener->port_index; sp->fd_index = listener->fd_index + count - i; - listener->sibling = sp; - sp->is_sibling = 1; - sp->sibling = listener->sibling; GPR_ASSERT(sp->emfd); while (listener->server->tail->next != NULL) { listener->server->tail = listener->server->tail->next; From 33e5cbbbb85e3bfe62c63897ea919baafddedfe6 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 11 Jul 2016 08:00:28 -0700 Subject: [PATCH 044/279] Add include to fix gcc-4.4 problem. --- test/cpp/end2end/filter_end2end_test.cc | 1 + third_party/protobuf | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc index 576d440c9bd..66598db7c91 100644 --- a/test/cpp/end2end/filter_end2end_test.cc +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include diff --git a/third_party/protobuf b/third_party/protobuf index d4d13a4349e..bdeb215cab2 160000 --- a/third_party/protobuf +++ b/third_party/protobuf @@ -1 +1 @@ -Subproject commit d4d13a4349e4e59d67f311185ddcc1890d956d7a +Subproject commit bdeb215cab2985195325fcd5e70c3fa751f46e0f From 4f0b06e747832fa54415b72b23685ba97437e936 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 11 Jul 2016 09:29:56 -0700 Subject: [PATCH 045/279] Move use of nullptr into grpc namespace, so that the hack in config.h can be used. --- test/cpp/end2end/filter_end2end_test.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc index 66598db7c91..853720fd0d0 100644 --- a/test/cpp/end2end/filter_end2end_test.cc +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -336,6 +336,11 @@ TEST_F(FilterEnd2endTest, SimpleBidiStreaming) { EXPECT_EQ(1, GetConnectionCounterValue()); } +void RegisterFilter() { + grpc::RegisterChannelFilter( + "test-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr); +} + } // namespace } // namespace testing } // namespace grpc @@ -343,8 +348,6 @@ TEST_F(FilterEnd2endTest, SimpleBidiStreaming) { int main(int argc, char** argv) { grpc_test_init(argc, argv); ::testing::InitGoogleTest(&argc, argv); - grpc::RegisterChannelFilter( - "test-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr); + grpc::testing::RegisterFilter(); return RUN_ALL_TESTS(); } From c919aff578cf59d4a1d610e1f7ed26db3aa601c3 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 11 Jul 2016 10:00:03 -0700 Subject: [PATCH 046/279] Prep for making GA video --- tools/gource/gen-all-logs.sh | 3 +-- tools/gource/gource.sh | 2 +- tools/gource/make-video.sh | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/tools/gource/gen-all-logs.sh b/tools/gource/gen-all-logs.sh index 85352c514e9..ab60c3c1b12 100755 --- a/tools/gource/gen-all-logs.sh +++ b/tools/gource/gen-all-logs.sh @@ -41,7 +41,6 @@ do git clone https://github.com/grpc/$repo.git cd $repo gource --output-custom-log $tmpdir/logs/$repo - sed -i .backup "s,\|/,\|/$repo/,g" $tmpdir/logs/$repo + sed -i "s,|/,|/$repo/,g" $tmpdir/logs/$repo done -rm $tmpdir/logs/*.backup cat $tmpdir/logs/* | sort -n > $outdir/all-logs.txt diff --git a/tools/gource/gource.sh b/tools/gource/gource.sh index b3dad5d7c7a..5529b32bbd8 100755 --- a/tools/gource/gource.sh +++ b/tools/gource/gource.sh @@ -34,7 +34,7 @@ gource \ --max-file-lag 0.05 \ --max-files 0 \ -e 0.01 \ - --hide filenames,dirnames \ + --hide filenames,dirnames,mouse,progress \ --disable-auto-rotate \ --file-filter '/grpc/doc/ref' \ $* diff --git a/tools/gource/make-video.sh b/tools/gource/make-video.sh index 02d79df81bf..cde0437255e 100755 --- a/tools/gource/make-video.sh +++ b/tools/gource/make-video.sh @@ -37,7 +37,7 @@ $(dirname $0)/gource.sh \ --stop-at-end \ --output-ppm-stream - \ $@ | \ -ffmpeg \ +avconv \ -y \ -r 60 \ -f image2pipe \ From 710d242e8973ed3e8ba0c63f554facae7034319f Mon Sep 17 00:00:00 2001 From: Robbie Shade Date: Wed, 13 Jul 2016 15:15:38 -0400 Subject: [PATCH 047/279] Move timeout_encoding from core/ext/transport/chttp2 to core/lib/transport --- BUILD | 16 ++++++------ CMakeLists.txt | 6 ++--- Makefile | 10 +++---- binding.gyp | 2 +- build.yaml | 6 ++--- config.m4 | 2 +- gRPC-Core.podspec | 6 ++--- gRPC.podspec | 6 ++--- grpc.gemspec | 4 +-- package.xml | 4 +-- .../chttp2/transport/chttp2_transport.c | 2 +- .../chttp2/transport/hpack_encoder.c | 6 ++--- .../ext/transport/chttp2/transport/parsing.c | 6 ++--- .../transport/timeout_encoding.c | 6 ++--- .../transport/timeout_encoding.h | 14 +++++----- src/python/grpcio/grpc_core_dependencies.py | 2 +- .../{chttp2 => }/timeout_encoding_test.c | 26 +++++++++---------- tools/doxygen/Doxyfile.core.internal | 4 +-- tools/run_tests/sources_and_headers.json | 8 +++--- vsprojects/vcxproj/grpc/grpc.vcxproj | 6 ++--- vsprojects/vcxproj/grpc/grpc.vcxproj.filters | 12 ++++----- .../grpc_unsecure/grpc_unsecure.vcxproj | 6 ++--- .../grpc_unsecure.vcxproj.filters | 12 ++++----- .../timeout_encoding_test.vcxproj | 2 +- .../timeout_encoding_test.vcxproj.filters | 7 ++--- 25 files changed, 89 insertions(+), 92 deletions(-) rename src/core/{ext/transport/chttp2 => lib}/transport/timeout_encoding.c (96%) rename src/core/{ext/transport/chttp2 => lib}/transport/timeout_encoding.h (77%) rename test/core/transport/{chttp2 => }/timeout_encoding_test.c (89%) diff --git a/BUILD b/BUILD index 33323be229d..15af05f2449 100644 --- a/BUILD +++ b/BUILD @@ -235,6 +235,7 @@ cc_library( "src/core/lib/transport/metadata.h", "src/core/lib/transport/metadata_batch.h", "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/timeout_encoding.h", "src/core/lib/transport/transport.h", "src/core/lib/transport/transport_impl.h", "src/core/ext/transport/chttp2/transport/bin_decoder.h", @@ -256,7 +257,6 @@ cc_library( "src/core/ext/transport/chttp2/transport/internal.h", "src/core/ext/transport/chttp2/transport/status_conversion.h", "src/core/ext/transport/chttp2/transport/stream_map.h", - "src/core/ext/transport/chttp2/transport/timeout_encoding.h", "src/core/ext/transport/chttp2/transport/varint.h", "src/core/ext/transport/chttp2/alpn/alpn.h", "src/core/lib/security/context/security_context.h", @@ -396,6 +396,7 @@ cc_library( "src/core/lib/transport/metadata.c", "src/core/lib/transport/metadata_batch.c", "src/core/lib/transport/static_metadata.c", + "src/core/lib/transport/timeout_encoding.c", "src/core/lib/transport/transport.c", "src/core/lib/transport/transport_op_string.c", "src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c", @@ -418,7 +419,6 @@ cc_library( "src/core/ext/transport/chttp2/transport/status_conversion.c", "src/core/ext/transport/chttp2/transport/stream_lists.c", "src/core/ext/transport/chttp2/transport/stream_map.c", - "src/core/ext/transport/chttp2/transport/timeout_encoding.c", "src/core/ext/transport/chttp2/transport/varint.c", "src/core/ext/transport/chttp2/transport/writing.c", "src/core/ext/transport/chttp2/alpn/alpn.c", @@ -622,6 +622,7 @@ cc_library( "src/core/lib/transport/metadata.h", "src/core/lib/transport/metadata_batch.h", "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/timeout_encoding.h", "src/core/lib/transport/transport.h", "src/core/lib/transport/transport_impl.h", "third_party/objective_c/Cronet/cronet_c_for_grpc.h", @@ -644,7 +645,6 @@ cc_library( "src/core/ext/transport/chttp2/transport/internal.h", "src/core/ext/transport/chttp2/transport/status_conversion.h", "src/core/ext/transport/chttp2/transport/stream_map.h", - "src/core/ext/transport/chttp2/transport/timeout_encoding.h", "src/core/ext/transport/chttp2/transport/varint.h", "src/core/ext/transport/chttp2/alpn/alpn.h", "src/core/ext/client_config/client_channel.h", @@ -773,6 +773,7 @@ cc_library( "src/core/lib/transport/metadata.c", "src/core/lib/transport/metadata_batch.c", "src/core/lib/transport/static_metadata.c", + "src/core/lib/transport/timeout_encoding.c", "src/core/lib/transport/transport.c", "src/core/lib/transport/transport_op_string.c", "src/core/ext/transport/cronet/client/secure/cronet_channel_create.c", @@ -798,7 +799,6 @@ cc_library( "src/core/ext/transport/chttp2/transport/status_conversion.c", "src/core/ext/transport/chttp2/transport/stream_lists.c", "src/core/ext/transport/chttp2/transport/stream_map.c", - "src/core/ext/transport/chttp2/transport/timeout_encoding.c", "src/core/ext/transport/chttp2/transport/varint.c", "src/core/ext/transport/chttp2/transport/writing.c", "src/core/ext/transport/chttp2/alpn/alpn.c", @@ -974,6 +974,7 @@ cc_library( "src/core/lib/transport/metadata.h", "src/core/lib/transport/metadata_batch.h", "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/timeout_encoding.h", "src/core/lib/transport/transport.h", "src/core/lib/transport/transport_impl.h", "src/core/ext/transport/chttp2/transport/bin_decoder.h", @@ -995,7 +996,6 @@ cc_library( "src/core/ext/transport/chttp2/transport/internal.h", "src/core/ext/transport/chttp2/transport/status_conversion.h", "src/core/ext/transport/chttp2/transport/stream_map.h", - "src/core/ext/transport/chttp2/transport/timeout_encoding.h", "src/core/ext/transport/chttp2/transport/varint.h", "src/core/ext/transport/chttp2/alpn/alpn.h", "src/core/ext/client_config/client_channel.h", @@ -1112,6 +1112,7 @@ cc_library( "src/core/lib/transport/metadata.c", "src/core/lib/transport/metadata_batch.c", "src/core/lib/transport/static_metadata.c", + "src/core/lib/transport/timeout_encoding.c", "src/core/lib/transport/transport.c", "src/core/lib/transport/transport_op_string.c", "src/core/ext/transport/chttp2/server/insecure/server_chttp2.c", @@ -1135,7 +1136,6 @@ cc_library( "src/core/ext/transport/chttp2/transport/status_conversion.c", "src/core/ext/transport/chttp2/transport/stream_lists.c", "src/core/ext/transport/chttp2/transport/stream_map.c", - "src/core/ext/transport/chttp2/transport/timeout_encoding.c", "src/core/ext/transport/chttp2/transport/varint.c", "src/core/ext/transport/chttp2/transport/writing.c", "src/core/ext/transport/chttp2/alpn/alpn.c", @@ -1871,6 +1871,7 @@ objc_library( "src/core/lib/transport/metadata.c", "src/core/lib/transport/metadata_batch.c", "src/core/lib/transport/static_metadata.c", + "src/core/lib/transport/timeout_encoding.c", "src/core/lib/transport/transport.c", "src/core/lib/transport/transport_op_string.c", "src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c", @@ -1893,7 +1894,6 @@ objc_library( "src/core/ext/transport/chttp2/transport/status_conversion.c", "src/core/ext/transport/chttp2/transport/stream_lists.c", "src/core/ext/transport/chttp2/transport/stream_map.c", - "src/core/ext/transport/chttp2/transport/timeout_encoding.c", "src/core/ext/transport/chttp2/transport/varint.c", "src/core/ext/transport/chttp2/transport/writing.c", "src/core/ext/transport/chttp2/alpn/alpn.c", @@ -2076,6 +2076,7 @@ objc_library( "src/core/lib/transport/metadata.h", "src/core/lib/transport/metadata_batch.h", "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/timeout_encoding.h", "src/core/lib/transport/transport.h", "src/core/lib/transport/transport_impl.h", "src/core/ext/transport/chttp2/transport/bin_decoder.h", @@ -2097,7 +2098,6 @@ objc_library( "src/core/ext/transport/chttp2/transport/internal.h", "src/core/ext/transport/chttp2/transport/status_conversion.h", "src/core/ext/transport/chttp2/transport/stream_map.h", - "src/core/ext/transport/chttp2/transport/timeout_encoding.h", "src/core/ext/transport/chttp2/transport/varint.h", "src/core/ext/transport/chttp2/alpn/alpn.h", "src/core/lib/security/context/security_context.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c0059cd2db..8a3d829741f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -219,6 +219,7 @@ add_library(grpc src/core/lib/transport/metadata.c src/core/lib/transport/metadata_batch.c src/core/lib/transport/static_metadata.c + src/core/lib/transport/timeout_encoding.c src/core/lib/transport/transport.c src/core/lib/transport/transport_op_string.c src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c @@ -241,7 +242,6 @@ add_library(grpc src/core/ext/transport/chttp2/transport/status_conversion.c src/core/ext/transport/chttp2/transport/stream_lists.c src/core/ext/transport/chttp2/transport/stream_map.c - src/core/ext/transport/chttp2/transport/timeout_encoding.c src/core/ext/transport/chttp2/transport/varint.c src/core/ext/transport/chttp2/transport/writing.c src/core/ext/transport/chttp2/alpn/alpn.c @@ -424,6 +424,7 @@ add_library(grpc_cronet src/core/lib/transport/metadata.c src/core/lib/transport/metadata_batch.c src/core/lib/transport/static_metadata.c + src/core/lib/transport/timeout_encoding.c src/core/lib/transport/transport.c src/core/lib/transport/transport_op_string.c src/core/ext/transport/cronet/client/secure/cronet_channel_create.c @@ -449,7 +450,6 @@ add_library(grpc_cronet src/core/ext/transport/chttp2/transport/status_conversion.c src/core/ext/transport/chttp2/transport/stream_lists.c src/core/ext/transport/chttp2/transport/stream_map.c - src/core/ext/transport/chttp2/transport/timeout_encoding.c src/core/ext/transport/chttp2/transport/varint.c src/core/ext/transport/chttp2/transport/writing.c src/core/ext/transport/chttp2/alpn/alpn.c @@ -606,6 +606,7 @@ add_library(grpc_unsecure src/core/lib/transport/metadata.c src/core/lib/transport/metadata_batch.c src/core/lib/transport/static_metadata.c + src/core/lib/transport/timeout_encoding.c src/core/lib/transport/transport.c src/core/lib/transport/transport_op_string.c src/core/ext/transport/chttp2/server/insecure/server_chttp2.c @@ -629,7 +630,6 @@ add_library(grpc_unsecure src/core/ext/transport/chttp2/transport/status_conversion.c src/core/ext/transport/chttp2/transport/stream_lists.c src/core/ext/transport/chttp2/transport/stream_map.c - src/core/ext/transport/chttp2/transport/timeout_encoding.c src/core/ext/transport/chttp2/transport/varint.c src/core/ext/transport/chttp2/transport/writing.c src/core/ext/transport/chttp2/alpn/alpn.c diff --git a/Makefile b/Makefile index e958b145e77..ea00baca8aa 100644 --- a/Makefile +++ b/Makefile @@ -2559,6 +2559,7 @@ LIBGRPC_SRC = \ src/core/lib/transport/metadata.c \ src/core/lib/transport/metadata_batch.c \ src/core/lib/transport/static_metadata.c \ + src/core/lib/transport/timeout_encoding.c \ src/core/lib/transport/transport.c \ src/core/lib/transport/transport_op_string.c \ src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c \ @@ -2581,7 +2582,6 @@ LIBGRPC_SRC = \ src/core/ext/transport/chttp2/transport/status_conversion.c \ src/core/ext/transport/chttp2/transport/stream_lists.c \ src/core/ext/transport/chttp2/transport/stream_map.c \ - src/core/ext/transport/chttp2/transport/timeout_encoding.c \ src/core/ext/transport/chttp2/transport/varint.c \ src/core/ext/transport/chttp2/transport/writing.c \ src/core/ext/transport/chttp2/alpn/alpn.c \ @@ -2831,6 +2831,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/transport/metadata.c \ src/core/lib/transport/metadata_batch.c \ src/core/lib/transport/static_metadata.c \ + src/core/lib/transport/timeout_encoding.c \ src/core/lib/transport/transport.c \ src/core/lib/transport/transport_op_string.c \ src/core/ext/transport/cronet/client/secure/cronet_channel_create.c \ @@ -2856,7 +2857,6 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/transport/chttp2/transport/status_conversion.c \ src/core/ext/transport/chttp2/transport/stream_lists.c \ src/core/ext/transport/chttp2/transport/stream_map.c \ - src/core/ext/transport/chttp2/transport/timeout_encoding.c \ src/core/ext/transport/chttp2/transport/varint.c \ src/core/ext/transport/chttp2/transport/writing.c \ src/core/ext/transport/chttp2/alpn/alpn.c \ @@ -3172,6 +3172,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/transport/metadata.c \ src/core/lib/transport/metadata_batch.c \ src/core/lib/transport/static_metadata.c \ + src/core/lib/transport/timeout_encoding.c \ src/core/lib/transport/transport.c \ src/core/lib/transport/transport_op_string.c \ src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \ @@ -3195,7 +3196,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/transport/chttp2/transport/status_conversion.c \ src/core/ext/transport/chttp2/transport/stream_lists.c \ src/core/ext/transport/chttp2/transport/stream_map.c \ - src/core/ext/transport/chttp2/transport/timeout_encoding.c \ src/core/ext/transport/chttp2/transport/varint.c \ src/core/ext/transport/chttp2/transport/writing.c \ src/core/ext/transport/chttp2/alpn/alpn.c \ @@ -9888,7 +9888,7 @@ endif TIMEOUT_ENCODING_TEST_SRC = \ - test/core/transport/chttp2/timeout_encoding_test.c \ + test/core/transport/timeout_encoding_test.c \ TIMEOUT_ENCODING_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TIMEOUT_ENCODING_TEST_SRC)))) ifeq ($(NO_SECURE),true) @@ -9908,7 +9908,7 @@ $(BINDIR)/$(CONFIG)/timeout_encoding_test: $(TIMEOUT_ENCODING_TEST_OBJS) $(LIBDI endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/timeout_encoding_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/timeout_encoding_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_timeout_encoding_test: $(TIMEOUT_ENCODING_TEST_OBJS:.o=.dep) diff --git a/binding.gyp b/binding.gyp index e1130ad01ab..2b1c48a5097 100644 --- a/binding.gyp +++ b/binding.gyp @@ -648,6 +648,7 @@ 'src/core/lib/transport/metadata.c', 'src/core/lib/transport/metadata_batch.c', 'src/core/lib/transport/static_metadata.c', + 'src/core/lib/transport/timeout_encoding.c', 'src/core/lib/transport/transport.c', 'src/core/lib/transport/transport_op_string.c', 'src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c', @@ -670,7 +671,6 @@ 'src/core/ext/transport/chttp2/transport/status_conversion.c', 'src/core/ext/transport/chttp2/transport/stream_lists.c', 'src/core/ext/transport/chttp2/transport/stream_map.c', - 'src/core/ext/transport/chttp2/transport/timeout_encoding.c', 'src/core/ext/transport/chttp2/transport/varint.c', 'src/core/ext/transport/chttp2/transport/writing.c', 'src/core/ext/transport/chttp2/alpn/alpn.c', diff --git a/build.yaml b/build.yaml index 071d4a8e1ea..ebd2cdc0225 100644 --- a/build.yaml +++ b/build.yaml @@ -226,6 +226,7 @@ filegroups: - src/core/lib/transport/metadata.h - src/core/lib/transport/metadata_batch.h - src/core/lib/transport/static_metadata.h + - src/core/lib/transport/timeout_encoding.h - src/core/lib/transport/transport.h - src/core/lib/transport/transport_impl.h src: @@ -314,6 +315,7 @@ filegroups: - src/core/lib/transport/metadata.c - src/core/lib/transport/metadata_batch.c - src/core/lib/transport/static_metadata.c + - src/core/lib/transport/timeout_encoding.c - src/core/lib/transport/transport.c - src/core/lib/transport/transport_op_string.c deps: @@ -527,7 +529,6 @@ filegroups: - src/core/ext/transport/chttp2/transport/internal.h - src/core/ext/transport/chttp2/transport/status_conversion.h - src/core/ext/transport/chttp2/transport/stream_map.h - - src/core/ext/transport/chttp2/transport/timeout_encoding.h - src/core/ext/transport/chttp2/transport/varint.h src: - src/core/ext/transport/chttp2/transport/bin_decoder.c @@ -549,7 +550,6 @@ filegroups: - src/core/ext/transport/chttp2/transport/status_conversion.c - src/core/ext/transport/chttp2/transport/stream_lists.c - src/core/ext/transport/chttp2/transport/stream_map.c - - src/core/ext/transport/chttp2/transport/timeout_encoding.c - src/core/ext/transport/chttp2/transport/varint.c - src/core/ext/transport/chttp2/transport/writing.c plugin: grpc_chttp2_plugin @@ -2333,7 +2333,7 @@ targets: build: test language: c src: - - test/core/transport/chttp2/timeout_encoding_test.c + - test/core/transport/timeout_encoding_test.c deps: - grpc_test_util - grpc diff --git a/config.m4 b/config.m4 index 0c3322d8efe..992360cabf0 100644 --- a/config.m4 +++ b/config.m4 @@ -167,6 +167,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/transport/metadata.c \ src/core/lib/transport/metadata_batch.c \ src/core/lib/transport/static_metadata.c \ + src/core/lib/transport/timeout_encoding.c \ src/core/lib/transport/transport.c \ src/core/lib/transport/transport_op_string.c \ src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c \ @@ -189,7 +190,6 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/transport/chttp2/transport/status_conversion.c \ src/core/ext/transport/chttp2/transport/stream_lists.c \ src/core/ext/transport/chttp2/transport/stream_map.c \ - src/core/ext/transport/chttp2/transport/timeout_encoding.c \ src/core/ext/transport/chttp2/transport/varint.c \ src/core/ext/transport/chttp2/transport/writing.c \ src/core/ext/transport/chttp2/alpn/alpn.c \ diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index e10e05387b1..564d95878ff 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -326,6 +326,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/metadata.h', 'src/core/lib/transport/metadata_batch.h', 'src/core/lib/transport/static_metadata.h', + 'src/core/lib/transport/timeout_encoding.h', 'src/core/lib/transport/transport.h', 'src/core/lib/transport/transport_impl.h', 'src/core/ext/transport/chttp2/transport/bin_decoder.h', @@ -347,7 +348,6 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/internal.h', 'src/core/ext/transport/chttp2/transport/status_conversion.h', 'src/core/ext/transport/chttp2/transport/stream_map.h', - 'src/core/ext/transport/chttp2/transport/timeout_encoding.h', 'src/core/ext/transport/chttp2/transport/varint.h', 'src/core/ext/transport/chttp2/alpn/alpn.h', 'src/core/lib/security/context/security_context.h', @@ -491,6 +491,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/metadata.c', 'src/core/lib/transport/metadata_batch.c', 'src/core/lib/transport/static_metadata.c', + 'src/core/lib/transport/timeout_encoding.c', 'src/core/lib/transport/transport.c', 'src/core/lib/transport/transport_op_string.c', 'src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c', @@ -513,7 +514,6 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/status_conversion.c', 'src/core/ext/transport/chttp2/transport/stream_lists.c', 'src/core/ext/transport/chttp2/transport/stream_map.c', - 'src/core/ext/transport/chttp2/transport/timeout_encoding.c', 'src/core/ext/transport/chttp2/transport/varint.c', 'src/core/ext/transport/chttp2/transport/writing.c', 'src/core/ext/transport/chttp2/alpn/alpn.c', @@ -679,6 +679,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/metadata.h', 'src/core/lib/transport/metadata_batch.h', 'src/core/lib/transport/static_metadata.h', + 'src/core/lib/transport/timeout_encoding.h', 'src/core/lib/transport/transport.h', 'src/core/lib/transport/transport_impl.h', 'src/core/ext/transport/chttp2/transport/bin_decoder.h', @@ -700,7 +701,6 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/internal.h', 'src/core/ext/transport/chttp2/transport/status_conversion.h', 'src/core/ext/transport/chttp2/transport/stream_map.h', - 'src/core/ext/transport/chttp2/transport/timeout_encoding.h', 'src/core/ext/transport/chttp2/transport/varint.h', 'src/core/ext/transport/chttp2/alpn/alpn.h', 'src/core/lib/security/context/security_context.h', diff --git a/gRPC.podspec b/gRPC.podspec index fd58bd6281f..3bb6aced7e7 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -238,6 +238,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/metadata.h', 'src/core/lib/transport/metadata_batch.h', 'src/core/lib/transport/static_metadata.h', + 'src/core/lib/transport/timeout_encoding.h', 'src/core/lib/transport/transport.h', 'src/core/lib/transport/transport_impl.h', 'src/core/ext/transport/chttp2/transport/bin_decoder.h', @@ -259,7 +260,6 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/internal.h', 'src/core/ext/transport/chttp2/transport/status_conversion.h', 'src/core/ext/transport/chttp2/transport/stream_map.h', - 'src/core/ext/transport/chttp2/transport/timeout_encoding.h', 'src/core/ext/transport/chttp2/transport/varint.h', 'src/core/ext/transport/chttp2/alpn/alpn.h', 'src/core/lib/security/context/security_context.h', @@ -433,6 +433,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/metadata.c', 'src/core/lib/transport/metadata_batch.c', 'src/core/lib/transport/static_metadata.c', + 'src/core/lib/transport/timeout_encoding.c', 'src/core/lib/transport/transport.c', 'src/core/lib/transport/transport_op_string.c', 'src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c', @@ -455,7 +456,6 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/status_conversion.c', 'src/core/ext/transport/chttp2/transport/stream_lists.c', 'src/core/ext/transport/chttp2/transport/stream_map.c', - 'src/core/ext/transport/chttp2/transport/timeout_encoding.c', 'src/core/ext/transport/chttp2/transport/varint.c', 'src/core/ext/transport/chttp2/transport/writing.c', 'src/core/ext/transport/chttp2/alpn/alpn.c', @@ -621,6 +621,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/metadata.h', 'src/core/lib/transport/metadata_batch.h', 'src/core/lib/transport/static_metadata.h', + 'src/core/lib/transport/timeout_encoding.h', 'src/core/lib/transport/transport.h', 'src/core/lib/transport/transport_impl.h', 'src/core/ext/transport/chttp2/transport/bin_decoder.h', @@ -642,7 +643,6 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/internal.h', 'src/core/ext/transport/chttp2/transport/status_conversion.h', 'src/core/ext/transport/chttp2/transport/stream_map.h', - 'src/core/ext/transport/chttp2/transport/timeout_encoding.h', 'src/core/ext/transport/chttp2/transport/varint.h', 'src/core/ext/transport/chttp2/alpn/alpn.h', 'src/core/lib/security/context/security_context.h', diff --git a/grpc.gemspec b/grpc.gemspec index 369851b0f24..1175439a6f8 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -247,6 +247,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/transport/metadata.h ) s.files += %w( src/core/lib/transport/metadata_batch.h ) s.files += %w( src/core/lib/transport/static_metadata.h ) + s.files += %w( src/core/lib/transport/timeout_encoding.h ) s.files += %w( src/core/lib/transport/transport.h ) s.files += %w( src/core/lib/transport/transport_impl.h ) s.files += %w( src/core/ext/transport/chttp2/transport/bin_decoder.h ) @@ -268,7 +269,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/transport/chttp2/transport/internal.h ) s.files += %w( src/core/ext/transport/chttp2/transport/status_conversion.h ) s.files += %w( src/core/ext/transport/chttp2/transport/stream_map.h ) - s.files += %w( src/core/ext/transport/chttp2/transport/timeout_encoding.h ) s.files += %w( src/core/ext/transport/chttp2/transport/varint.h ) s.files += %w( src/core/ext/transport/chttp2/alpn/alpn.h ) s.files += %w( src/core/lib/security/context/security_context.h ) @@ -412,6 +412,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/transport/metadata.c ) s.files += %w( src/core/lib/transport/metadata_batch.c ) s.files += %w( src/core/lib/transport/static_metadata.c ) + s.files += %w( src/core/lib/transport/timeout_encoding.c ) s.files += %w( src/core/lib/transport/transport.c ) s.files += %w( src/core/lib/transport/transport_op_string.c ) s.files += %w( src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c ) @@ -434,7 +435,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/transport/chttp2/transport/status_conversion.c ) s.files += %w( src/core/ext/transport/chttp2/transport/stream_lists.c ) s.files += %w( src/core/ext/transport/chttp2/transport/stream_map.c ) - s.files += %w( src/core/ext/transport/chttp2/transport/timeout_encoding.c ) s.files += %w( src/core/ext/transport/chttp2/transport/varint.c ) s.files += %w( src/core/ext/transport/chttp2/transport/writing.c ) s.files += %w( src/core/ext/transport/chttp2/alpn/alpn.c ) diff --git a/package.xml b/package.xml index d7d10b3f7cc..ad36868a03a 100644 --- a/package.xml +++ b/package.xml @@ -254,6 +254,7 @@ + @@ -275,7 +276,6 @@ - @@ -419,6 +419,7 @@ + @@ -441,7 +442,6 @@ - diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 5aae753c07d..0894af9a60d 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -46,11 +46,11 @@ #include "src/core/ext/transport/chttp2/transport/http2_errors.h" #include "src/core/ext/transport/chttp2/transport/internal.h" #include "src/core/ext/transport/chttp2/transport/status_conversion.h" -#include "src/core/ext/transport/chttp2/transport/timeout_encoding.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/support/string.h" #include "src/core/lib/transport/static_metadata.h" +#include "src/core/lib/transport/timeout_encoding.h" #include "src/core/lib/transport/transport_impl.h" #define DEFAULT_WINDOW 65535 diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.c b/src/core/ext/transport/chttp2/transport/hpack_encoder.c index ebeee37f0d9..2cb8205d942 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.c +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.c @@ -47,10 +47,10 @@ #include "src/core/ext/transport/chttp2/transport/bin_encoder.h" #include "src/core/ext/transport/chttp2/transport/hpack_table.h" -#include "src/core/ext/transport/chttp2/transport/timeout_encoding.h" #include "src/core/ext/transport/chttp2/transport/varint.h" #include "src/core/lib/transport/metadata.h" #include "src/core/lib/transport/static_metadata.h" +#include "src/core/lib/transport/timeout_encoding.h" #define HASH_FRAGMENT_1(x) ((x)&255) #define HASH_FRAGMENT_2(x) ((x >> 8) & 255) @@ -456,9 +456,9 @@ static void hpack_enc(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem, static void deadline_enc(grpc_chttp2_hpack_compressor *c, gpr_timespec deadline, framer_state *st) { - char timeout_str[GRPC_CHTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE]; + char timeout_str[GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE]; grpc_mdelem *mdelem; - grpc_chttp2_encode_timeout( + grpc_http2_encode_timeout( gpr_time_sub(deadline, gpr_now(deadline.clock_type)), timeout_str); mdelem = grpc_mdelem_from_metadata_strings( GRPC_MDSTR_GRPC_TIMEOUT, grpc_mdstr_from_string(timeout_str)); diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index 84eb5752f16..a2a47d95b2c 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -41,9 +41,9 @@ #include "src/core/ext/transport/chttp2/transport/http2_errors.h" #include "src/core/ext/transport/chttp2/transport/status_conversion.h" -#include "src/core/ext/transport/chttp2/transport/timeout_encoding.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/transport/static_metadata.h" +#include "src/core/lib/transport/timeout_encoding.h" #define TRANSPORT_FROM_PARSING(tp) \ ((grpc_chttp2_transport *)((char *)(tp)-offsetof(grpc_chttp2_transport, \ @@ -667,8 +667,8 @@ static void on_initial_header(void *tp, grpc_mdelem *md) { if (!cached_timeout) { /* not already parsed: parse it now, and store the result away */ cached_timeout = gpr_malloc(sizeof(gpr_timespec)); - if (!grpc_chttp2_decode_timeout(grpc_mdstr_as_c_string(md->value), - cached_timeout)) { + if (!grpc_http2_decode_timeout(grpc_mdstr_as_c_string(md->value), + cached_timeout)) { gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", grpc_mdstr_as_c_string(md->value)); *cached_timeout = gpr_inf_future(GPR_TIMESPAN); diff --git a/src/core/ext/transport/chttp2/transport/timeout_encoding.c b/src/core/lib/transport/timeout_encoding.c similarity index 96% rename from src/core/ext/transport/chttp2/transport/timeout_encoding.c rename to src/core/lib/transport/timeout_encoding.c index b7f79124939..b58ebbd0a8f 100644 --- a/src/core/ext/transport/chttp2/transport/timeout_encoding.c +++ b/src/core/lib/transport/timeout_encoding.c @@ -31,7 +31,7 @@ * */ -#include "src/core/ext/transport/chttp2/transport/timeout_encoding.h" +#include "src/core/lib/transport/timeout_encoding.h" #include #include @@ -117,7 +117,7 @@ static void enc_micros(char *buffer, int64_t x) { } } -void grpc_chttp2_encode_timeout(gpr_timespec timeout, char *buffer) { +void grpc_http2_encode_timeout(gpr_timespec timeout, char *buffer) { if (timeout.tv_sec < 0) { enc_tiny(buffer); } else if (timeout.tv_sec == 0) { @@ -136,7 +136,7 @@ static int is_all_whitespace(const char *p) { return *p == 0; } -int grpc_chttp2_decode_timeout(const char *buffer, gpr_timespec *timeout) { +int grpc_http2_decode_timeout(const char *buffer, gpr_timespec *timeout) { int32_t x = 0; const uint8_t *p = (const uint8_t *)buffer; int have_digit = 0; diff --git a/src/core/ext/transport/chttp2/transport/timeout_encoding.h b/src/core/lib/transport/timeout_encoding.h similarity index 77% rename from src/core/ext/transport/chttp2/transport/timeout_encoding.h rename to src/core/lib/transport/timeout_encoding.h index df2324c7912..92f02f6ecd1 100644 --- a/src/core/ext/transport/chttp2/transport/timeout_encoding.h +++ b/src/core/lib/transport/timeout_encoding.h @@ -31,17 +31,17 @@ * */ -#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_TIMEOUT_ENCODING_H -#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_TIMEOUT_ENCODING_H +#ifndef GRPC_CORE_LIB_TRANSPORT_TIMEOUT_ENCODING_H +#define GRPC_CORE_LIB_TRANSPORT_TIMEOUT_ENCODING_H #include #include "src/core/lib/support/string.h" -#define GRPC_CHTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE (GPR_LTOA_MIN_BUFSIZE + 1) +#define GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE (GPR_LTOA_MIN_BUFSIZE + 1) -/* Encode/decode timeouts to the GRPC over HTTP2 format; +/* Encode/decode timeouts to the GRPC over HTTP/2 format; encoding may round up arbitrarily */ -void grpc_chttp2_encode_timeout(gpr_timespec timeout, char *buffer); -int grpc_chttp2_decode_timeout(const char *buffer, gpr_timespec *timeout); +void grpc_http2_encode_timeout(gpr_timespec timeout, char *buffer); +int grpc_http2_decode_timeout(const char *buffer, gpr_timespec *timeout); -#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_TIMEOUT_ENCODING_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_TIMEOUT_ENCODING_H */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index b37e27c27ea..6e6513d4a46 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -161,6 +161,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/transport/metadata.c', 'src/core/lib/transport/metadata_batch.c', 'src/core/lib/transport/static_metadata.c', + 'src/core/lib/transport/timeout_encoding.c', 'src/core/lib/transport/transport.c', 'src/core/lib/transport/transport_op_string.c', 'src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c', @@ -183,7 +184,6 @@ CORE_SOURCE_FILES = [ 'src/core/ext/transport/chttp2/transport/status_conversion.c', 'src/core/ext/transport/chttp2/transport/stream_lists.c', 'src/core/ext/transport/chttp2/transport/stream_map.c', - 'src/core/ext/transport/chttp2/transport/timeout_encoding.c', 'src/core/ext/transport/chttp2/transport/varint.c', 'src/core/ext/transport/chttp2/transport/writing.c', 'src/core/ext/transport/chttp2/alpn/alpn.c', diff --git a/test/core/transport/chttp2/timeout_encoding_test.c b/test/core/transport/timeout_encoding_test.c similarity index 89% rename from test/core/transport/chttp2/timeout_encoding_test.c rename to test/core/transport/timeout_encoding_test.c index 67639936a76..b6004af7b47 100644 --- a/test/core/transport/chttp2/timeout_encoding_test.c +++ b/test/core/transport/timeout_encoding_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/ext/transport/chttp2/transport/timeout_encoding.h" +#include "src/core/lib/transport/timeout_encoding.h" #include #include @@ -46,8 +46,8 @@ #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x) static void assert_encodes_as(gpr_timespec ts, const char *s) { - char buffer[GRPC_CHTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE]; - grpc_chttp2_encode_timeout(ts, buffer); + char buffer[GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE]; + grpc_http2_encode_timeout(ts, buffer); gpr_log(GPR_INFO, "check '%s' == '%s'", buffer, s); GPR_ASSERT(0 == strcmp(buffer, s)); } @@ -88,7 +88,7 @@ void test_encoding(void) { static void assert_decodes_as(const char *buffer, gpr_timespec expected) { gpr_timespec got; gpr_log(GPR_INFO, "check decoding '%s'", buffer); - GPR_ASSERT(1 == grpc_chttp2_decode_timeout(buffer, &got)); + GPR_ASSERT(1 == grpc_http2_decode_timeout(buffer, &got)); GPR_ASSERT(0 == gpr_time_cmp(got, expected)); } @@ -137,15 +137,15 @@ void test_decoding(void) { void test_decoding_fails(void) { gpr_timespec x; LOG_TEST("test_decoding_fails"); - GPR_ASSERT(0 == grpc_chttp2_decode_timeout("", &x)); - GPR_ASSERT(0 == grpc_chttp2_decode_timeout(" ", &x)); - GPR_ASSERT(0 == grpc_chttp2_decode_timeout("x", &x)); - GPR_ASSERT(0 == grpc_chttp2_decode_timeout("1", &x)); - GPR_ASSERT(0 == grpc_chttp2_decode_timeout("1x", &x)); - GPR_ASSERT(0 == grpc_chttp2_decode_timeout("1ux", &x)); - GPR_ASSERT(0 == grpc_chttp2_decode_timeout("!", &x)); - GPR_ASSERT(0 == grpc_chttp2_decode_timeout("n1", &x)); - GPR_ASSERT(0 == grpc_chttp2_decode_timeout("-1u", &x)); + GPR_ASSERT(0 == grpc_http2_decode_timeout("", &x)); + GPR_ASSERT(0 == grpc_http2_decode_timeout(" ", &x)); + GPR_ASSERT(0 == grpc_http2_decode_timeout("x", &x)); + GPR_ASSERT(0 == grpc_http2_decode_timeout("1", &x)); + GPR_ASSERT(0 == grpc_http2_decode_timeout("1x", &x)); + GPR_ASSERT(0 == grpc_http2_decode_timeout("1ux", &x)); + GPR_ASSERT(0 == grpc_http2_decode_timeout("!", &x)); + GPR_ASSERT(0 == grpc_http2_decode_timeout("n1", &x)); + GPR_ASSERT(0 == grpc_http2_decode_timeout("-1u", &x)); } int main(int argc, char **argv) { diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 8233da957d1..b721cd96d1e 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -866,6 +866,7 @@ src/core/lib/transport/connectivity_state.h \ src/core/lib/transport/metadata.h \ src/core/lib/transport/metadata_batch.h \ src/core/lib/transport/static_metadata.h \ +src/core/lib/transport/timeout_encoding.h \ src/core/lib/transport/transport.h \ src/core/lib/transport/transport_impl.h \ src/core/ext/transport/chttp2/transport/bin_decoder.h \ @@ -887,7 +888,6 @@ src/core/ext/transport/chttp2/transport/incoming_metadata.h \ src/core/ext/transport/chttp2/transport/internal.h \ src/core/ext/transport/chttp2/transport/status_conversion.h \ src/core/ext/transport/chttp2/transport/stream_map.h \ -src/core/ext/transport/chttp2/transport/timeout_encoding.h \ src/core/ext/transport/chttp2/transport/varint.h \ src/core/ext/transport/chttp2/alpn/alpn.h \ src/core/lib/security/context/security_context.h \ @@ -1031,6 +1031,7 @@ src/core/lib/transport/connectivity_state.c \ src/core/lib/transport/metadata.c \ src/core/lib/transport/metadata_batch.c \ src/core/lib/transport/static_metadata.c \ +src/core/lib/transport/timeout_encoding.c \ src/core/lib/transport/transport.c \ src/core/lib/transport/transport_op_string.c \ src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c \ @@ -1053,7 +1054,6 @@ src/core/ext/transport/chttp2/transport/parsing.c \ src/core/ext/transport/chttp2/transport/status_conversion.c \ src/core/ext/transport/chttp2/transport/stream_lists.c \ src/core/ext/transport/chttp2/transport/stream_map.c \ -src/core/ext/transport/chttp2/transport/timeout_encoding.c \ src/core/ext/transport/chttp2/transport/varint.c \ src/core/ext/transport/chttp2/transport/writing.c \ src/core/ext/transport/chttp2/alpn/alpn.c \ diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index cdbc254f430..54459150e14 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -1685,7 +1685,7 @@ "language": "c", "name": "timeout_encoding_test", "src": [ - "test/core/transport/chttp2/timeout_encoding_test.c" + "test/core/transport/timeout_encoding_test.c" ], "third_party": false, "type": "target" @@ -5782,6 +5782,7 @@ "src/core/lib/transport/metadata.h", "src/core/lib/transport/metadata_batch.h", "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/timeout_encoding.h", "src/core/lib/transport/transport.h", "src/core/lib/transport/transport_impl.h" ], @@ -5955,6 +5956,8 @@ "src/core/lib/transport/metadata_batch.h", "src/core/lib/transport/static_metadata.c", "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/timeout_encoding.c", + "src/core/lib/transport/timeout_encoding.h", "src/core/lib/transport/transport.c", "src/core/lib/transport/transport.h", "src/core/lib/transport/transport_impl.h", @@ -6314,7 +6317,6 @@ "src/core/ext/transport/chttp2/transport/internal.h", "src/core/ext/transport/chttp2/transport/status_conversion.h", "src/core/ext/transport/chttp2/transport/stream_map.h", - "src/core/ext/transport/chttp2/transport/timeout_encoding.h", "src/core/ext/transport/chttp2/transport/varint.h" ], "language": "c", @@ -6358,8 +6360,6 @@ "src/core/ext/transport/chttp2/transport/stream_lists.c", "src/core/ext/transport/chttp2/transport/stream_map.c", "src/core/ext/transport/chttp2/transport/stream_map.h", - "src/core/ext/transport/chttp2/transport/timeout_encoding.c", - "src/core/ext/transport/chttp2/transport/timeout_encoding.h", "src/core/ext/transport/chttp2/transport/varint.c", "src/core/ext/transport/chttp2/transport/varint.h", "src/core/ext/transport/chttp2/transport/writing.c" diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj index a9e96dab462..fd051977775 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj @@ -375,6 +375,7 @@ + @@ -396,7 +397,6 @@ - @@ -628,6 +628,8 @@ + + @@ -672,8 +674,6 @@ - - diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters index be77e53f457..dff246723b8 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters @@ -259,6 +259,9 @@ src\core\lib\transport + + src\core\lib\transport + src\core\lib\transport @@ -325,9 +328,6 @@ src\core\ext\transport\chttp2\transport - - src\core\ext\transport\chttp2\transport - src\core\ext\transport\chttp2\transport @@ -881,6 +881,9 @@ src\core\lib\transport + + src\core\lib\transport + src\core\lib\transport @@ -944,9 +947,6 @@ src\core\ext\transport\chttp2\transport - - src\core\ext\transport\chttp2\transport - src\core\ext\transport\chttp2\transport diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj index 1cfe06aec6d..df455f91f6e 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj @@ -364,6 +364,7 @@ + @@ -385,7 +386,6 @@ - @@ -595,6 +595,8 @@ + + @@ -641,8 +643,6 @@ - - diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters index c33c6650e70..84c4807ef06 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -262,6 +262,9 @@ src\core\lib\transport + + src\core\lib\transport + src\core\lib\transport @@ -331,9 +334,6 @@ src\core\ext\transport\chttp2\transport - - src\core\ext\transport\chttp2\transport - src\core\ext\transport\chttp2\transport @@ -788,6 +788,9 @@ src\core\lib\transport + + src\core\lib\transport + src\core\lib\transport @@ -851,9 +854,6 @@ src\core\ext\transport\chttp2\transport - - src\core\ext\transport\chttp2\transport - src\core\ext\transport\chttp2\transport diff --git a/vsprojects/vcxproj/test/timeout_encoding_test/timeout_encoding_test.vcxproj b/vsprojects/vcxproj/test/timeout_encoding_test/timeout_encoding_test.vcxproj index 37be682009f..76efe303947 100644 --- a/vsprojects/vcxproj/test/timeout_encoding_test/timeout_encoding_test.vcxproj +++ b/vsprojects/vcxproj/test/timeout_encoding_test/timeout_encoding_test.vcxproj @@ -158,7 +158,7 @@ - + diff --git a/vsprojects/vcxproj/test/timeout_encoding_test/timeout_encoding_test.vcxproj.filters b/vsprojects/vcxproj/test/timeout_encoding_test/timeout_encoding_test.vcxproj.filters index 3e3b8d21a42..d5fafc20ed3 100644 --- a/vsprojects/vcxproj/test/timeout_encoding_test/timeout_encoding_test.vcxproj.filters +++ b/vsprojects/vcxproj/test/timeout_encoding_test/timeout_encoding_test.vcxproj.filters @@ -1,8 +1,8 @@ - - test\core\transport\chttp2 + + test\core\transport @@ -16,9 +16,6 @@ {3178e0c5-5a68-26eb-6bf6-a5a8dabb0a3c} - - {40739011-4ce0-83f5-d2d6-af515bac7f87} - From 51d002244816d53623d1743df15fe26e94f9e8b6 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 15 Jul 2016 09:12:26 -0700 Subject: [PATCH 048/279] Change priority for adding the filter in the filter_call_init_fails test. --- test/core/end2end/tests/filter_call_init_fails.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/core/end2end/tests/filter_call_init_fails.c b/test/core/end2end/tests/filter_call_init_fails.c index e8ceb33eb7e..a1699e86c9f 100644 --- a/test/core/end2end/tests/filter_call_init_fails.c +++ b/test/core/end2end/tests/filter_call_init_fails.c @@ -238,16 +238,16 @@ static const grpc_channel_filter test_filter = { static bool maybe_add_filter(grpc_channel_stack_builder *builder, void *arg) { if (g_enable_filter) { - return grpc_channel_stack_builder_prepend_filter(builder, &test_filter, - NULL, NULL); + return grpc_channel_stack_builder_append_filter(builder, &test_filter, + NULL, NULL); } else { return true; } } static void init_plugin(void) { - grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, 0, maybe_add_filter, - NULL); + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, MAX_INT, + maybe_add_filter, NULL); } static void destroy_plugin(void) {} From e4704d3edae128b64951e399d2164f1f402c56b8 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Mon, 18 Jul 2016 11:08:04 -0700 Subject: [PATCH 049/279] =?UTF-8?q?=E2=80=9CAllow=20non-modular=20includes?= =?UTF-8?q?=20in=20framework=20modules=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s the magic sentence that allows pods dependent on RxLibrary to be archived correctly by XCode. It’s less than ideal, and seems arbitrary (why RxLibrary specifically?), so we’ll try to produce a minimal case and open an issue with it in the Cocoapods repo. --- .../objective-c/auth_sample/AuthTestService.podspec | 11 +++++++---- examples/objective-c/helloworld/HelloWorld.podspec | 11 +++++++---- examples/objective-c/route_guide/RouteGuide.podspec | 11 +++++++---- gRPC-ProtoRPC.podspec | 4 +++- gRPC.podspec | 5 +++++ src/objective-c/README.md | 11 +++++++---- .../examples/RemoteTestClient/RemoteTest.podspec | 11 +++++++---- .../tests/RemoteTestClient/RemoteTest.podspec | 11 +++++++---- 8 files changed, 50 insertions(+), 25 deletions(-) diff --git a/examples/objective-c/auth_sample/AuthTestService.podspec b/examples/objective-c/auth_sample/AuthTestService.podspec index af5ef289464..12a59700705 100644 --- a/examples/objective-c/auth_sample/AuthTestService.podspec +++ b/examples/objective-c/auth_sample/AuthTestService.podspec @@ -45,10 +45,6 @@ Pod::Spec.new do |s| ms.requires_arc = false # The generated files depend on the protobuf runtime. ms.dependency "Protobuf" - # This is needed by all pods that depend on Protobuf: - ms.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', - } end # Files generated by the gRPC plugin @@ -60,4 +56,11 @@ Pod::Spec.new do |s| ss.dependency "gRPC-ProtoRPC" ss.dependency "#{s.name}/Messages" end + + s.pod_target_xcconfig = { + # This is needed by all pods that depend on Protobuf: + 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', + # This is needed by all pods that depend on gRPC-RxLibrary: + 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES', + } end diff --git a/examples/objective-c/helloworld/HelloWorld.podspec b/examples/objective-c/helloworld/HelloWorld.podspec index bce6cd51724..537cc36a61a 100644 --- a/examples/objective-c/helloworld/HelloWorld.podspec +++ b/examples/objective-c/helloworld/HelloWorld.podspec @@ -45,10 +45,6 @@ Pod::Spec.new do |s| ms.requires_arc = false # The generated files depend on the protobuf runtime. ms.dependency "Protobuf" - # This is needed by all pods that depend on Protobuf: - ms.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', - } end # Files generated by the gRPC plugin @@ -60,4 +56,11 @@ Pod::Spec.new do |s| ss.dependency "gRPC-ProtoRPC" ss.dependency "#{s.name}/Messages" end + + s.pod_target_xcconfig = { + # This is needed by all pods that depend on Protobuf: + 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', + # This is needed by all pods that depend on gRPC-RxLibrary: + 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES', + } end diff --git a/examples/objective-c/route_guide/RouteGuide.podspec b/examples/objective-c/route_guide/RouteGuide.podspec index e2132507514..3fead932e59 100644 --- a/examples/objective-c/route_guide/RouteGuide.podspec +++ b/examples/objective-c/route_guide/RouteGuide.podspec @@ -45,10 +45,6 @@ Pod::Spec.new do |s| ms.requires_arc = false # The generated files depend on the protobuf runtime. ms.dependency "Protobuf" - # This is needed by all pods that depend on Protobuf: - ms.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', - } end # Files generated by the gRPC plugin @@ -60,4 +56,11 @@ Pod::Spec.new do |s| ss.dependency "gRPC-ProtoRPC" ss.dependency "#{s.name}/Messages" end + + s.pod_target_xcconfig = { + # This is needed by all pods that depend on Protobuf: + 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', + # This is needed by all pods that depend on gRPC-RxLibrary: + 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES', + } end diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 9cc33c7dbd0..62c9a232a54 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -62,8 +62,10 @@ Pod::Spec.new do |s| s.dependency 'gRPC', version s.dependency 'gRPC-RxLibrary', version s.dependency 'Protobuf', '~> 3.0.0-beta-3.1' - # This is needed by all pods that depend on Protobuf: s.pod_target_xcconfig = { + # This is needed by all pods that depend on Protobuf: 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', + # This is needed by all pods that depend on gRPC-RxLibrary: + 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES', } end diff --git a/gRPC.podspec b/gRPC.podspec index e5556cc5448..f95a6b32232 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -65,4 +65,9 @@ Pod::Spec.new do |s| # Certificates, to be able to establish TLS connections: s.resource_bundles = { 'gRPCCertificates' => ['etc/roots.pem'] } + + s.pod_target_xcconfig = { + # This is needed by all pods that depend on gRPC-RxLibrary: + 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES', + } end diff --git a/src/objective-c/README.md b/src/objective-c/README.md index a0ca5f448a0..ee20cc295de 100644 --- a/src/objective-c/README.md +++ b/src/objective-c/README.md @@ -82,10 +82,6 @@ Pod::Spec.new do |s| ms.requires_arc = false # The generated files depend on the protobuf runtime. ms.dependency 'Protobuf' - # This is needed by all pods that depend on Protobuf: - ms.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', - } end # The --objcgrpc_out plugin generates a pair of .pbrpc.h/.pbrpc.m files for each .proto file with @@ -98,6 +94,13 @@ Pod::Spec.new do |s| ss.dependency 'gRPC-ProtoRPC' ss.dependency "#{s.name}/Messages" end + + s.pod_target_xcconfig = { + # This is needed by all pods that depend on Protobuf: + 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', + # This is needed by all pods that depend on gRPC-RxLibrary: + 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES', + } end ``` diff --git a/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec b/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec index 6e783fb5adb..c4578047b6f 100644 --- a/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec +++ b/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec @@ -35,10 +35,6 @@ Pod::Spec.new do |s| ms.header_mappings_dir = '.' ms.requires_arc = false ms.dependency 'Protobuf' - # This is needed by all pods that depend on Protobuf: - ms.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', - } end s.subspec 'Services' do |ss| @@ -48,4 +44,11 @@ Pod::Spec.new do |s| ss.dependency 'gRPC-ProtoRPC' ss.dependency "#{s.name}/Messages" end + + s.pod_target_xcconfig = { + # This is needed by all pods that depend on Protobuf: + 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', + # This is needed by all pods that depend on gRPC-RxLibrary: + 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES', + } end diff --git a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec index 7d84a5ae4dc..d47b3044ad5 100644 --- a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec +++ b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec @@ -35,10 +35,6 @@ Pod::Spec.new do |s| ms.header_mappings_dir = "." ms.requires_arc = false ms.dependency "Protobuf" - # This is needed by all pods that depend on Protobuf: - ms.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', - } end s.subspec "Services" do |ss| @@ -48,4 +44,11 @@ Pod::Spec.new do |s| ss.dependency "gRPC-ProtoRPC" ss.dependency "#{s.name}/Messages" end + + s.pod_target_xcconfig = { + # This is needed by all pods that depend on Protobuf: + 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', + # This is needed by all pods that depend on gRPC-RxLibrary: + 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES', + } end From 44a2f25667fa902edcfa0e184be9e980ac002664 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 18 Jul 2016 14:13:31 -0700 Subject: [PATCH 050/279] s/MAX_INT/INT_MAX/ --- test/core/end2end/tests/filter_call_init_fails.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/core/end2end/tests/filter_call_init_fails.c b/test/core/end2end/tests/filter_call_init_fails.c index a1699e86c9f..78cc56921e0 100644 --- a/test/core/end2end/tests/filter_call_init_fails.c +++ b/test/core/end2end/tests/filter_call_init_fails.c @@ -33,6 +33,7 @@ #include "test/core/end2end/end2end_tests.h" +#include #include #include #include @@ -246,7 +247,7 @@ static bool maybe_add_filter(grpc_channel_stack_builder *builder, void *arg) { } static void init_plugin(void) { - grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, MAX_INT, + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, maybe_add_filter, NULL); } From 6570b83c9cf40e749a8b57c33df123993b0fb680 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Mon, 18 Jul 2016 23:29:50 +0200 Subject: [PATCH 051/279] Splitting interop_server.cc --- Makefile | 62 +++++++++++++++++-- build.yaml | 10 ++- test/cpp/interop/interop_server.cc | 19 +----- test/cpp/interop/interop_server_bootstrap.cc | 54 ++++++++++++++++ test/cpp/interop/server_helper.h | 6 ++ tools/run_tests/sources_and_headers.json | 16 ++++- .../interop_server_main.vcxproj | 51 +-------------- .../interop_server_main.vcxproj.filters | 23 +------ 8 files changed, 147 insertions(+), 94 deletions(-) create mode 100644 test/cpp/interop/interop_server_bootstrap.cc diff --git a/Makefile b/Makefile index 4ce22678d7e..061af59f992 100644 --- a/Makefile +++ b/Makefile @@ -1184,9 +1184,9 @@ pc_cxx: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++.pc pc_cxx_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++_unsecure.pc ifeq ($(EMBED_OPENSSL),true) -privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a +privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a else -privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a +privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a endif @@ -4302,7 +4302,7 @@ endif endif -LIBINTEROP_SERVER_MAIN_SRC = \ +LIBINTEROP_SERVER_LIB_SRC = \ $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc \ $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \ $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc \ @@ -4310,6 +4310,56 @@ LIBINTEROP_SERVER_MAIN_SRC = \ PUBLIC_HEADERS_CXX += \ +LIBINTEROP_SERVER_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBINTEROP_SERVER_LIB_SRC)))) + + +ifeq ($(NO_SECURE),true) + +# You can't build secure libraries if you don't have OpenSSL. + +$(LIBDIR)/$(CONFIG)/libinterop_server_lib.a: openssl_dep_error + + +else + +ifeq ($(NO_PROTOBUF),true) + +# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. + +$(LIBDIR)/$(CONFIG)/libinterop_server_lib.a: protobuf_dep_error + + +else + +$(LIBDIR)/$(CONFIG)/libinterop_server_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_SERVER_LIB_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a + $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBINTEROP_SERVER_LIB_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a +endif + + + + +endif + +endif + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(LIBINTEROP_SERVER_LIB_OBJS:.o=.dep) +endif +endif +$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_server.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc + + +LIBINTEROP_SERVER_MAIN_SRC = \ + test/cpp/interop/interop_server_bootstrap.cc \ + +PUBLIC_HEADERS_CXX += \ + LIBINTEROP_SERVER_MAIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBINTEROP_SERVER_MAIN_SRC)))) @@ -4352,7 +4402,6 @@ ifneq ($(NO_DEPS),true) -include $(LIBINTEROP_SERVER_MAIN_OBJS:.o=.dep) endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_server.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc LIBQPS_SRC = \ @@ -11311,10 +11360,10 @@ $(BINDIR)/$(CONFIG)/interop_server: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/interop_server: $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/interop_server: $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_server + $(Q) $(LDXX) $(LDFLAGS) $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_server endif @@ -14872,6 +14921,7 @@ test/cpp/interop/client.cc: $(OPENSSL_DEP) test/cpp/interop/client_helper.cc: $(OPENSSL_DEP) test/cpp/interop/interop_client.cc: $(OPENSSL_DEP) test/cpp/interop/interop_server.cc: $(OPENSSL_DEP) +test/cpp/interop/interop_server_bootstrap.cc: $(OPENSSL_DEP) test/cpp/interop/server_helper.cc: $(OPENSSL_DEP) test/cpp/qps/client_async.cc: $(OPENSSL_DEP) test/cpp/qps/client_sync.cc: $(OPENSSL_DEP) diff --git a/build.yaml b/build.yaml index 57545839d43..c1d3c5d793e 100644 --- a/build.yaml +++ b/build.yaml @@ -1114,7 +1114,7 @@ libs: - grpc++ - grpc - gpr -- name: interop_server_main +- name: interop_server_lib build: private language: c++ src: @@ -1131,6 +1131,13 @@ libs: - gpr_test_util - gpr - grpc++_test_config +- name: interop_server_main + build: private + language: c++ + src: + - test/cpp/interop/interop_server_bootstrap.cc + deps: + - interop_server_lib - name: qps build: private language: c++ @@ -2773,6 +2780,7 @@ targets: deps: - interop_server_main - interop_server_helper + - interop_server_lib - grpc++_test_util - grpc_test_util - grpc++ diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc index ebef0002a3c..384d8da720e 100644 --- a/test/cpp/interop/interop_server.cc +++ b/test/cpp/interop/interop_server.cc @@ -31,7 +31,6 @@ * */ -#include #include #include @@ -311,7 +310,9 @@ class TestServiceImpl : public TestService::Service { } }; -void RunServer() { +void grpc::testing::interop::RunServer( + std::shared_ptr creds) { + GPR_ASSERT(FLAGS_port != 0); std::ostringstream server_address; server_address << "0.0.0.0:" << FLAGS_port; TestServiceImpl service; @@ -321,8 +322,6 @@ void RunServer() { ServerBuilder builder; builder.RegisterService(&service); - std::shared_ptr creds = - grpc::testing::CreateInteropServerCredentials(); builder.AddListeningPort(server_address.str(), creds); std::unique_ptr server(builder.BuildAndStart()); gpr_log(GPR_INFO, "Server listening on %s", server_address.str().c_str()); @@ -330,15 +329,3 @@ void RunServer() { sleep(5); } } - -static void sigint_handler(int x) { got_sigint = true; } - -int main(int argc, char** argv) { - grpc::testing::InitTest(&argc, &argv, true); - signal(SIGINT, sigint_handler); - - GPR_ASSERT(FLAGS_port != 0); - RunServer(); - - return 0; -} diff --git a/test/cpp/interop/interop_server_bootstrap.cc b/test/cpp/interop/interop_server_bootstrap.cc new file mode 100644 index 00000000000..424f7ca7f0d --- /dev/null +++ b/test/cpp/interop/interop_server_bootstrap.cc @@ -0,0 +1,54 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include + +#include "test/cpp/interop/server_helper.h" +#include "test/cpp/util/test_config.h" + +bool grpc::testing::interop::g_got_sigint = false; + +static void sigint_handler(int x) { + grpc::testing::interop::g_got_sigint = true; +} + +int main(int argc, char** argv) { + grpc::testing::InitTest(&argc, &argv, true); + signal(SIGINT, sigint_handler); + + grpc::testing::interop::RunServer( + grpc::testing::CreateInteropServerCredentials()); + + return 0; +} diff --git a/test/cpp/interop/server_helper.h b/test/cpp/interop/server_helper.h index a1da14a4c8d..fc4ea8b3e81 100644 --- a/test/cpp/interop/server_helper.h +++ b/test/cpp/interop/server_helper.h @@ -60,6 +60,12 @@ class InteropServerContextInspector { const ::grpc::ServerContext& context_; }; +namespace interop { + +extern bool g_got_sigint; +void RunServer(std::shared_ptr creds); + +} // namespace interop } // namespace testing } // namespace grpc diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index e3cfd55cd62..6b7ed70da15 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -2291,6 +2291,7 @@ "grpc++_test_util", "grpc_test_util", "interop_server_helper", + "interop_server_lib", "interop_server_main" ], "headers": [], @@ -4617,13 +4618,26 @@ "src/proto/grpc/testing/test.pb.h" ], "language": "c++", - "name": "interop_server_main", + "name": "interop_server_lib", "src": [ "test/cpp/interop/interop_server.cc" ], "third_party": false, "type": "lib" }, + { + "deps": [ + "interop_server_lib" + ], + "headers": [], + "language": "c++", + "name": "interop_server_main", + "src": [ + "test/cpp/interop/interop_server_bootstrap.cc" + ], + "third_party": false, + "type": "lib" + }, { "deps": [ "grpc++", diff --git a/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj b/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj index 18971d6a341..9fd4d11be9a 100644 --- a/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj +++ b/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj @@ -147,57 +147,12 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + - - {F55BEA2C-B61D-AAFE-CA15-223B8AC0DE5A} - - - {0BE77741-552A-929B-A497-4EF7ECE17A64} - - - {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} - - - {C187A093-A0FE-489D-A40A-6E33DE0F9FEB} - - - {29D16885-7228-4C31-81ED-5F9187C7F2A9} - - - {EAB0A629-17A9-44DB-B5FF-E91A721FE037} - - - {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} - - - {3F7D093D-11F9-C4BC-BEB7-18EB28E3F290} + + {458DCA09-83B9-5E68-D7E9-118864ECBD94} diff --git a/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj.filters b/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj.filters index 4ee8135c045..d8d049299ba 100644 --- a/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj.filters +++ b/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj.filters @@ -1,33 +1,12 @@ - - src\proto\grpc\testing - - - src\proto\grpc\testing - - - src\proto\grpc\testing - - + test\cpp\interop - - {9dfb04b3-9e58-7efb-70a2-b02ec8c5e83e} - - - {ebd8177f-6130-a4fb-1c41-d894f801e3b9} - - - {1df1acf2-4654-4530-10af-912381c69012} - - - {ba56d830-1546-c07f-f5ee-03164e41914e} - {02523054-816a-75a0-b24b-f527e99c7142} From b5f32f0aad59c98e89734f7932fc374cdf475b3a Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 19 Jul 2016 08:36:52 -0700 Subject: [PATCH 052/279] Add test filter right before connected channel filter. --- test/core/end2end/tests/filter_call_init_fails.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/core/end2end/tests/filter_call_init_fails.c b/test/core/end2end/tests/filter_call_init_fails.c index 78cc56921e0..1be6b8bdeaa 100644 --- a/test/core/end2end/tests/filter_call_init_fails.c +++ b/test/core/end2end/tests/filter_call_init_fails.c @@ -239,8 +239,15 @@ static const grpc_channel_filter test_filter = { static bool maybe_add_filter(grpc_channel_stack_builder *builder, void *arg) { if (g_enable_filter) { - return grpc_channel_stack_builder_append_filter(builder, &test_filter, - NULL, NULL); + // Want to add the filter as close to the end as possible, to make + // sure that all of the filters work well together. However, we + // can't add it at the very end, because the connected channel filter + // must be the last one. So we add it right before the last one. + grpc_channel_stack_builder_iterator *it = + grpc_channel_stack_builder_create_iterator_at_last(builder); + GPR_ASSERT(grpc_channel_stack_builder_move_prev(it)); + return grpc_channel_stack_builder_add_filter_before(it, &test_filter, + NULL, NULL); } else { return true; } From 9e6372380dc1571d16f4115b21b8d370f08a4864 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Tue, 19 Jul 2016 17:34:34 -0700 Subject: [PATCH 053/279] Update protobuf submodule to 3.0.0-beta-4 Which has the fix for oneofs when using dynamic frameworks in ObjectiveC --- .gitmodules | 2 +- examples/cpp/helloworld/Makefile | 2 +- examples/cpp/route_guide/Makefile | 2 +- third_party/protobuf | 2 +- tools/run_tests/sanity/check_submodules.sh | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitmodules b/.gitmodules index ce647f3c455..98bedade522 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,7 +4,7 @@ [submodule "third_party/protobuf"] path = third_party/protobuf url = https://github.com/google/protobuf.git - branch = 3.0.0-beta-3 + branch = 3.0.0-beta-4 [submodule "third_party/gflags"] path = third_party/gflags url = https://github.com/gflags/gflags.git diff --git a/examples/cpp/helloworld/Makefile b/examples/cpp/helloworld/Makefile index b45b3c7ee0c..8e6bd96c6ac 100644 --- a/examples/cpp/helloworld/Makefile +++ b/examples/cpp/helloworld/Makefile @@ -97,7 +97,7 @@ ifneq ($(HAS_VALID_PROTOC),true) @echo "Please install Google protocol buffers 3.0.0 and its compiler." @echo "You can find it here:" @echo - @echo " https://github.com/google/protobuf/releases/tag/v3.0.0-beta-3.3" + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0-beta-4" @echo @echo "Here is what I get when trying to evaluate your version of protoc:" @echo diff --git a/examples/cpp/route_guide/Makefile b/examples/cpp/route_guide/Makefile index 50ecf041f56..c29bcaf9fe7 100644 --- a/examples/cpp/route_guide/Makefile +++ b/examples/cpp/route_guide/Makefile @@ -86,7 +86,7 @@ ifneq ($(HAS_VALID_PROTOC),true) @echo "Please install Google protocol buffers 3.0.0 and its compiler." @echo "You can find it here:" @echo - @echo " https://github.com/google/protobuf/releases/tag/v3.0.0-beta-3.3" + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0-beta-4" @echo @echo "Here is what I get when trying to evaluate your version of protoc:" @echo diff --git a/third_party/protobuf b/third_party/protobuf index bdeb215cab2..4b36284bdfd 160000 --- a/third_party/protobuf +++ b/third_party/protobuf @@ -1 +1 @@ -Subproject commit bdeb215cab2985195325fcd5e70c3fa751f46e0f +Subproject commit 4b36284bdfdc77896d7c4cb9645433cf86efb069 diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh index b602d695649..a03d6f07171 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -45,7 +45,7 @@ cat << EOF | awk '{ print $1 }' | sort > $want_submodules 05b155ff59114735ec8cd089f669c4c3d8f59029 third_party/gflags (v2.1.0-45-g05b155f) c99458533a9b4c743ed51537e25989ea55944908 third_party/googletest (release-1.7.0) f8ac463766281625ad710900479130c7fcb4d63b third_party/nanopb (nanopb-0.3.4-29-gf8ac463) - bdeb215cab2985195325fcd5e70c3fa751f46e0f third_party/protobuf (v3.0.0-beta-3.3) + 4b36284bdfdc77896d7c4cb9645433cf86efb069 third_party/protobuf (v3.0.0-beta-4-3-g4b36284) 50893291621658f355bc5b4d450a8d06a563053d third_party/zlib (v1.2.8) EOF From 70ded7eeccf1994f5a87bc983989b96eef503af1 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Tue, 19 Jul 2016 17:33:29 -0700 Subject: [PATCH 054/279] Update sample and test versions to -pre1.1 To use the 3.0.0-beta-4 version of protoc, which has the fix for oneofs when using dynamic frameworks. --- examples/objective-c/auth_sample/AuthTestService.podspec | 2 +- examples/objective-c/helloworld/HelloWorld.podspec | 2 +- examples/objective-c/route_guide/RouteGuide.podspec | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 4 ++-- src/objective-c/!ProtoCompiler.podspec | 8 +++++--- .../examples/RemoteTestClient/RemoteTest.podspec | 2 +- src/objective-c/tests/RemoteTestClient/RemoteTest.podspec | 2 +- 7 files changed, 12 insertions(+), 10 deletions(-) diff --git a/examples/objective-c/auth_sample/AuthTestService.podspec b/examples/objective-c/auth_sample/AuthTestService.podspec index d709c7e636f..b03b3fe82d3 100644 --- a/examples/objective-c/auth_sample/AuthTestService.podspec +++ b/examples/objective-c/auth_sample/AuthTestService.podspec @@ -14,7 +14,7 @@ Pod::Spec.new do |s| src = "../../protos" # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.1" # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = 'Pods' diff --git a/examples/objective-c/helloworld/HelloWorld.podspec b/examples/objective-c/helloworld/HelloWorld.podspec index 48364fc0af1..8168e8a492c 100644 --- a/examples/objective-c/helloworld/HelloWorld.podspec +++ b/examples/objective-c/helloworld/HelloWorld.podspec @@ -14,7 +14,7 @@ Pod::Spec.new do |s| src = "../../protos" # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.1" # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = 'Pods' diff --git a/examples/objective-c/route_guide/RouteGuide.podspec b/examples/objective-c/route_guide/RouteGuide.podspec index 04bc10bc0b5..50a2e5c9620 100644 --- a/examples/objective-c/route_guide/RouteGuide.podspec +++ b/examples/objective-c/route_guide/RouteGuide.podspec @@ -14,7 +14,7 @@ Pod::Spec.new do |s| src = "../../protos" # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.1" # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = 'Pods' diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 97f4f586b72..4e8a8de3040 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -37,7 +37,7 @@ Pod::Spec.new do |s| # before them. s.name = '!ProtoCompiler-gRPCPlugin' v = '1.0.0-pre1' - s.version = v + s.version = "#{v}.1" # .1 to depend on protoc 3.0.0-beta-4 s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC This podspec only downloads the gRPC protoc plugin so that local pods generating protos can use @@ -96,7 +96,7 @@ Pod::Spec.new do |s| s.preserve_paths = plugin # Restrict the protoc version to the one supported by this plugin. - s.dependency '!ProtoCompiler', '3.0.0-beta-3.1' + s.dependency '!ProtoCompiler', '3.0.0-beta-4' # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.1' s.osx.deployment_target = '10.9' diff --git a/src/objective-c/!ProtoCompiler.podspec b/src/objective-c/!ProtoCompiler.podspec index 56aacc33305..45fc1356719 100644 --- a/src/objective-c/!ProtoCompiler.podspec +++ b/src/objective-c/!ProtoCompiler.podspec @@ -36,7 +36,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' - v = '3.0.0-beta-3.1' + v = '3.0.0-beta-4' s.version = v s.summary = 'The Protobuf Compiler (protoc) generates Objective-C files from .proto files' s.description = <<-DESC @@ -120,7 +120,7 @@ Pod::Spec.new do |s| repo_root = '../..' plugin = 'grpc_objective_c_plugin' s.prepare_command = <<-CMD - if [ ! -f protoc ]; then + if [ ! -f bin/protoc ]; then cd #{repo_root} # This will build protoc from the Protobuf submodule of gRPC, and put it in # #{repo_root}/bins/opt/protobuf. @@ -129,7 +129,9 @@ Pod::Spec.new do |s| # _we do not want_. Find a way for this to always build from source. make #{plugin} cd - + else + mv bin/protoc . + mv include/google . fi CMD - end diff --git a/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec b/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec index 7222a80b887..e1ed9b69d3c 100644 --- a/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec +++ b/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec @@ -11,7 +11,7 @@ Pod::Spec.new do |s| s.osx.deployment_target = '10.9' # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.1" repo_root = '../../../..' bin_dir = "#{repo_root}/bins/$CONFIG" diff --git a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec index 53ba1019131..711061b6041 100644 --- a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec +++ b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec @@ -11,7 +11,7 @@ Pod::Spec.new do |s| s.osx.deployment_target = '10.9' # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.1" repo_root = '../../../..' bin_dir = "#{repo_root}/bins/$CONFIG" From d9892bdd8032485919067748c5eedcf52f56240f Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Mon, 4 Jul 2016 00:52:39 -0700 Subject: [PATCH 055/279] Moved sending of initial metadata from server into server handler methods --- src/ruby/lib/grpc/generic/active_call.rb | 47 +++- src/ruby/lib/grpc/generic/bidi_call.rb | 16 +- src/ruby/lib/grpc/generic/rpc_desc.rb | 9 +- src/ruby/lib/grpc/generic/rpc_server.rb | 23 +- src/ruby/spec/generic/active_call_spec.rb | 329 +++++++++++++++++++++- src/ruby/spec/generic/rpc_desc_spec.rb | 14 +- 6 files changed, 412 insertions(+), 26 deletions(-) diff --git a/src/ruby/lib/grpc/generic/active_call.rb b/src/ruby/lib/grpc/generic/active_call.rb index 4260d854376..d43a9e7a4b7 100644 --- a/src/ruby/lib/grpc/generic/active_call.rb +++ b/src/ruby/lib/grpc/generic/active_call.rb @@ -58,7 +58,7 @@ module GRPC include Core::TimeConsts include Core::CallOps extend Forwardable - attr_reader(:deadline) + attr_reader :deadline, :metadata_sent, :metadata_to_send def_delegators :@call, :cancel, :metadata, :write_flag, :write_flag=, :peer, :peer_cert, :trailing_metadata @@ -101,7 +101,7 @@ module GRPC # @param metadata_received [true|false] indicates if metadata has already # been received. Should always be true for server calls def initialize(call, marshal, unmarshal, deadline, started: true, - metadata_received: false) + metadata_received: false, metadata_to_send: nil) fail(TypeError, '!Core::Call') unless call.is_a? Core::Call @call = call @deadline = deadline @@ -110,6 +110,14 @@ module GRPC @metadata_received = metadata_received @metadata_sent = started @op_notifier = nil + + fail(ArgumentError, 'Already sent md') if started && metadata_to_send + @metadata_to_send = metadata_to_send || {} unless started + end + + def send_initial_metadata + fail 'Already sent metadata' if @metadata_sent + start_call(@metadata_to_send) end # output_metadata are provides access to hash that can be used to @@ -187,7 +195,7 @@ module GRPC # @param marshalled [false, true] indicates if the object is already # marshalled. def remote_send(req, marshalled = false) - # TODO(murgatroid99): ensure metadata was sent + start_call(@metadata_to_send) unless @metadata_sent GRPC.logger.debug("sending #{req}, marshalled? #{marshalled}") payload = marshalled ? req : @marshal.call(req) @call.run_batch(SEND_MESSAGE => payload) @@ -203,6 +211,7 @@ module GRPC # list, mulitple metadata for its key are sent def send_status(code = OK, details = '', assert_finished = false, metadata: {}) + start_call unless @metadata_sent ops = { SEND_STATUS_FROM_SERVER => Struct::Status.new(code, details, metadata) } @@ -392,9 +401,12 @@ module GRPC # a list, multiple metadata for its key are sent # @return [Enumerator, nil] a response Enumerator def bidi_streamer(requests, metadata: {}, &blk) - start_call(metadata) - bd = BidiCall.new(@call, @marshal, @unmarshal, + start_call(metadata) unless @metadata_sent + bd = BidiCall.new(@call, + @marshal, + @unmarshal, metadata_received: @metadata_received) + bd.run_on_client(requests, @op_notifier, &blk) end @@ -410,8 +422,12 @@ module GRPC # # @param gen_each_reply [Proc] generates the BiDi stream replies def run_server_bidi(gen_each_reply) - bd = BidiCall.new(@call, @marshal, @unmarshal, - metadata_received: @metadata_received) + bd = BidiCall.new(@call, + @marshal, + @unmarshal, + metadata_received: @metadata_received, + req_view: MultiReqView.new(self)) + bd.run_on_server(gen_each_reply) end @@ -428,6 +444,11 @@ module GRPC @op_notifier.notify(self) end + def merge_metadata_to_send(new_metadata = {}) + fail('cant change metadata after already sent') if @metadata_sent + @metadata_to_send.merge!(new_metadata) + end + private # Starts the call if not already started @@ -454,12 +475,20 @@ module GRPC # SingleReqView limits access to an ActiveCall's methods for use in server # handlers that receive just one request. SingleReqView = view_class(:cancelled?, :deadline, :metadata, - :output_metadata, :peer, :peer_cert) + :output_metadata, :peer, :peer_cert, + :send_initial_metadata, + :metadata_to_send, + :merge_metadata_to_send, + :metadata_sent) # MultiReqView limits access to an ActiveCall's methods for use in # server client_streamer handlers. MultiReqView = view_class(:cancelled?, :deadline, :each_queued_msg, - :each_remote_read, :metadata, :output_metadata) + :each_remote_read, :metadata, :output_metadata, + :send_initial_metadata, + :metadata_to_send, + :merge_metadata_to_send, + :metadata_sent) # Operation limits access to an ActiveCall's methods for use as # a Operation on the client. diff --git a/src/ruby/lib/grpc/generic/bidi_call.rb b/src/ruby/lib/grpc/generic/bidi_call.rb index 425dc3e5198..0b6ef4918c6 100644 --- a/src/ruby/lib/grpc/generic/bidi_call.rb +++ b/src/ruby/lib/grpc/generic/bidi_call.rb @@ -56,7 +56,8 @@ module GRPC # @param unmarshal [Function] f(string)->obj that unmarshals responses # @param metadata_received [true|false] indicates if metadata has already # been received. Should always be true for server calls - def initialize(call, marshal, unmarshal, metadata_received: false) + def initialize(call, marshal, unmarshal, metadata_received: false, + req_view: nil) fail(ArgumentError, 'not a call') unless call.is_a? Core::Call @call = call @marshal = marshal @@ -68,6 +69,7 @@ module GRPC @writes_complete = false @complete = false @done_mutex = Mutex.new + @req_view = req_view end # Begins orchestration of the Bidi stream for a client sending requests. @@ -97,7 +99,15 @@ module GRPC # # @param gen_each_reply [Proc] generates the BiDi stream replies. def run_on_server(gen_each_reply) - replys = gen_each_reply.call(each_queued_msg) + # Pass in the optional call object parameter if possible + if gen_each_reply.arity == 1 + replys = gen_each_reply.call(each_queued_msg) + elsif gen_each_reply.arity == 2 + replys = gen_each_reply.call(each_queued_msg, @req_view) + else + fail 'Illegal arity of reply generator' + end + @loop_th = start_read_loop(is_client: false) write_loop(replys, is_client: false) end @@ -162,6 +172,8 @@ module GRPC payload = @marshal.call(req) # Fails if status already received begin + @req_view.send_initial_metadata unless + @req_view.nil? || @req_view.metadata_sent @call.run_batch(SEND_MESSAGE => payload) rescue GRPC::Core::CallError => e # This is almost definitely caused by a status arriving while still diff --git a/src/ruby/lib/grpc/generic/rpc_desc.rb b/src/ruby/lib/grpc/generic/rpc_desc.rb index 913f55d0d3b..584fe781698 100644 --- a/src/ruby/lib/grpc/generic/rpc_desc.rb +++ b/src/ruby/lib/grpc/generic/rpc_desc.rb @@ -104,7 +104,14 @@ module GRPC end def assert_arity_matches(mth) - if request_response? || server_streamer? + # A bidi handler function can optionally be passed a second + # call object parameter for access to metadata, cancelling, etc. + if bidi_streamer? + if mth.arity != 2 && mth.arity != 1 + fail arity_error(mth, 2, "should be #{mth.name}(req, call) or " \ + "#{mth.name}(req)") + end + elsif request_response? || server_streamer? if mth.arity != 2 fail arity_error(mth, 2, "should be #{mth.name}(req, call)") end diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb index c92a532a500..b1d30b8e38c 100644 --- a/src/ruby/lib/grpc/generic/rpc_server.rb +++ b/src/ruby/lib/grpc/generic/rpc_server.rb @@ -339,8 +339,11 @@ module GRPC return an_rpc if @pool.jobs_waiting <= @max_waiting_requests GRPC.logger.warn("NOT AVAILABLE: too many jobs_waiting: #{an_rpc}") noop = proc { |x| x } + + # Create a new active call that knows that metadata hasn't been + # sent yet c = ActiveCall.new(an_rpc.call, noop, noop, an_rpc.deadline, - metadata_received: true) + metadata_received: true, started: false) c.send_status(GRPC::Core::StatusCodes::RESOURCE_EXHAUSTED, '') nil end @@ -351,8 +354,11 @@ module GRPC return an_rpc if rpc_descs.key?(mth) GRPC.logger.warn("UNIMPLEMENTED: #{an_rpc}") noop = proc { |x| x } + + # Create a new active call that knows that + # metadata hasn't been sent yet c = ActiveCall.new(an_rpc.call, noop, noop, an_rpc.deadline, - metadata_received: true) + metadata_received: true, started: false) c.send_status(GRPC::Core::StatusCodes::UNIMPLEMENTED, '') nil end @@ -400,17 +406,20 @@ module GRPC unless @connect_md_proc.nil? connect_md = @connect_md_proc.call(an_rpc.method, an_rpc.metadata) end - an_rpc.call.run_batch(SEND_INITIAL_METADATA => connect_md) return nil unless available?(an_rpc) return nil unless implemented?(an_rpc) - # Create the ActiveCall + # Create the ActiveCall. Indicate that metadata hasnt been sent yet. GRPC.logger.info("deadline is #{an_rpc.deadline}; (now=#{Time.now})") rpc_desc = rpc_descs[an_rpc.method.to_sym] - c = ActiveCall.new(an_rpc.call, rpc_desc.marshal_proc, - rpc_desc.unmarshal_proc(:input), an_rpc.deadline, - metadata_received: true) + c = ActiveCall.new(an_rpc.call, + rpc_desc.marshal_proc, + rpc_desc.unmarshal_proc(:input), + an_rpc.deadline, + metadata_received: true, + started: false, + metadata_to_send: connect_md) mth = an_rpc.method.to_sym [c, mth] end diff --git a/src/ruby/spec/generic/active_call_spec.rb b/src/ruby/spec/generic/active_call_spec.rb index 018580e0dfa..0c72be9a98a 100644 --- a/src/ruby/spec/generic/active_call_spec.rb +++ b/src/ruby/spec/generic/active_call_spec.rb @@ -60,8 +60,10 @@ describe GRPC::ActiveCall do end describe '#multi_req_view' do - it 'exposes a fixed subset of the ActiveCall methods' do - want = %w(cancelled?, deadline, each_remote_read, metadata, shutdown) + it 'exposes a fixed subset of the ActiveCall.methods' do + want = %w(cancelled?, deadline, each_remote_read, metadata, \ + shutdown, peer, peer_cert, send_initial_metadata, \ + initial_metadata_sent) v = @client_call.multi_req_view want.each do |w| expect(v.methods.include?(w)) @@ -70,8 +72,10 @@ describe GRPC::ActiveCall do end describe '#single_req_view' do - it 'exposes a fixed subset of the ActiveCall methods' do - want = %w(cancelled?, deadline, metadata, shutdown) + it 'exposes a fixed subset of the ActiveCall.methods' do + want = %w(cancelled?, deadline, metadata, shutdown, \ + send_initial_metadata, metadata_to_send, \ + merge_metadata_to_send, initial_metadata_sent) v = @client_call.single_req_view want.each do |w| expect(v.methods.include?(w)) @@ -149,6 +153,158 @@ describe GRPC::ActiveCall do end end + describe 'sending initial metadata', send_initial_metadata: true do + it 'sends metadata before sending a message if it hasnt been sent yet' do + call = make_test_call + @client_call = ActiveCall.new( + call, + @pass_through, + @pass_through, + deadline, + started: false) + + metadata = { key: 'dummy_val', other: 'other_val' } + expect(@client_call.metadata_sent).to eq(false) + @client_call.merge_metadata_to_send(metadata) + + message = 'dummy message' + + expect(call).to( + receive(:run_batch) + .with( + hash_including( + CallOps::SEND_INITIAL_METADATA => metadata)).once) + + expect(call).to( + receive(:run_batch).with(hash_including( + CallOps::SEND_MESSAGE => message)).once) + @client_call.remote_send(message) + + expect(@client_call.metadata_sent).to eq(true) + end + + it 'doesnt send metadata if it thinks its already been sent' do + call = make_test_call + + @client_call = ActiveCall.new(call, + @pass_through, + @pass_through, + deadline) + + expect(@client_call.metadata_sent).to eql(true) + expect(call).to( + receive(:run_batch).with(hash_including( + CallOps::SEND_INITIAL_METADATA)).never) + + @client_call.remote_send('test message') + end + + it 'sends metadata if it is explicitly sent and ok to do so' do + call = make_test_call + + @client_call = ActiveCall.new(call, + @pass_through, + @pass_through, + deadline, + started: false) + + expect(@client_call.metadata_sent).to eql(false) + + metadata = { test_key: 'val' } + @client_call.merge_metadata_to_send(metadata) + expect(@client_call.metadata_to_send).to eq(metadata) + + expect(call).to( + receive(:run_batch).with(hash_including( + CallOps::SEND_INITIAL_METADATA => + metadata)).once) + @client_call.send_initial_metadata + end + + it 'explicit sending fails if metadata has already been sent' do + call = make_test_call + + @client_call = ActiveCall.new(call, + @pass_through, + @pass_through, + deadline) + + expect(@client_call.metadata_sent).to eql(true) + + blk = proc do + @client_call.send_initial_metadata + end + + expect { blk.call }.to raise_error + end + end + + describe '#merge_metadata_to_send', merge_metadata_to_send: true do + it 'adds to existing metadata when there is existing metadata to send' do + call = make_test_call + starting_metadata = { k1: 'key1_val', k2: 'key2_val' } + @client_call = ActiveCall.new( + call, + @pass_through, @pass_through, + deadline, + started: false, + metadata_to_send: starting_metadata) + + expect(@client_call.metadata_to_send).to eq(starting_metadata) + + @client_call.merge_metadata_to_send( + k3: 'key3_val', + k4: 'key4_val') + + expected_md_to_send = { + k1: 'key1_val', + k2: 'key2_val', + k3: 'key3_val', + k4: 'key4_val' } + + expect(@client_call.metadata_to_send).to eq(expected_md_to_send) + + @client_call.merge_metadata_to_send(k5: 'key5_val') + expected_md_to_send.merge!(k5: 'key5_val') + expect(@client_call.metadata_to_send).to eq(expected_md_to_send) + end + + it 'overrides existing metadata if adding metadata with an existing key' do + call = make_test_call + starting_metadata = { k1: 'key1_val', k2: 'key2_val' } + @client_call = ActiveCall.new( + call, + @pass_through, + @pass_through, + deadline, + started: false, + metadata_to_send: starting_metadata) + + expect(@client_call.metadata_to_send).to eq(starting_metadata) + @client_call.merge_metadata_to_send(k1: 'key1_new_val') + expect(@client_call.metadata_to_send).to eq(k1: 'key1_new_val', + k2: 'key2_val') + end + + it 'fails when initial metadata has already been sent' do + call = make_test_call + @client_call = ActiveCall.new( + call, + @pass_through, + @pass_through, + deadline, + started: true) + + expect(@client_call.metadata_sent).to eq(true) + + blk = proc do + @client_call.merge_metadata_to_send(k1: 'key1_val') + end + + expect { blk.call }.to raise_error + end + end + describe '#client_invoke' do it 'sends metadata to the server when present' do call = make_test_call @@ -163,7 +319,26 @@ describe GRPC::ActiveCall do end end - describe '#remote_read' do + describe '#send_status', send_status: true do + it 'works when no metadata or messages have been sent yet' do + call = make_test_call + ActiveCall.client_invoke(call) + + recvd_rpc = @server.request_call + server_call = ActiveCall.new( + recvd_rpc.call, + @pass_through, + @pass_through, + deadline, + started: false) + + expect(server_call.metadata_sent).to eq(false) + blk = proc { server_call.send_status(OK) } + expect { blk.call }.to_not raise_error + end + end + + describe '#remote_read', remote_read: true do it 'reads the response sent by a server' do call = make_test_call ActiveCall.client_invoke(call) @@ -205,6 +380,31 @@ describe GRPC::ActiveCall do expect(client_call.metadata).to eq(expected) end + it 'get a status from server when nothing else sent from server' do + client_call = make_test_call + ActiveCall.client_invoke(client_call) + + recvd_rpc = @server.request_call + recvd_call = recvd_rpc.call + + server_call = ActiveCall.new( + recvd_call, + @pass_through, + @pass_through, + deadline, + started: false) + + server_call.send_status(OK, 'OK') + + # Check that we can receive initial metadata and a status + client_call.run_batch( + CallOps::RECV_INITIAL_METADATA => nil) + batch_result = client_call.run_batch( + CallOps::RECV_STATUS_ON_CLIENT => nil) + + expect(batch_result.status.code).to eq(OK) + end + it 'get a nil msg before a status when an OK status is sent' do call = make_test_call ActiveCall.client_invoke(call) @@ -329,6 +529,125 @@ describe GRPC::ActiveCall do end end + # Test sending of the initial metadata in #run_server_bidi + # from the server handler both implicitly and explicitly, + # when the server handler function has one argument and two arguments + describe '#run_server_bidi sanity tests', run_server_bidi: true do + it 'sends the initial metadata implicitly if not already sent' do + requests = ['first message', 'second message'] + server_to_client_metadata = { 'test_key' => 'test_val' } + server_status = OK + + client_call = make_test_call + client_call.run_batch(CallOps::SEND_INITIAL_METADATA => {}) + + recvd_rpc = @server.request_call + recvd_call = recvd_rpc.call + server_call = ActiveCall.new(recvd_call, + @pass_through, + @pass_through, + deadline, + metadata_received: true, + started: false, + metadata_to_send: server_to_client_metadata) + + # Server handler that doesn't have access to a "call" + # It echoes the requests + fake_gen_each_reply_with_no_call_param = proc do |msgs| + msgs + end + + server_thread = Thread.new do + server_call.run_server_bidi( + fake_gen_each_reply_with_no_call_param) + server_call.send_status(server_status) + end + + # Send the requests and send a close so the server can send a status + requests.each do |message| + client_call.run_batch(CallOps::SEND_MESSAGE => message) + end + client_call.run_batch(CallOps::SEND_CLOSE_FROM_CLIENT => nil) + + server_thread.join + + # Expect that initial metadata was sent, + # the requests were echoed, and a status was sent + batch_result = client_call.run_batch( + CallOps::RECV_INITIAL_METADATA => nil) + expect(batch_result.metadata).to eq(server_to_client_metadata) + + requests.each do |message| + batch_result = client_call.run_batch( + CallOps::RECV_MESSAGE => nil) + expect(batch_result.message).to eq(message) + end + + batch_result = client_call.run_batch( + CallOps::RECV_STATUS_ON_CLIENT => nil) + expect(batch_result.status.code).to eq(server_status) + end + + it 'sends the metadata when sent explicitly and not already sent' do + requests = ['first message', 'second message'] + server_to_client_metadata = { 'test_key' => 'test_val' } + server_status = OK + + client_call = make_test_call + client_call.run_batch(CallOps::SEND_INITIAL_METADATA => {}) + + recvd_rpc = @server.request_call + recvd_call = recvd_rpc.call + server_call = ActiveCall.new(recvd_call, + @pass_through, + @pass_through, + deadline, + metadata_received: true, + started: false) + + # Fake server handler that has access to a "call" object and + # uses it to explicitly update and sent the initial metadata + fake_gen_each_reply_with_call_param = proc do |msgs, call_param| + call_param.merge_metadata_to_send(server_to_client_metadata) + call_param.send_initial_metadata + msgs + end + + server_thread = Thread.new do + server_call.run_server_bidi( + fake_gen_each_reply_with_call_param) + server_call.send_status(server_status) + end + + # Send requests and a close from the client so the server + # can send a status + requests.each do |message| + client_call.run_batch( + CallOps::SEND_MESSAGE => message) + end + client_call.run_batch( + CallOps::SEND_CLOSE_FROM_CLIENT => nil) + + server_thread.join + + # Verify that the correct metadata was sent, the requests + # were echoed, and the correct status was sent + batch_result = client_call.run_batch( + CallOps::RECV_INITIAL_METADATA => nil) + expect(batch_result.metadata).to eq(server_to_client_metadata) + + requests.each do |message| + batch_result = client_call.run_batch( + CallOps::RECV_MESSAGE => nil) + expect(batch_result.message).to eq(message) + end + + batch_result = client_call.run_batch( + CallOps::RECV_STATUS_ON_CLIENT => nil) + expect(batch_result.status.code).to eq(server_status) + end + end + def expect_server_to_receive(sent_text, **kw) c = expect_server_to_be_invoked(**kw) expect(c.remote_read).to eq(sent_text) diff --git a/src/ruby/spec/generic/rpc_desc_spec.rb b/src/ruby/spec/generic/rpc_desc_spec.rb index d2080b7ca2d..1a895005bc3 100644 --- a/src/ruby/spec/generic/rpc_desc_spec.rb +++ b/src/ruby/spec/generic/rpc_desc_spec.rb @@ -196,6 +196,9 @@ describe GRPC::RpcDesc do def fake_svstream(_arg1, _arg2) end + def fake_three_args(_arg1, _arg2, _arg3) + end + it 'raises when a request_response does not have 2 args' do [:fake_clstream, :no_arg].each do |mth| blk = proc do @@ -244,8 +247,8 @@ describe GRPC::RpcDesc do expect(&blk).to_not raise_error end - it 'raises when a bidi streamer does not have 1 arg' do - [:fake_svstream, :no_arg].each do |mth| + it 'raises when a bidi streamer does not have 1 or 2 args' do + [:fake_three_args, :no_arg].each do |mth| blk = proc do @bidi_streamer.assert_arity_matches(method(mth)) end @@ -259,6 +262,13 @@ describe GRPC::RpcDesc do end expect(&blk).to_not raise_error end + + it 'passes when a bidi streamer has 2 args' do + blk = proc do + @bidi_streamer.assert_arity_matches(method(:fake_svstream)) + end + expect(&blk).to_not raise_error + end end describe '#request_response?' do From e7ab7203311e3c30569ad98963ac066f335ecb9b Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 21 Jul 2016 11:02:48 -0700 Subject: [PATCH 056/279] clang-format --- test/core/end2end/tests/filter_call_init_fails.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/core/end2end/tests/filter_call_init_fails.c b/test/core/end2end/tests/filter_call_init_fails.c index 1be6b8bdeaa..4980b372784 100644 --- a/test/core/end2end/tests/filter_call_init_fails.c +++ b/test/core/end2end/tests/filter_call_init_fails.c @@ -246,8 +246,8 @@ static bool maybe_add_filter(grpc_channel_stack_builder *builder, void *arg) { grpc_channel_stack_builder_iterator *it = grpc_channel_stack_builder_create_iterator_at_last(builder); GPR_ASSERT(grpc_channel_stack_builder_move_prev(it)); - return grpc_channel_stack_builder_add_filter_before(it, &test_filter, - NULL, NULL); + return grpc_channel_stack_builder_add_filter_before(it, &test_filter, NULL, + NULL); } else { return true; } From 2222047f4588c03abbbd0554eb2b938ee44d0501 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 13 Jul 2016 12:57:41 -0700 Subject: [PATCH 057/279] Add csharp check to return val of byte_buffer_reader_init --- src/csharp/ext/grpc_csharp_ext.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index c670ea65c79..3d0947c03dc 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -253,8 +253,9 @@ GPR_EXPORT intptr_t GPR_CALLTYPE grpcsharp_batch_context_recv_message_length( if (!ctx->recv_message) { return -1; } - /* TODO(issue:#7206): check return value of grpc_byte_buffer_reader_init. */ - grpc_byte_buffer_reader_init(&reader, ctx->recv_message); + + GPR_ASSERT(grpc_byte_buffer_reader_init(&reader, ctx->recv_message)); + return (intptr_t)grpc_byte_buffer_length(reader.buffer_out); } @@ -268,8 +269,7 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_batch_context_recv_message_to_buffer( gpr_slice slice; size_t offset = 0; - /* TODO(issue:#7206): check return value of grpc_byte_buffer_reader_init. */ - grpc_byte_buffer_reader_init(&reader, ctx->recv_message); + GPR_ASSERT(grpc_byte_buffer_reader_init(&reader, ctx->recv_message)); while (grpc_byte_buffer_reader_next(&reader, &slice)) { size_t len = GPR_SLICE_LENGTH(slice); From 2ea5e3d3969a6154a863c8fe0b898f71b5042cff Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Fri, 22 Jul 2016 09:26:41 -0700 Subject: [PATCH 058/279] address comments --- src/core/ext/census/resource.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/core/ext/census/resource.c b/src/core/ext/census/resource.c index 0ca0db94bad..905de2d63da 100644 --- a/src/core/ext/census/resource.c +++ b/src/core/ext/census/resource.c @@ -61,14 +61,11 @@ void initialize_resources(void) { gpr_mu_init(&resource_lock); gpr_mu_lock(&resource_lock); GPR_ASSERT(resources == NULL && n_resources == 0 && n_defined_resources == 0); - // 8 seems like a reasonable size for initial number of resources. - n_resources = 8; - resources = gpr_malloc(n_resources * sizeof(resource *)); - memset(resources, 0, n_resources * sizeof(resource *)); gpr_mu_unlock(&resource_lock); } -// Delete a resource given it's ID. Must be called with resource_lock held. +// Delete a resource given it's ID. The ID must be a valid resource ID. Must be +// called with resource_lock held. static void delete_resource_locked(size_t rid) { GPR_ASSERT(resources[rid] != NULL); gpr_free(resources[rid]->name); @@ -222,12 +219,14 @@ size_t allocate_resource(void) { size_t id = n_resources; // resource ID - initialize to invalid value. // Expand resources if needed. if (n_resources == n_defined_resources) { - resource **new_resources = gpr_malloc(n_resources * 2 * sizeof(resource *)); + size_t new_n_resources = n_resources ? n_resources * 2 : 2; + resource **new_resources = gpr_malloc(new_n_resources * sizeof(resource *)); memcpy(new_resources, resources, n_resources * sizeof(resource *)); - memset(new_resources + n_resources, 0, n_resources * sizeof(resource *)); + memset(new_resources + n_resources, 0, + (new_n_resources - n_resources) * sizeof(resource *)); gpr_free(resources); resources = new_resources; - n_resources *= 2; + n_resources = new_n_resources; id = n_defined_resources; } else { GPR_ASSERT(n_defined_resources < n_resources); @@ -273,11 +272,9 @@ void census_delete_resource(int32_t rid) { int32_t census_resource_id(const char *name) { gpr_mu_lock(&resource_lock); for (int32_t id = 0; (size_t)id < n_resources; id++) { - if (resources[id] != NULL) { - if (strcmp(resources[id]->name, name) == 0) { - gpr_mu_unlock(&resource_lock); - return id; - } + if (resources[id] != NULL && strcmp(resources[id]->name, name) == 0) { + gpr_mu_unlock(&resource_lock); + return id; } } gpr_mu_unlock(&resource_lock); From 74543125b5786c0d3d8ea36adfdc7ae98bfcc3b5 Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Sat, 23 Jul 2016 01:26:46 -0700 Subject: [PATCH 059/279] moved Grpc.Tools dependency from solution level to project level --- examples/csharp/helloworld/.nuget/packages.config | 4 ---- examples/csharp/helloworld/Greeter.sln | 5 ----- examples/csharp/helloworld/Greeter/packages.config | 1 + examples/csharp/route_guide/.nuget/packages.config | 4 ---- examples/csharp/route_guide/RouteGuide.sln | 5 ----- examples/csharp/route_guide/RouteGuide/RouteGuide.csproj | 8 ++++---- .../route_guide/RouteGuideServer/RouteGuideServer.csproj | 8 ++++---- .../csharp/route_guide/RouteGuideServer/packages.config | 1 + 8 files changed, 10 insertions(+), 26 deletions(-) delete mode 100644 examples/csharp/helloworld/.nuget/packages.config delete mode 100644 examples/csharp/route_guide/.nuget/packages.config diff --git a/examples/csharp/helloworld/.nuget/packages.config b/examples/csharp/helloworld/.nuget/packages.config deleted file mode 100644 index aa060800c19..00000000000 --- a/examples/csharp/helloworld/.nuget/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/examples/csharp/helloworld/Greeter.sln b/examples/csharp/helloworld/Greeter.sln index 9430e94de99..49e364d91c0 100644 --- a/examples/csharp/helloworld/Greeter.sln +++ b/examples/csharp/helloworld/Greeter.sln @@ -9,11 +9,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreeterServer", "GreeterSer EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreeterClient", "GreeterClient\GreeterClient.csproj", "{ACCF4597-3748-4117-8633-1CB767F8CCC3}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{FF1EBE95-F20D-4C27-8A61-D0125F3C8152}" - ProjectSection(SolutionItems) = preProject - .nuget\packages.config = .nuget\packages.config - EndProjectSection -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/examples/csharp/helloworld/Greeter/packages.config b/examples/csharp/helloworld/Greeter/packages.config index ff9d6bbf73f..c94bb873073 100644 --- a/examples/csharp/helloworld/Greeter/packages.config +++ b/examples/csharp/helloworld/Greeter/packages.config @@ -4,4 +4,5 @@ + \ No newline at end of file diff --git a/examples/csharp/route_guide/.nuget/packages.config b/examples/csharp/route_guide/.nuget/packages.config deleted file mode 100644 index aa060800c19..00000000000 --- a/examples/csharp/route_guide/.nuget/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/examples/csharp/route_guide/RouteGuide.sln b/examples/csharp/route_guide/RouteGuide.sln index 0b79fdc5ca7..00065b0ba9d 100644 --- a/examples/csharp/route_guide/RouteGuide.sln +++ b/examples/csharp/route_guide/RouteGuide.sln @@ -9,11 +9,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideClient", "RouteGu EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideServer", "RouteGuideServer\RouteGuideServer.csproj", "{4B7C7794-BE24-4477-ACE7-18259EB73D27}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{2F6B184B-A576-4F21-AF2E-27E73D1FC96E}" - ProjectSection(SolutionItems) = preProject - .nuget\packages.config = .nuget\packages.config - EndProjectSection -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj b/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj index 601d16ba24d..942d94f66c7 100644 --- a/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj +++ b/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj @@ -45,15 +45,15 @@ - - False - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll - + + False + ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + diff --git a/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj b/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj index 5bf46b05b89..4ffc5ccca98 100644 --- a/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj +++ b/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj @@ -47,15 +47,15 @@ - - False - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll - + + False + ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + diff --git a/examples/csharp/route_guide/RouteGuideServer/packages.config b/examples/csharp/route_guide/RouteGuideServer/packages.config index b962a7232a9..916fe4c01db 100644 --- a/examples/csharp/route_guide/RouteGuideServer/packages.config +++ b/examples/csharp/route_guide/RouteGuideServer/packages.config @@ -5,4 +5,5 @@ + \ No newline at end of file From 29ca79be8939c0386f1c7b17ba66cc3b105c7fc1 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Mon, 25 Jul 2016 12:00:08 -0700 Subject: [PATCH 060/279] Command processing, validation --- Makefile | 67 +++- build.yaml | 26 +- test/cpp/util/grpc_cli.cc | 202 ++-------- test/cpp/util/grpc_tool.cc | 369 ++++++++++++++++++ test/cpp/util/grpc_tool.h | 47 +++ test/cpp/util/grpc_tool_test.cc | 219 +++++++++++ tools/run_tests/sources_and_headers.json | 32 ++ tools/run_tests/tests.json | 21 + .../grpc_cli_libs/grpc_cli_libs.vcxproj | 3 + .../grpc_cli_libs.vcxproj.filters | 6 + .../vcxproj/test/grpc_cli/grpc_cli.vcxproj | 6 +- .../grpc_tool_test/grpc_tool_test.vcxproj | 286 ++++++++++++++ .../grpc_tool_test.vcxproj.filters | 232 +++++++++++ 13 files changed, 1332 insertions(+), 184 deletions(-) create mode 100644 test/cpp/util/grpc_tool.cc create mode 100644 test/cpp/util/grpc_tool.h create mode 100644 test/cpp/util/grpc_tool_test.cc create mode 100644 vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj create mode 100644 vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters diff --git a/Makefile b/Makefile index 37999d3b1e2..a1165955a9a 100644 --- a/Makefile +++ b/Makefile @@ -1047,6 +1047,7 @@ grpc_node_plugin: $(BINDIR)/$(CONFIG)/grpc_node_plugin grpc_objective_c_plugin: $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin grpc_python_plugin: $(BINDIR)/$(CONFIG)/grpc_python_plugin grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin +grpc_tool_test: $(BINDIR)/$(CONFIG)/grpc_tool_test grpclb_api_test: $(BINDIR)/$(CONFIG)/grpclb_api_test hybrid_end2end_test: $(BINDIR)/$(CONFIG)/hybrid_end2end_test interop_client: $(BINDIR)/$(CONFIG)/interop_client @@ -1402,6 +1403,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/generic_end2end_test \ $(BINDIR)/$(CONFIG)/golden_file_test \ $(BINDIR)/$(CONFIG)/grpc_cli \ + $(BINDIR)/$(CONFIG)/grpc_tool_test \ $(BINDIR)/$(CONFIG)/grpclb_api_test \ $(BINDIR)/$(CONFIG)/hybrid_end2end_test \ $(BINDIR)/$(CONFIG)/interop_client \ @@ -1486,6 +1488,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/generic_end2end_test \ $(BINDIR)/$(CONFIG)/golden_file_test \ $(BINDIR)/$(CONFIG)/grpc_cli \ + $(BINDIR)/$(CONFIG)/grpc_tool_test \ $(BINDIR)/$(CONFIG)/grpclb_api_test \ $(BINDIR)/$(CONFIG)/hybrid_end2end_test \ $(BINDIR)/$(CONFIG)/interop_client \ @@ -1772,6 +1775,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/generic_end2end_test || ( echo test generic_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing golden_file_test" $(Q) $(BINDIR)/$(CONFIG)/golden_file_test || ( echo test golden_file_test failed ; exit 1 ) + $(E) "[RUN] Testing grpc_tool_test" + $(Q) $(BINDIR)/$(CONFIG)/grpc_tool_test || ( echo test grpc_tool_test failed ; exit 1 ) $(E) "[RUN] Testing grpclb_api_test" $(Q) $(BINDIR)/$(CONFIG)/grpclb_api_test || ( echo test grpclb_api_test failed ; exit 1 ) $(E) "[RUN] Testing hybrid_end2end_test" @@ -4089,6 +4094,7 @@ endif LIBGRPC_CLI_LIBS_SRC = \ test/cpp/util/cli_call.cc \ + test/cpp/util/grpc_tool.cc \ test/cpp/util/proto_file_parser.cc \ test/cpp/util/proto_reflection_descriptor_database.cc \ @@ -10998,16 +11004,16 @@ $(BINDIR)/$(CONFIG)/grpc_cli: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/grpc_cli: $(PROTOBUF_DEP) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/grpc_cli: $(PROTOBUF_DEP) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_cli + $(Q) $(LDXX) $(LDFLAGS) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_cli endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_cli.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_cli.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_grpc_cli: $(GRPC_CLI_OBJS:.o=.dep) @@ -11204,6 +11210,60 @@ ifneq ($(NO_DEPS),true) endif +GRPC_TOOL_TEST_SRC = \ + $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \ + $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc \ + test/cpp/util/grpc_tool_test.cc \ + test/cpp/util/string_ref_helper.cc \ + +GRPC_TOOL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_TOOL_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/grpc_tool_test: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+. + +$(BINDIR)/$(CONFIG)/grpc_tool_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/grpc_tool_test: $(PROTOBUF_DEP) $(GRPC_TOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(GRPC_TOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_tool_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_tool_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_grpc_tool_test: $(GRPC_TOOL_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(GRPC_TOOL_TEST_OBJS:.o=.dep) +endif +endif +$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_tool_test.o: $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc + + GRPCLB_API_TEST_SRC = \ $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc \ test/cpp/grpclb/grpclb_api_test.cc \ @@ -14920,6 +14980,7 @@ test/cpp/util/benchmark_config.cc: $(OPENSSL_DEP) test/cpp/util/byte_buffer_proto_helper.cc: $(OPENSSL_DEP) test/cpp/util/cli_call.cc: $(OPENSSL_DEP) test/cpp/util/create_test_channel.cc: $(OPENSSL_DEP) +test/cpp/util/grpc_tool.cc: $(OPENSSL_DEP) test/cpp/util/proto_file_parser.cc: $(OPENSSL_DEP) test/cpp/util/proto_reflection_descriptor_database.cc: $(OPENSSL_DEP) test/cpp/util/string_ref_helper.cc: $(OPENSSL_DEP) diff --git a/build.yaml b/build.yaml index 237394c2056..5b2c5818501 100644 --- a/build.yaml +++ b/build.yaml @@ -1029,10 +1029,12 @@ libs: language: c++ headers: - test/cpp/util/cli_call.h + - test/cpp/util/grpc_tool.h - test/cpp/util/proto_file_parser.h - test/cpp/util/proto_reflection_descriptor_database.h src: - test/cpp/util/cli_call.cc + - test/cpp/util/grpc_tool.cc - test/cpp/util/proto_file_parser.cc - test/cpp/util/proto_reflection_descriptor_database.cc deps: @@ -2658,9 +2660,9 @@ targets: - test/cpp/util/grpc_cli.cc deps: - grpc_cli_libs + - grpc++_reflection - grpc++_test_util - grpc_test_util - - grpc++_reflection - grpc++ - grpc - gpr_test_util @@ -2725,6 +2727,28 @@ targets: secure: false vs_config_type: Application vs_project_guid: '{069E9D05-B78B-4751-9252-D21EBAE7DE8E}' +- name: grpc_tool_test + gtest: true + build: test + language: c++ + headers: + - test/cpp/util/string_ref_helper.h + src: + - src/proto/grpc/testing/echo.proto + - src/proto/grpc/testing/echo_messages.proto + - test/cpp/util/grpc_tool_test.cc + - test/cpp/util/string_ref_helper.cc + deps: + - grpc_cli_libs + - grpc++_reflection + - grpc_test_util + - grpc++ + - grpc + - gpr_test_util + - gpr + filegroups: + - grpc++_codegen_proto + - grpc++_config_proto - name: grpclb_api_test gtest: true build: test diff --git a/test/cpp/util/grpc_cli.cc b/test/cpp/util/grpc_cli.cc index 53529da782c..28c87956d67 100644 --- a/test/cpp/util/grpc_cli.cc +++ b/test/cpp/util/grpc_cli.cc @@ -34,21 +34,18 @@ /* A command line tool to talk to a grpc server. Example of talking to grpc interop server: - grpc_cli call localhost:50051 UnaryCall "response_size:10" \ - --protofiles=src/proto/grpc/testing/test.proto --enable_ssl=false + grpc_cli call localhost:50051 UnaryCall src/proto/grpc/testing/test.proto \ + "response_size:10" --enable_ssl=false Options: - 1. --protofiles, use this flag to provide a proto file if the server does - does not have the reflection service. - 2. --proto_path, if your proto file is not under current working directory, + 1. --proto_path, if your proto file is not under current working directory, use this flag to provide a search root. It should work similar to the - counterpart in protoc. This option is valid only when protofiles is - provided. - 3. --metadata specifies metadata to be sent to the server, such as: + counterpart in protoc. + 2. --metadata specifies metadata to be sent to the server, such as: --metadata="MyHeaderKey1:Value1:MyHeaderKey2:Value2" - 4. --enable_ssl, whether to use tls. - 5. --use_auth, if set to true, attach a GoogleDefaultCredentials to the call - 6. --input_binary_file, a file containing the serialized request. The file + 3. --enable_ssl, whether to use tls. + 4. --use_auth, if set to true, attach a GoogleDefaultCredentials to the call + 3. --input_binary_file, a file containing the serialized request. The file can be generated by calling something like: protoc --proto_path=src/proto/grpc/testing/ \ --encode=grpc.testing.SimpleRequest \ @@ -56,7 +53,7 @@ < input.txt > input.bin If this is used and no proto file is provided in the argument list, the method string has to be exact in the form of /package.service/method. - 7. --output_binary_file, a file to write binary format response into, it can + 4. --output_binary_file, a file to write binary format response into, it can be later decoded using protoc: protoc --proto_path=src/proto/grpc/testing/ \ --decode=grpc.testing.SimpleResponse \ @@ -64,182 +61,33 @@ < output.bin > output.txt */ -#include #include +#include #include -#include #include -#include -#include -#include -#include -#include - -#include "test/cpp/util/cli_call.h" -#include "test/cpp/util/proto_file_parser.h" -#include "test/cpp/util/string_ref_helper.h" +#include +#include "test/cpp/util/grpc_tool.h" #include "test/cpp/util/test_config.h" -DEFINE_bool(enable_ssl, true, "Whether to use ssl/tls."); -DEFINE_bool(use_auth, false, "Whether to create default google credentials."); -DEFINE_string(input_binary_file, "", - "Path to input file containing serialized request."); -DEFINE_string(output_binary_file, "", - "Path to output file to write serialized response."); -DEFINE_string(metadata, "", - "Metadata to send to server, in the form of key1:val1:key2:val2"); -DEFINE_string(proto_path, ".", "Path to look for the proto file."); -// TODO(zyc): support a list of input proto files -DEFINE_string(protofiles, "", "Name of the proto file."); +DEFINE_string(outfile, "", "Output file (default is stdout)"); -void ParseMetadataFlag( - std::multimap* client_metadata) { - if (FLAGS_metadata.empty()) { - return; - } - std::vector fields; - const char* delim = ":"; - size_t cur, next = -1; - do { - cur = next + 1; - next = FLAGS_metadata.find_first_of(delim, cur); - fields.push_back(FLAGS_metadata.substr(cur, next - cur)); - } while (next != grpc::string::npos); - if (fields.size() % 2) { - std::cout << "Failed to parse metadata flag" << std::endl; - exit(1); - } - for (size_t i = 0; i < fields.size(); i += 2) { - client_metadata->insert( - std::pair(fields[i], fields[i + 1])); - } -} - -template -void PrintMetadata(const T& m, const grpc::string& message) { - if (m.empty()) { - return; - } - std::cout << message << std::endl; - grpc::string pair; - for (typename T::const_iterator iter = m.begin(); iter != m.end(); ++iter) { - pair.clear(); - pair.append(iter->first.data(), iter->first.size()); - pair.append(" : "); - pair.append(iter->second.data(), iter->second.size()); - std::cout << pair << std::endl; +static bool SimplePrint(const grpc::string& outfile, + const grpc::string& output) { + if (outfile.empty()) { + std::cout << output; + } else { + std::ofstream output_file(outfile, std::ios::trunc | std::ios::binary); + output_file << output; + output_file.close(); } + return true; } int main(int argc, char** argv) { grpc::testing::InitTest(&argc, &argv, true); - if (argc < 4 || grpc::string(argv[1]) != "call") { - std::cout << "Usage: grpc_cli call server_host:port method_name " - << "[proto file] [text format request] []" << std::endl; - return 1; - } - - grpc::string request_text; - grpc::string server_address(argv[2]); - grpc::string method_name(argv[3]); - std::unique_ptr parser; - grpc::string serialized_request_proto; - - if (argc == 5) { - request_text = argv[4]; - } - - std::shared_ptr creds; - if (!FLAGS_enable_ssl) { - creds = grpc::InsecureChannelCredentials(); - } else { - if (FLAGS_use_auth) { - creds = grpc::GoogleDefaultCredentials(); - } else { - creds = grpc::SslCredentials(grpc::SslCredentialsOptions()); - } - } - std::shared_ptr channel = - grpc::CreateChannel(server_address, creds); - - if (request_text.empty() && FLAGS_input_binary_file.empty()) { - if (isatty(STDIN_FILENO)) { - std::cout << "reading request message from stdin..." << std::endl; - } - std::stringstream input_stream; - input_stream << std::cin.rdbuf(); - request_text = input_stream.str(); - } - - if (!request_text.empty()) { - if (!FLAGS_protofiles.empty()) { - parser.reset(new grpc::testing::ProtoFileParser( - FLAGS_proto_path, FLAGS_protofiles, method_name)); - } else { - parser.reset(new grpc::testing::ProtoFileParser(channel, method_name)); - } - method_name = parser->GetFullMethodName(); - if (parser->HasError()) { - return 1; - } - - if (!FLAGS_input_binary_file.empty()) { - std::cout - << "warning: request given in argv, ignoring --input_binary_file" - << std::endl; - } - } - - if (parser) { - serialized_request_proto = - parser->GetSerializedProto(request_text, true /* is_request */); - if (parser->HasError()) { - return 1; - } - } else if (!FLAGS_input_binary_file.empty()) { - std::ifstream input_file(FLAGS_input_binary_file, - std::ios::in | std::ios::binary); - std::stringstream input_stream; - input_stream << input_file.rdbuf(); - serialized_request_proto = input_stream.str(); - } - std::cout << "connecting to " << server_address << std::endl; - - grpc::string serialized_response_proto; - std::multimap client_metadata; - std::multimap server_initial_metadata, - server_trailing_metadata; - ParseMetadataFlag(&client_metadata); - PrintMetadata(client_metadata, "Sending client initial metadata:"); - grpc::Status s = grpc::testing::CliCall::Call( - channel, method_name, serialized_request_proto, - &serialized_response_proto, client_metadata, &server_initial_metadata, - &server_trailing_metadata); - PrintMetadata(server_initial_metadata, - "Received initial metadata from server:"); - PrintMetadata(server_trailing_metadata, - "Received trailing metadata from server:"); - if (s.ok()) { - std::cout << "Rpc succeeded with OK status" << std::endl; - if (parser) { - grpc::string response_text = parser->GetTextFormat( - serialized_response_proto, false /* is_request */); - if (parser->HasError()) { - return 1; - } - std::cout << "Response: \n " << response_text << std::endl; - } - if (!FLAGS_output_binary_file.empty()) { - std::ofstream output_file(FLAGS_output_binary_file, - std::ios::trunc | std::ios::binary); - output_file << serialized_response_proto; - } - } else { - std::cout << "Rpc failed with status code " << s.error_code() - << ", error message: " << s.error_message() << std::endl; - } - - return 0; + return grpc::testing::GrpcToolMainLib( + argc, (const char**)argv, + std::bind(SimplePrint, FLAGS_outfile, std::placeholders::_1)); } diff --git a/test/cpp/util/grpc_tool.cc b/test/cpp/util/grpc_tool.cc new file mode 100644 index 00000000000..38ac9e55a03 --- /dev/null +++ b/test/cpp/util/grpc_tool.cc @@ -0,0 +1,369 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "grpc_tool.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "test/cpp/util/cli_call.h" + +#include "test/cpp/util/proto_file_parser.h" +#include "test/cpp/util/proto_reflection_descriptor_database.h" +#include "test/cpp/util/string_ref_helper.h" +#include "test/cpp/util/test_config.h" + +DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls."); +DEFINE_bool(use_auth, false, "Whether to create default google credentials."); +DEFINE_string(input_binary_file, "", + "Path to input file containing serialized request."); +DEFINE_string(output_binary_file, "", + "Path to output file to write serialized response."); +DEFINE_string(metadata, "", + "Metadata to send to server, in the form of key1:val1:key2:val2"); +DEFINE_string(proto_path, ".", "Path to look for the proto file."); +// TODO(zyc): support a list of input proto files +DEFINE_string(protofiles, "", "Name of the proto file."); + +namespace grpc { +namespace testing { +namespace { + +class GrpcTool { + public: + explicit GrpcTool(); + virtual ~GrpcTool() {} + bool Help(int argc, const char** argv, OutputCallback callback); + bool CallMethod(int argc, const char** argv, OutputCallback callback); + void SetPrintCommandMode(int exit_status) { + print_command_usage_ = true; + usage_exit_status_ = exit_status; + } + + private: + void CommandUsage(const grpc::string& usage) const; + bool print_command_usage_; + int usage_exit_status_; +}; + +template +std::function BindWith4Args( + T&& func) { + return std::bind(std::forward(func), std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3, + std::placeholders::_4); +} + +template +size_t ArraySize(T& a) { + return ((sizeof(a) / sizeof(*(a))) / + static_cast(!(sizeof(a) % sizeof(*(a))))); +} + +void ParseMetadataFlag( + std::multimap* client_metadata) { + if (FLAGS_metadata.empty()) { + return; + } + std::vector fields; + const char* delim = ":"; + size_t cur, next = -1; + do { + cur = next + 1; + next = FLAGS_metadata.find_first_of(delim, cur); + fields.push_back(FLAGS_metadata.substr(cur, next - cur)); + } while (next != grpc::string::npos); + if (fields.size() % 2) { + fprintf(stderr, "Failed to parse metadata flag.\n"); + exit(1); + } + for (size_t i = 0; i < fields.size(); i += 2) { + client_metadata->insert( + std::pair(fields[i], fields[i + 1])); + } +} + +template +void PrintMetadata(const T& m, const grpc::string& message) { + if (m.empty()) { + return; + } + fprintf(stderr, "%s\n", message.c_str()); + grpc::string pair; + for (typename T::const_iterator iter = m.begin(); iter != m.end(); ++iter) { + pair.clear(); + pair.append(iter->first.data(), iter->first.size()); + pair.append(" : "); + pair.append(iter->second.data(), iter->second.size()); + fprintf(stderr, "%s\n", pair.c_str()); + } +} + +struct Command { + const char* command; + std::function function; + int min_args; + int max_args; +}; + +const Command ops[] = { + {"help", BindWith4Args(&GrpcTool::Help), 0, INT_MAX}, + // {"ls", BindWith4Args(&GrpcTool::ListServices), 1, 3}, + // {"list", BindWith4Args(&GrpcTool::ListServices), 1, 3}, + {"call", BindWith4Args(&GrpcTool::CallMethod), 2, 3}, + // {"type", BindWith4Args(&GrpcTool::PrintType), 2, 2}, + // {"parse", BindWith4Args(&GrpcTool::ParseMessage), 2, 3}, + // {"totext", BindWith4Args(&GrpcTool::ToText), 2, 3}, + // {"tobinary", BindWith4Args(&GrpcTool::ToBinary), 2, 3}, +}; + +void Usage(const grpc::string& msg) { + fprintf( + stderr, + "%s\n" + // " grpc_cli ls ... ; List services\n" + " grpc_cli call ... ; Call method\n" + // " grpc_cli type ... ; Print type\n" + // " grpc_cli parse ... ; Parse message\n" + // " grpc_cli totext ... ; Convert binary message to text\n" + // " grpc_cli tobinary ... ; Convert text message to binary\n" + " grpc_cli help ... ; Print this message, or per-command usage\n" + "\n", + msg.c_str()); + + exit(1); +} + +const Command* FindCommand(const grpc::string& name) { + for (int i = 0; i < (int)ArraySize(ops); i++) { + if (name == ops[i].command) { + return &ops[i]; + } + } + return NULL; +} +} // namespace + +int GrpcToolMainLib(int argc, const char** argv, OutputCallback callback) { + if (argc < 2) { + Usage("No command specified"); + } + + grpc::string command = argv[1]; + argc -= 2; + argv += 2; + + const Command* cmd = FindCommand(command); + if (cmd != NULL) { + GrpcTool grpc_tool; + if (argc < cmd->min_args || argc > cmd->max_args) { + // Force the command to print its usage message + fprintf(stderr, "\nWrong number of arguments for %s\n", command.c_str()); + grpc_tool.SetPrintCommandMode(1); + return cmd->function(&grpc_tool, -1, NULL, callback); + } + const bool ok = cmd->function(&grpc_tool, argc, argv, callback); + return ok ? 0 : 1; + } else { + Usage("Invalid command '" + grpc::string(command.c_str()) + "'"); + } + return 1; +} + +GrpcTool::GrpcTool() : print_command_usage_(false), usage_exit_status_(0) {} + +void GrpcTool::CommandUsage(const grpc::string& usage) const { + if (print_command_usage_) { + fprintf(stderr, "\n%s%s\n", usage.c_str(), + (usage.empty() || usage[usage.size() - 1] != '\n') ? "\n" : ""); + exit(usage_exit_status_); + } +} + +bool GrpcTool::Help(int argc, const char** argv, OutputCallback callback) { + CommandUsage( + "Print help\n" + " grpc_cli help [subcommand]\n"); + + if (argc == 0) { + Usage(""); + } else { + const Command* cmd = FindCommand(argv[0]); + if (cmd == NULL) { + Usage("Unknown command '" + grpc::string(argv[0]) + "'"); + } + SetPrintCommandMode(0); + cmd->function(this, -1, NULL, callback); + } + return true; +} + +bool GrpcTool::CallMethod(int argc, const char** argv, + OutputCallback callback) { + CommandUsage( + "Call method\n" + " grpc_cli call
[.] \n" + "
; host:port\n" + " ; Exported service name\n" + " ; Method name\n" + " ; Text protobuffer (overrides infile)\n" + " --protofiles ; Comma separated proto files used as a" + " fallback when parsing request/response\n" + " --proto_path ; The search path of proto files, valid" + " only when --protofiles is given\n" + " --metadata ; The metadata to be sent to the server\n" + " --enable_ssl ; Set whether to use tls\n" + " --use_auth ; Set whether to create default google" + " credentials\n" + " --outfile ; Output filename (defaults to stdout)\n" + " --input_binary_file ; Path to input file in binary format\n" + " --binary_output ; Path to output file in binary format\n"); + + std::stringstream output_ss; + grpc::string request_text; + grpc::string server_address(argv[0]); + grpc::string method_name(argv[1]); + std::unique_ptr parser; + grpc::string serialized_request_proto; + + if (argc == 3) { + request_text = argv[2]; + } + + std::shared_ptr creds; + if (!FLAGS_enable_ssl) { + creds = grpc::InsecureChannelCredentials(); + } else { + if (FLAGS_use_auth) { + creds = grpc::GoogleDefaultCredentials(); + } else { + creds = grpc::SslCredentials(grpc::SslCredentialsOptions()); + } + } + std::shared_ptr channel = + grpc::CreateChannel(server_address, creds); + + if (request_text.empty() && FLAGS_input_binary_file.empty()) { + if (isatty(STDIN_FILENO)) { + std::cout << "reading request message from stdin..." << std::endl; + } + std::stringstream input_stream; + input_stream << std::cin.rdbuf(); + request_text = input_stream.str(); + } + + if (!request_text.empty()) { + if (!FLAGS_protofiles.empty()) { + parser.reset(new grpc::testing::ProtoFileParser( + FLAGS_proto_path, FLAGS_protofiles, method_name)); + } else { + parser.reset(new grpc::testing::ProtoFileParser(channel, method_name)); + } + method_name = parser->GetFullMethodName(); + if (parser->HasError()) { + return 1; + } + + if (!FLAGS_input_binary_file.empty()) { + std::cout + << "warning: request given in argv, ignoring --input_binary_file" + << std::endl; + } + } + + if (parser) { + serialized_request_proto = + parser->GetSerializedProto(request_text, true /* is_request */); + if (parser->HasError()) { + return 1; + } + } else if (!FLAGS_input_binary_file.empty()) { + std::ifstream input_file(FLAGS_input_binary_file, + std::ios::in | std::ios::binary); + std::stringstream input_stream; + input_stream << input_file.rdbuf(); + serialized_request_proto = input_stream.str(); + } + std::cout << "connecting to " << server_address << std::endl; + + grpc::string serialized_response_proto; + std::multimap client_metadata; + std::multimap server_initial_metadata, + server_trailing_metadata; + ParseMetadataFlag(&client_metadata); + PrintMetadata(client_metadata, "Sending client initial metadata:"); + grpc::Status s = grpc::testing::CliCall::Call( + channel, method_name, serialized_request_proto, + &serialized_response_proto, client_metadata, &server_initial_metadata, + &server_trailing_metadata); + PrintMetadata(server_initial_metadata, + "Received initial metadata from server:"); + PrintMetadata(server_trailing_metadata, + "Received trailing metadata from server:"); + if (s.ok()) { + std::cout << "Rpc succeeded with OK status" << std::endl; + if (parser) { + grpc::string response_text = parser->GetTextFormat( + serialized_response_proto, false /* is_request */); + if (parser->HasError()) { + return false; + } + output_ss << "Response: \n " << response_text << std::endl; + } + if (!FLAGS_output_binary_file.empty()) { + std::ofstream output_file(FLAGS_output_binary_file, + std::ios::trunc | std::ios::binary); + output_file << serialized_response_proto; + } + } else { + std::cout << "Rpc failed with status code " << s.error_code() + << ", error message: " << s.error_message() << std::endl; + } + + return callback(output_ss.str()); +} + +} // namespace testing +} // namespace grpc diff --git a/test/cpp/util/grpc_tool.h b/test/cpp/util/grpc_tool.h new file mode 100644 index 00000000000..d779737cd5c --- /dev/null +++ b/test/cpp/util/grpc_tool.h @@ -0,0 +1,47 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include + +#include + +namespace grpc { +namespace testing { + +typedef std::function OutputCallback; + +int GrpcToolMainLib(int argc, const char **argv, OutputCallback callback); + +} // namespace testing +} // namespace grpc diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc new file mode 100644 index 00000000000..77c3f3fc24d --- /dev/null +++ b/test/cpp/util/grpc_tool_test.cc @@ -0,0 +1,219 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "test/cpp/util/grpc_tool.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "src/proto/grpc/testing/echo.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/util/string_ref_helper.h" + +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; + +namespace grpc { +namespace testing { + +class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { + public: + Status Echo(ServerContext* context, const EchoRequest* request, + EchoResponse* response) GRPC_OVERRIDE { + if (!context->client_metadata().empty()) { + for (std::multimap::const_iterator + iter = context->client_metadata().begin(); + iter != context->client_metadata().end(); ++iter) { + context->AddInitialMetadata(ToString(iter->first), + ToString(iter->second)); + } + } + context->AddTrailingMetadata("trailing_key", "trailing_value"); + response->set_message(request->message()); + return Status::OK; + } +}; + +class GrpcToolTest : public ::testing::Test { + protected: + GrpcToolTest() {} + + void SetUp() GRPC_OVERRIDE { + int port = grpc_pick_unused_port_or_die(); + server_address_ << "localhost:" << port; + // Setup server + ServerBuilder builder; + builder.AddListeningPort(server_address_.str(), + InsecureServerCredentials()); + builder.RegisterService(&service_); + server_ = builder.BuildAndStart(); + } + + void TearDown() GRPC_OVERRIDE { server_->Shutdown(); } + + void ResetStub() { + channel_ = + CreateChannel(server_address_.str(), InsecureChannelCredentials()); + stub_ = grpc::testing::EchoTestService::NewStub(channel_); + } + + std::shared_ptr channel_; + std::unique_ptr stub_; + std::unique_ptr server_; + std::ostringstream server_address_; + TestServiceImpl service_; + reflection::ProtoServerReflectionPlugin plugin_; +}; + +static bool PrintStream(std::stringstream* ss, const grpc::string& output) { + (*ss) << output << std::endl; + return true; +} + +template +static size_t ArraySize(T& a) { + return ((sizeof(a) / sizeof(*(a))) / + static_cast(!(sizeof(a) % sizeof(*(a))))); +} + +#define USAGE_REGEX "( grpc_cli .+\n){2,10}" + +TEST_F(GrpcToolTest, NoCommand) { + // Test input "grpc_cli" + std::stringstream output_stream; + const char* argv[] = {"grpc_cli"}; + // Exit with 1, print usage instruction in stderr + EXPECT_EXIT( + GrpcToolMainLib( + ArraySize(argv), argv, + std::bind(PrintStream, &output_stream, std::placeholders::_1)), + ::testing::ExitedWithCode(1), "No command specified\n" USAGE_REGEX); + // No output + EXPECT_TRUE(0 == output_stream.tellp()); +} + +TEST_F(GrpcToolTest, InvalidCommand) { + // Test input "grpc_cli" + std::stringstream output_stream; + const char* argv[] = {"grpc_cli", "abc"}; + // Exit with 1, print usage instruction in stderr + EXPECT_EXIT( + GrpcToolMainLib( + ArraySize(argv), argv, + std::bind(PrintStream, &output_stream, std::placeholders::_1)), + ::testing::ExitedWithCode(1), "Invalid command 'abc'\n" USAGE_REGEX); + // No output + EXPECT_TRUE(0 == output_stream.tellp()); +} + +TEST_F(GrpcToolTest, HelpCommand) { + // Test input "grpc_cli help" + std::stringstream output_stream; + const char* argv[] = {"grpc_cli", "help"}; + // Exit with 1, print usage instruction in stderr + EXPECT_EXIT(GrpcToolMainLib(ArraySize(argv), argv, + std::bind(PrintStream, &output_stream, + std::placeholders::_1)), + ::testing::ExitedWithCode(1), USAGE_REGEX); + // No output + EXPECT_TRUE(0 == output_stream.tellp()); +} + +TEST_F(GrpcToolTest, CallCommand) { + // Test input "grpc_cli call Echo" + std::stringstream output_stream; + grpc::string server_address = server_address_.str(); + const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", + "message: 'Hello'"}; + + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + // Expected output: "message: \"Hello\"" + EXPECT_TRUE(NULL != + strstr(output_stream.str().c_str(), "message: \"Hello\"")); +} + +TEST_F(GrpcToolTest, TooFewArguments) { + // Test input "grpc_cli call localhost: Echo "message: 'Hello'" + std::stringstream output_stream; + grpc::string server_address = server_address_.str(); + const char* argv[] = {"grpc_cli", "call", "Echo"}; + + // Exit with 1 + EXPECT_EXIT( + GrpcToolMainLib( + ArraySize(argv), argv, + std::bind(PrintStream, &output_stream, std::placeholders::_1)), + ::testing::ExitedWithCode(1), ".*Wrong number of arguments for call.*"); + // No output + EXPECT_TRUE(0 == output_stream.tellp()); +} + +TEST_F(GrpcToolTest, TooManyArguments) { + // Test input "grpc_cli call localhost: Echo Echo "message: 'Hello'" + std::stringstream output_stream; + grpc::string server_address = server_address_.str(); + const char* argv[] = {"grpc_cli", "call", server_address.c_str(), + "Echo", "Echo", "message: 'Hello'"}; + + // Exit with 1 + EXPECT_EXIT( + GrpcToolMainLib( + ArraySize(argv), argv, + std::bind(PrintStream, &output_stream, std::placeholders::_1)), + ::testing::ExitedWithCode(1), ".*Wrong number of arguments for call.*"); + // No output + EXPECT_TRUE(0 == output_stream.tellp()); +} + +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; + return RUN_ALL_TESTS(); +} diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 4a27a1d8752..f7232a24f32 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -2226,6 +2226,35 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc++", + "grpc++_codegen_proto", + "grpc++_config_proto", + "grpc++_reflection", + "grpc_cli_libs", + "grpc_test_util" + ], + "headers": [ + "src/proto/grpc/testing/echo.grpc.pb.h", + "src/proto/grpc/testing/echo.pb.h", + "src/proto/grpc/testing/echo_messages.grpc.pb.h", + "src/proto/grpc/testing/echo_messages.pb.h", + "test/cpp/util/string_ref_helper.h" + ], + "language": "c++", + "name": "grpc_tool_test", + "src": [ + "test/cpp/util/grpc_tool_test.cc", + "test/cpp/util/string_ref_helper.cc", + "test/cpp/util/string_ref_helper.h" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "grpc", @@ -4466,6 +4495,7 @@ ], "headers": [ "test/cpp/util/cli_call.h", + "test/cpp/util/grpc_tool.h", "test/cpp/util/proto_file_parser.h", "test/cpp/util/proto_reflection_descriptor_database.h" ], @@ -4474,6 +4504,8 @@ "src": [ "test/cpp/util/cli_call.cc", "test/cpp/util/cli_call.h", + "test/cpp/util/grpc_tool.cc", + "test/cpp/util/grpc_tool.h", "test/cpp/util/proto_file_parser.cc", "test/cpp/util/proto_file_parser.h", "test/cpp/util/proto_reflection_descriptor_database.cc", diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index d94301b946b..379833bde5e 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -2269,6 +2269,27 @@ "windows" ] }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "grpc_tool_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, { "args": [], "ci_platforms": [ diff --git a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj index d25c692e3e8..3269bab56fa 100644 --- a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj +++ b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj @@ -148,12 +148,15 @@ + + + diff --git a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters index 4add8ed5e13..cbce2f23120 100644 --- a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters @@ -4,6 +4,9 @@ test\cpp\util + + test\cpp\util + test\cpp\util @@ -15,6 +18,9 @@ test\cpp\util + + test\cpp\util + test\cpp\util diff --git a/vsprojects/vcxproj/test/grpc_cli/grpc_cli.vcxproj b/vsprojects/vcxproj/test/grpc_cli/grpc_cli.vcxproj index 9c8cdc54c25..f9dbe1dcb69 100644 --- a/vsprojects/vcxproj/test/grpc_cli/grpc_cli.vcxproj +++ b/vsprojects/vcxproj/test/grpc_cli/grpc_cli.vcxproj @@ -167,15 +167,15 @@ {86E35862-43E8-F59E-F906-AFE0348AD3D2} + + {5F575402-3F89-5D1A-6910-9DB8BF5D2BAB} + {0BE77741-552A-929B-A497-4EF7ECE17A64} {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} - - {5F575402-3F89-5D1A-6910-9DB8BF5D2BAB} - {C187A093-A0FE-489D-A40A-6E33DE0F9FEB} diff --git a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj new file mode 100644 index 00000000000..c6f65aa30b8 --- /dev/null +++ b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj @@ -0,0 +1,286 @@ + + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {F00D82D4-E988-6D2F-F0B9-9E82BCC2A2B2} + true + $(SolutionDir)IntDir\$(MSBuildProjectName)\ + + + + v100 + + + v110 + + + v120 + + + v140 + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + + + grpc_tool_test + static + Debug + static + Debug + + + grpc_tool_test + static + Release + static + Release + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {86E35862-43E8-F59E-F906-AFE0348AD3D2} + + + {5F575402-3F89-5D1A-6910-9DB8BF5D2BAB} + + + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} + + + {C187A093-A0FE-489D-A40A-6E33DE0F9FEB} + + + {29D16885-7228-4C31-81ED-5F9187C7F2A9} + + + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + + + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + diff --git a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters new file mode 100644 index 00000000000..731eb2e6ffb --- /dev/null +++ b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters @@ -0,0 +1,232 @@ + + + + + src\proto\grpc\testing + + + src\proto\grpc\testing + + + test\cpp\util + + + test\cpp\util + + + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen\security + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc\impl\codegen + + + include\grpc++\impl\codegen + + + + + test\cpp\util + + + + + + {89fed779-17c5-23da-c8a2-9e868ff34480} + + + {96e4a1a8-0b91-1a6d-ae4d-ddf33abb93c0} + + + {1d9dcc6f-7c1b-cdc3-4c35-73d5968dfd92} + + + {5eca7690-973a-c8ed-84d6-5325f8de43ac} + + + {5789073e-5b84-0ec9-af06-47866647874d} + + + {d3f3293f-204f-7771-fcdf-de673f6b06b6} + + + {7e90f37b-f9cc-0725-b2c1-12aa7d4809ba} + + + {7e4b71ef-8125-6446-bfc1-9bc90beed59c} + + + {169774bd-5c6c-6827-66a4-326b4aef44d6} + + + {1b609b37-ef2a-e5eb-e1ba-ad9e79c77438} + + + {cd1e35d8-8a61-62fe-6ce1-c8936872d1ef} + + + {f7ee4df5-1f47-1e7f-c91e-350382c1b729} + + + {f2166b83-6b0b-d53b-b58b-627bd9efcad2} + + + {bbe36cbc-7fbe-2817-0bd0-d03726f323e6} + + + {e106cd7b-cfa0-0645-f1a9-2acedc23afe7} + + + + From 365ef40947e22b5438a63f123679ae9a5474c47c Mon Sep 17 00:00:00 2001 From: siddharthshukla Date: Mon, 25 Jul 2016 21:53:07 +0200 Subject: [PATCH 061/279] Add .idea folder to .gitignore .idea folder is where Project settings are stored with each specific project as a set of xml files. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 09223fa1ead..75a73a1e562 100644 --- a/.gitignore +++ b/.gitignore @@ -99,3 +99,6 @@ artifacts/ # Git generated files for conflicting *.orig + +# IDE specific folder for JetBrains IDEs +.idea/ From 28263275f0ab22d5a9d01f7e5afddbcc24a9d22c Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Mon, 25 Jul 2016 14:38:07 -0700 Subject: [PATCH 062/279] Remove unnecessary dependencies --- Makefile | 7 +++--- build.yaml | 6 ++--- test/cpp/util/grpc_cli.cc | 23 +++++++++++-------- test/cpp/util/grpc_tool.cc | 22 ++++++++++-------- test/cpp/util/grpc_tool.h | 9 ++++---- tools/run_tests/sources_and_headers.json | 13 ++++++----- .../grpc_cli_libs/grpc_cli_libs.vcxproj | 6 +++++ .../grpc_cli_libs.vcxproj.filters | 6 +++++ .../vcxproj/test/grpc_cli/grpc_cli.vcxproj | 9 -------- 9 files changed, 56 insertions(+), 45 deletions(-) diff --git a/Makefile b/Makefile index a1165955a9a..f3a9b2bc7a8 100644 --- a/Makefile +++ b/Makefile @@ -4097,6 +4097,7 @@ LIBGRPC_CLI_LIBS_SRC = \ test/cpp/util/grpc_tool.cc \ test/cpp/util/proto_file_parser.cc \ test/cpp/util/proto_reflection_descriptor_database.cc \ + test/cpp/util/string_ref_helper.cc \ PUBLIC_HEADERS_CXX += \ @@ -11004,16 +11005,16 @@ $(BINDIR)/$(CONFIG)/grpc_cli: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/grpc_cli: $(PROTOBUF_DEP) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/grpc_cli: $(PROTOBUF_DEP) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_cli + $(Q) $(LDXX) $(LDFLAGS) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_cli endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_cli.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_cli.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_grpc_cli: $(GRPC_CLI_OBJS:.o=.dep) diff --git a/build.yaml b/build.yaml index 5b2c5818501..afad1e113c5 100644 --- a/build.yaml +++ b/build.yaml @@ -1032,15 +1032,18 @@ libs: - test/cpp/util/grpc_tool.h - test/cpp/util/proto_file_parser.h - test/cpp/util/proto_reflection_descriptor_database.h + - test/cpp/util/string_ref_helper.h src: - test/cpp/util/cli_call.cc - test/cpp/util/grpc_tool.cc - test/cpp/util/proto_file_parser.cc - test/cpp/util/proto_reflection_descriptor_database.cc + - test/cpp/util/string_ref_helper.cc deps: - grpc++_reflection - grpc++ - grpc_plugin_support + - grpc++_test_config - name: grpc_plugin_support build: protoc language: c++ @@ -2661,11 +2664,8 @@ targets: deps: - grpc_cli_libs - grpc++_reflection - - grpc++_test_util - - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: grpc_cpp_plugin diff --git a/test/cpp/util/grpc_cli.cc b/test/cpp/util/grpc_cli.cc index 28c87956d67..897ac5ce4a0 100644 --- a/test/cpp/util/grpc_cli.cc +++ b/test/cpp/util/grpc_cli.cc @@ -33,19 +33,24 @@ /* A command line tool to talk to a grpc server. + Run `grpc_cli help` command to see its usage information. + Example of talking to grpc interop server: - grpc_cli call localhost:50051 UnaryCall src/proto/grpc/testing/test.proto \ - "response_size:10" --enable_ssl=false + grpc_cli call localhost:50051 UnaryCall "response_size:10" \ + --protofiles=src/proto/grpc/testing/test.proto --enable_ssl=false Options: - 1. --proto_path, if your proto file is not under current working directory, + 1. --protofiles, use this flag to provide a proto file if the server does + does not have the reflection service. + 2. --proto_path, if your proto file is not under current working directory, use this flag to provide a search root. It should work similar to the - counterpart in protoc. - 2. --metadata specifies metadata to be sent to the server, such as: + counterpart in protoc. This option is valid only when protofiles is + provided. + 3. --metadata specifies metadata to be sent to the server, such as: --metadata="MyHeaderKey1:Value1:MyHeaderKey2:Value2" - 3. --enable_ssl, whether to use tls. - 4. --use_auth, if set to true, attach a GoogleDefaultCredentials to the call - 3. --input_binary_file, a file containing the serialized request. The file + 4. --enable_ssl, whether to use tls. + 5. --use_auth, if set to true, attach a GoogleDefaultCredentials to the call + 6. --input_binary_file, a file containing the serialized request. The file can be generated by calling something like: protoc --proto_path=src/proto/grpc/testing/ \ --encode=grpc.testing.SimpleRequest \ @@ -53,7 +58,7 @@ < input.txt > input.bin If this is used and no proto file is provided in the argument list, the method string has to be exact in the form of /package.service/method. - 4. --output_binary_file, a file to write binary format response into, it can + 7. --output_binary_file, a file to write binary format response into, it can be later decoded using protoc: protoc --proto_path=src/proto/grpc/testing/ \ --decode=grpc.testing.SimpleResponse \ diff --git a/test/cpp/util/grpc_tool.cc b/test/cpp/util/grpc_tool.cc index 38ac9e55a03..5b3f565ff50 100644 --- a/test/cpp/util/grpc_tool.cc +++ b/test/cpp/util/grpc_tool.cc @@ -31,7 +31,7 @@ * */ -#include "grpc_tool.h" +#include "test/cpp/util/grpc_tool.h" #include #include @@ -47,7 +47,6 @@ #include #include #include -#include #include "test/cpp/util/cli_call.h" #include "test/cpp/util/proto_file_parser.h" @@ -75,8 +74,8 @@ class GrpcTool { public: explicit GrpcTool(); virtual ~GrpcTool() {} - bool Help(int argc, const char** argv, OutputCallback callback); - bool CallMethod(int argc, const char** argv, OutputCallback callback); + bool Help(int argc, const char** argv, GrpcToolOutputCallback callback); + bool CallMethod(int argc, const char** argv, GrpcToolOutputCallback callback); void SetPrintCommandMode(int exit_status) { print_command_usage_ = true; usage_exit_status_ = exit_status; @@ -89,8 +88,8 @@ class GrpcTool { }; template -std::function BindWith4Args( - T&& func) { +std::function +BindWith4Args(T&& func) { return std::bind(std::forward(func), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4); @@ -143,7 +142,8 @@ void PrintMetadata(const T& m, const grpc::string& message) { struct Command { const char* command; - std::function function; + std::function + function; int min_args; int max_args; }; @@ -186,7 +186,8 @@ const Command* FindCommand(const grpc::string& name) { } } // namespace -int GrpcToolMainLib(int argc, const char** argv, OutputCallback callback) { +int GrpcToolMainLib(int argc, const char** argv, + GrpcToolOutputCallback callback) { if (argc < 2) { Usage("No command specified"); } @@ -222,7 +223,8 @@ void GrpcTool::CommandUsage(const grpc::string& usage) const { } } -bool GrpcTool::Help(int argc, const char** argv, OutputCallback callback) { +bool GrpcTool::Help(int argc, const char** argv, + GrpcToolOutputCallback callback) { CommandUsage( "Print help\n" " grpc_cli help [subcommand]\n"); @@ -241,7 +243,7 @@ bool GrpcTool::Help(int argc, const char** argv, OutputCallback callback) { } bool GrpcTool::CallMethod(int argc, const char** argv, - OutputCallback callback) { + GrpcToolOutputCallback callback) { CommandUsage( "Call method\n" " grpc_cli call
[.] \n" diff --git a/test/cpp/util/grpc_tool.h b/test/cpp/util/grpc_tool.h index d779737cd5c..9e61abf6418 100644 --- a/test/cpp/util/grpc_tool.h +++ b/test/cpp/util/grpc_tool.h @@ -31,17 +31,16 @@ * */ +#include #include -#include - -#include namespace grpc { namespace testing { -typedef std::function OutputCallback; +typedef std::function GrpcToolOutputCallback; -int GrpcToolMainLib(int argc, const char **argv, OutputCallback callback); +int GrpcToolMainLib(int argc, const char **argv, + GrpcToolOutputCallback callback); } // namespace testing } // namespace grpc diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index f7232a24f32..e2d2796184f 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -2130,14 +2130,11 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_reflection", "grpc++_test_config", - "grpc++_test_util", - "grpc_cli_libs", - "grpc_test_util" + "grpc_cli_libs" ], "headers": [], "language": "c++", @@ -4491,13 +4488,15 @@ "deps": [ "grpc++", "grpc++_reflection", + "grpc++_test_config", "grpc_plugin_support" ], "headers": [ "test/cpp/util/cli_call.h", "test/cpp/util/grpc_tool.h", "test/cpp/util/proto_file_parser.h", - "test/cpp/util/proto_reflection_descriptor_database.h" + "test/cpp/util/proto_reflection_descriptor_database.h", + "test/cpp/util/string_ref_helper.h" ], "language": "c++", "name": "grpc_cli_libs", @@ -4509,7 +4508,9 @@ "test/cpp/util/proto_file_parser.cc", "test/cpp/util/proto_file_parser.h", "test/cpp/util/proto_reflection_descriptor_database.cc", - "test/cpp/util/proto_reflection_descriptor_database.h" + "test/cpp/util/proto_reflection_descriptor_database.h", + "test/cpp/util/string_ref_helper.cc", + "test/cpp/util/string_ref_helper.h" ], "third_party": false, "type": "lib" diff --git a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj index 3269bab56fa..59b2923b037 100644 --- a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj +++ b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj @@ -151,6 +151,7 @@ + @@ -161,6 +162,8 @@ + + @@ -172,6 +175,9 @@ {B6E81D84-2ACB-41B8-8781-493A944C7817} + + {3F7D093D-11F9-C4BC-BEB7-18EB28E3F290} + diff --git a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters index cbce2f23120..d400f8eccf2 100644 --- a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters @@ -13,6 +13,9 @@ test\cpp\util + + test\cpp\util + @@ -27,6 +30,9 @@ test\cpp\util + + test\cpp\util + diff --git a/vsprojects/vcxproj/test/grpc_cli/grpc_cli.vcxproj b/vsprojects/vcxproj/test/grpc_cli/grpc_cli.vcxproj index f9dbe1dcb69..78a0a63b5d7 100644 --- a/vsprojects/vcxproj/test/grpc_cli/grpc_cli.vcxproj +++ b/vsprojects/vcxproj/test/grpc_cli/grpc_cli.vcxproj @@ -170,21 +170,12 @@ {5F575402-3F89-5D1A-6910-9DB8BF5D2BAB} - - {0BE77741-552A-929B-A497-4EF7ECE17A64} - - - {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} - {C187A093-A0FE-489D-A40A-6E33DE0F9FEB} {29D16885-7228-4C31-81ED-5F9187C7F2A9} - - {EAB0A629-17A9-44DB-B5FF-E91A721FE037} - {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} From 724a4e253a579f44d6b3d4ab9599f771837d7580 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Mon, 25 Jul 2016 14:56:06 -0700 Subject: [PATCH 063/279] Add header guard --- test/cpp/util/grpc_tool.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/cpp/util/grpc_tool.h b/test/cpp/util/grpc_tool.h index 9e61abf6418..0c7217d962a 100644 --- a/test/cpp/util/grpc_tool.h +++ b/test/cpp/util/grpc_tool.h @@ -31,6 +31,9 @@ * */ +#ifndef GRPC_TEST_CPP_UTIL_GRPC_TOOL_H +#define GRPC_TEST_CPP_UTIL_GRPC_TOOL_H + #include #include @@ -44,3 +47,5 @@ int GrpcToolMainLib(int argc, const char **argv, } // namespace testing } // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_GRPC_TOOL_H From 9be73916dea8eea2795812e0e0345e935143c42e Mon Sep 17 00:00:00 2001 From: Makarand Dharmapurikar Date: Mon, 25 Jul 2016 15:59:01 -0700 Subject: [PATCH 064/279] removed hardcoded disable on logging Removed "false &&" that was (mistakenly?) appended to the trace condition --- src/core/lib/security/transport/secure_endpoint.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/security/transport/secure_endpoint.c b/src/core/lib/security/transport/secure_endpoint.c index bc50f9d1b00..0169ccd9ef9 100644 --- a/src/core/lib/security/transport/secure_endpoint.c +++ b/src/core/lib/security/transport/secure_endpoint.c @@ -128,7 +128,7 @@ static void flush_read_staging_buffer(secure_endpoint *ep, uint8_t **cur, static void call_read_cb(grpc_exec_ctx *exec_ctx, secure_endpoint *ep, grpc_error *error) { - if (false && grpc_trace_secure_endpoint) { + if (grpc_trace_secure_endpoint) { size_t i; for (i = 0; i < ep->read_buffer->count; i++) { char *data = gpr_dump_slice(ep->read_buffer->slices[i], @@ -256,7 +256,7 @@ static void endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *secure_ep, gpr_slice_buffer_reset_and_unref(&ep->output_buffer); - if (false && grpc_trace_secure_endpoint) { + if (grpc_trace_secure_endpoint) { for (i = 0; i < slices->count; i++) { char *data = gpr_dump_slice(slices->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); From 6b86080912d347efd336d9ebba61439cd7950ed6 Mon Sep 17 00:00:00 2001 From: Makarand Dharmapurikar Date: Mon, 25 Jul 2016 16:10:35 -0700 Subject: [PATCH 065/279] fixing issues from cronet end to end testing changed core logic for executing multiple ops. added call cancellation logic simplified the code. --- .../cronet/transport/cronet_transport.c | 373 +++++++++++++----- 1 file changed, 264 insertions(+), 109 deletions(-) diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c index 25d8aca2508..d589d750be3 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.c +++ b/src/core/ext/transport/cronet/transport/cronet_transport.c @@ -65,10 +65,11 @@ typedef struct grpc_cronet_transport grpc_cronet_transport; enum send_state { CRONET_SEND_IDLE = 0, - CRONET_REQ_STARTED, CRONET_SEND_HEADER, - CRONET_WRITE, + CRONET_WRITE_PENDING, CRONET_WRITE_COMPLETED, + CRONET_WAIT_FOR_CANCEL, + CRONET_STREAM_CLOSED, }; enum recv_state { @@ -91,13 +92,14 @@ enum e_caller { }; enum callback_id { - CB_SEND_INITIAL_METADATA = 0, - CB_SEND_MESSAGE, - CB_SEND_TRAILING_METADATA, - CB_RECV_MESSAGE, - CB_RECV_INITIAL_METADATA, - CB_RECV_TRAILING_METADATA, - CB_NUM_CALLBACKS + OP_SEND_INITIAL_METADATA = 0, + OP_SEND_MESSAGE, + OP_SEND_TRAILING_METADATA, + OP_RECV_MESSAGE, + OP_RECV_INITIAL_METADATA, + OP_RECV_TRAILING_METADATA, + OP_CANCEL_ERROR, + OP_NUM_CALLBACKS }; struct stream_obj { @@ -117,23 +119,29 @@ struct stream_obj { // Hold the URL char *url; - bool response_headers_received; - bool read_requested; - bool response_trailers_received; + // One bit per operation + bool op_requested[OP_NUM_CALLBACKS]; + bool op_done[OP_NUM_CALLBACKS]; + // Set to true when server indicates no more data will be sent bool read_closed; // Recv message stuff grpc_byte_buffer **recv_message; // Initial metadata stuff grpc_metadata_batch *recv_initial_metadata; + grpc_chttp2_incoming_metadata_buffer initial_metadata; // Trailing metadata stuff grpc_metadata_batch *recv_trailing_metadata; grpc_chttp2_incoming_metadata_buffer imb; + bool imb_valid; // true if there are any valid entries in imb. // This mutex protects receive state machine execution gpr_mu recv_mu; - // we can queue up up to 2 callbacks for each OP - grpc_closure *callback_list[CB_NUM_CALLBACKS][2]; + + // Callbacks to be called when operations complete + grpc_closure *cb_recv_initial_metadata_ready; + grpc_closure *cb_recv_message_ready; + grpc_closure *on_complete; // storage for header cronet_bidirectional_stream_header *headers; @@ -156,34 +164,63 @@ static void set_pollset_set_do_nothing(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_stream *gs, grpc_pollset_set *pollset_set) {} -static void enqueue_callbacks(grpc_closure *callback_list[]) { - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - if (callback_list[0]) { - grpc_exec_ctx_sched(&exec_ctx, callback_list[0], GRPC_ERROR_NONE, NULL); - callback_list[0] = NULL; +// Client creates a bunch of operations and invokes "call_start_batch" +// call_start_batch creates a stream_op structure. this structure has info +// needed for executing all the ops. It has on_complete callback that needs +// to be called when all ops are executed. This function keeps track of all +// outstanding operations. It returns true if all operations that were part of +// the stream_op have been completed. +static bool is_op_complete(stream_obj *s) { + int i; + // Check if any requested op is pending + for (i = 0; i < OP_NUM_CALLBACKS; i++) { + if (s->op_requested[i] && !s->op_done[i]) { + gpr_log(GPR_DEBUG, "is_op_complete is FALSE because of %d", i); + return false; + } } - if (callback_list[1]) { - grpc_exec_ctx_sched(&exec_ctx, callback_list[1], GRPC_ERROR_NONE, NULL); - callback_list[1] = NULL; + // Clear the requested/done bits and return true + for (i = 0; i < OP_NUM_CALLBACKS; i++) { + s->op_requested[i] = s->op_done[i] = false; } + return true; +} + +static void enqueue_callback(grpc_closure *callback) { + GPR_ASSERT(callback); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_exec_ctx_sched(&exec_ctx, callback, GRPC_ERROR_NONE, NULL); grpc_exec_ctx_finish(&exec_ctx); } static void on_canceled(cronet_bidirectional_stream *stream) { if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "on_canceled %p", stream); + gpr_log(GPR_DEBUG, "on_canceled(%p)", stream); } + stream_obj *s = (stream_obj *)stream->annotation; + s->op_done[OP_CANCEL_ERROR] = true; + + // Terminate any read callback + if (s->cb_recv_message_ready) { + enqueue_callback(s->cb_recv_message_ready); + s->cb_recv_message_ready = 0; + s->op_done[OP_RECV_MESSAGE] = true; + } + // Don't wait to get any trailing metadata + s->op_done[OP_RECV_TRAILING_METADATA] = true; + + next_send_step(s); } static void on_failed(cronet_bidirectional_stream *stream, int net_error) { if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "on_failed %p, error = %d", stream, net_error); + gpr_log(GPR_DEBUG, "on_failed(%p, %d)", stream, net_error); } } static void on_succeeded(cronet_bidirectional_stream *stream) { if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "on_succeeded %p", stream); + gpr_log(GPR_DEBUG, "on_succeeded(%p)", stream); } } @@ -191,31 +228,38 @@ static void on_response_trailers_received( cronet_bidirectional_stream *stream, const cronet_bidirectional_stream_header_array *trailers) { if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "R: on_response_trailers_received"); + gpr_log(GPR_DEBUG, "R: on_response_trailers_received(%p,%p)", stream, + trailers); } stream_obj *s = (stream_obj *)stream->annotation; memset(&s->imb, 0, sizeof(s->imb)); + s->imb_valid = false; grpc_chttp2_incoming_metadata_buffer_init(&s->imb); unsigned int i = 0; for (i = 0; i < trailers->count; i++) { + if (grpc_cronet_trace) { + gpr_log(GPR_DEBUG, "trailer key=%s, value=%s", trailers->headers[i].key, + trailers->headers[i].value); + } + grpc_chttp2_incoming_metadata_buffer_add( &s->imb, grpc_mdelem_from_metadata_strings( grpc_mdstr_from_string(trailers->headers[i].key), grpc_mdstr_from_string(trailers->headers[i].value))); + s->imb_valid = true; } - s->response_trailers_received = true; + s->op_done[OP_RECV_TRAILING_METADATA] = true; next_recv_step(s, ON_RESPONSE_TRAILERS_RECEIVED); } static void on_write_completed(cronet_bidirectional_stream *stream, const char *data) { if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "W: on_write_completed"); + gpr_log(GPR_DEBUG, "W: on_write_completed(%p, %s)", stream, data); } stream_obj *s = (stream_obj *)stream->annotation; - enqueue_callbacks(s->callback_list[CB_SEND_MESSAGE]); - s->cronet_send_state = CRONET_WRITE_COMPLETED; + s->op_done[OP_SEND_MESSAGE] = true; next_send_step(s); } @@ -245,14 +289,14 @@ static void on_read_completed(cronet_bidirectional_stream *stream, char *data, int count) { stream_obj *s = (stream_obj *)stream->annotation; if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "R: on_read_completed count=%d, total=%d, remaining=%d", - count, s->total_read_bytes, s->remaining_read_bytes); + gpr_log(GPR_DEBUG, "R: on_read_completed(%p, %p, %d)", stream, data, count); } if (count > 0) { GPR_ASSERT(s->recv_message); s->remaining_read_bytes -= count; next_recv_step(s, ON_READ_COMPLETE); } else { + gpr_log(GPR_DEBUG, "read_closed = true"); s->read_closed = true; next_recv_step(s, ON_READ_COMPLETE); } @@ -263,21 +307,39 @@ static void on_response_headers_received( const cronet_bidirectional_stream_header_array *headers, const char *negotiated_protocol) { if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "R: on_response_headers_received"); + gpr_log(GPR_DEBUG, "R: on_response_headers_received(%p, %p, %s)", stream, + headers, negotiated_protocol); } stream_obj *s = (stream_obj *)stream->annotation; - enqueue_callbacks(s->callback_list[CB_RECV_INITIAL_METADATA]); - s->response_headers_received = true; + + memset(&s->initial_metadata, 0, sizeof(s->initial_metadata)); + grpc_chttp2_incoming_metadata_buffer_init(&s->initial_metadata); + unsigned int i = 0; + for (i = 0; i < headers->count; i++) { + if (grpc_cronet_trace) { + gpr_log(GPR_DEBUG, "header key=%s, value=%s", headers->headers[i].key, + headers->headers[i].value); + } + grpc_chttp2_incoming_metadata_buffer_add( + &s->initial_metadata, + grpc_mdelem_from_metadata_strings( + grpc_mdstr_from_string(headers->headers[i].key), + grpc_mdstr_from_string(headers->headers[i].value))); + } + + grpc_chttp2_incoming_metadata_buffer_publish(&s->initial_metadata, + s->recv_initial_metadata); + enqueue_callback(s->cb_recv_initial_metadata_ready); + s->op_done[OP_RECV_INITIAL_METADATA] = true; next_recv_step(s, ON_RESPONSE_HEADERS_RECEIVED); } static void on_request_headers_sent(cronet_bidirectional_stream *stream) { if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "W: on_request_headers_sent"); + gpr_log(GPR_DEBUG, "W: on_request_headers_sent(%p)", stream); } stream_obj *s = (stream_obj *)stream->annotation; - enqueue_callbacks(s->callback_list[CB_SEND_INITIAL_METADATA]); - s->cronet_send_state = CRONET_SEND_HEADER; + s->op_done[OP_SEND_INITIAL_METADATA] = true; next_send_step(s); } @@ -293,11 +355,13 @@ static cronet_bidirectional_stream_callback callbacks = { on_canceled}; static void invoke_closing_callback(stream_obj *s) { - grpc_chttp2_incoming_metadata_buffer_publish(&s->imb, - s->recv_trailing_metadata); - if (s->callback_list[CB_RECV_TRAILING_METADATA]) { - enqueue_callbacks(s->callback_list[CB_RECV_TRAILING_METADATA]); + if (!is_op_complete(s)) return; + + if (s->imb_valid) { + grpc_chttp2_incoming_metadata_buffer_publish(&s->imb, + s->recv_trailing_metadata); } + enqueue_callback(s->on_complete); } static void set_recv_state(stream_obj *s, enum recv_state state) { @@ -309,29 +373,35 @@ static void set_recv_state(stream_obj *s, enum recv_state state) { // This is invoked from perform_stream_op, and all on_xxxx callbacks. static void next_recv_step(stream_obj *s, enum e_caller caller) { + // gpr_log(GPR_DEBUG, "locking mutex %p", &s->recv_mu); gpr_mu_lock(&s->recv_mu); switch (s->cronet_recv_state) { case CRONET_RECV_IDLE: if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "cronet_recv_state = CRONET_RECV_IDLE"); + gpr_log(GPR_DEBUG, "cronet_recv_state = CRONET_RECV_IDLE, caller=%d", + caller); } if (caller == PERFORM_STREAM_OP || caller == ON_RESPONSE_HEADERS_RECEIVED) { - if (s->read_closed && s->response_trailers_received) { - invoke_closing_callback(s); + if (s->read_closed && s->op_done[OP_RECV_TRAILING_METADATA]) { set_recv_state(s, CRONET_RECV_CLOSED); - } else if (s->response_headers_received == true && - s->read_requested == true) { + } else if (s->op_done[OP_RECV_INITIAL_METADATA] == true && + s->op_requested[OP_RECV_MESSAGE]) { set_recv_state(s, CRONET_RECV_READ_LENGTH); s->total_read_bytes = s->remaining_read_bytes = GRPC_HEADER_SIZE_IN_BYTES; GPR_ASSERT(s->read_buffer); if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "R: cronet_bidirectional_stream_read()"); + gpr_log(GPR_DEBUG, "R: cronet_bidirectional_stream_read(%p,%p,%d)", + s->cbs, s->read_buffer, s->remaining_read_bytes); } cronet_bidirectional_stream_read(s->cbs, s->read_buffer, s->remaining_read_bytes); } + } else if (caller == ON_RESPONSE_TRAILERS_RECEIVED) { + // We get here when we receive trailers directly, i.e. without + // going through a data read operation. + set_recv_state(s, CRONET_RECV_CLOSED); } break; case CRONET_RECV_READ_LENGTH: @@ -340,8 +410,8 @@ static void next_recv_step(stream_obj *s, enum e_caller caller) { } if (caller == ON_READ_COMPLETE) { if (s->read_closed) { - invoke_closing_callback(s); - enqueue_callbacks(s->callback_list[CB_RECV_MESSAGE]); + enqueue_callback(s->cb_recv_message_ready); + s->op_done[OP_RECV_MESSAGE] = true; set_recv_state(s, CRONET_RECV_CLOSED); } else { GPR_ASSERT(s->remaining_read_bytes == 0); @@ -352,7 +422,8 @@ static void next_recv_step(stream_obj *s, enum e_caller caller) { gpr_realloc(s->read_buffer, (uint32_t)s->remaining_read_bytes); GPR_ASSERT(s->read_buffer); if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "R: cronet_bidirectional_stream_read()"); + gpr_log(GPR_DEBUG, "R: cronet_bidirectional_stream_read(%p,%p,%d)", + s->cbs, s->read_buffer, s->remaining_read_bytes); } if (s->remaining_read_bytes > 0) { cronet_bidirectional_stream_read(s->cbs, (char *)s->read_buffer, @@ -361,8 +432,8 @@ static void next_recv_step(stream_obj *s, enum e_caller caller) { // Calling the closing callback directly since this is a 0 byte read // for an empty message. process_recv_message(s, NULL); - enqueue_callbacks(s->callback_list[CB_RECV_MESSAGE]); - invoke_closing_callback(s); + enqueue_callback(s->cb_recv_message_ready); + s->op_done[OP_RECV_MESSAGE] = true; set_recv_state(s, CRONET_RECV_CLOSED); } } @@ -386,7 +457,8 @@ static void next_recv_step(stream_obj *s, enum e_caller caller) { uint8_t *p = (uint8_t *)s->read_buffer; process_recv_message(s, p); set_recv_state(s, CRONET_RECV_IDLE); - enqueue_callbacks(s->callback_list[CB_RECV_MESSAGE]); + enqueue_callback(s->cb_recv_message_ready); + s->op_done[OP_RECV_MESSAGE] = true; } } break; @@ -396,7 +468,9 @@ static void next_recv_step(stream_obj *s, enum e_caller caller) { GPR_ASSERT(0); // Should not reach here break; } + invoke_closing_callback(s); gpr_mu_unlock(&s->recv_mu); + // gpr_log(GPR_DEBUG, "unlocking mutex %p", &s->recv_mu); } // This function takes the data from s->write_slice_buffer and assembles into @@ -417,27 +491,69 @@ static void create_grpc_frame(stream_obj *s) { // append actual data memcpy(p, raw_data, length); } - -static void do_write(stream_obj *s) { +// Return false if there is no data to write +static bool do_write(stream_obj *s) { gpr_slice_buffer *sb = &s->write_slice_buffer; GPR_ASSERT(sb->count <= 1); if (sb->count > 0) { create_grpc_frame(s); if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "W: cronet_bidirectional_stream_write"); + gpr_log(GPR_DEBUG, "W: cronet_bidirectional_stream_write(%p,%p,%d,%d)", + s->cbs, s->write_buffer, (int)s->write_buffer_size, false); } cronet_bidirectional_stream_write(s->cbs, s->write_buffer, (int)s->write_buffer_size, false); + return true; + } else { + return false; + } +} + +static bool init_cronet_stream(stream_obj *s, grpc_transport *gt) { + GPR_ASSERT(s->cbs == NULL); + grpc_cronet_transport *ct = (grpc_cronet_transport *)gt; + GPR_ASSERT(ct->engine); + if (grpc_cronet_trace) { + gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_create"); + } + s->cbs = cronet_bidirectional_stream_create(ct->engine, s, &callbacks); + GPR_ASSERT(s->cbs); + s->read_closed = false; + + for (int i = 0; i < OP_NUM_CALLBACKS; i++) { + s->op_requested[i] = s->op_done[i] = false; + } + s->cronet_send_state = CRONET_SEND_IDLE; + s->cronet_recv_state = CRONET_RECV_IDLE; +} + +static bool do_close_connection(stream_obj *s) { + s->op_done[OP_SEND_TRAILING_METADATA] = true; + if (s->cbs) { + // Send an "empty" write to the far end to signal that we're done. + // This will induce the server to send down trailers. + if (grpc_cronet_trace) { + gpr_log(GPR_DEBUG, "W: cronet_bidirectional_stream_write length 0"); + } + cronet_bidirectional_stream_write(s->cbs, "abc", 0, true); + return true; + } else { + // We never created a stream. This was probably an empty request. + invoke_closing_callback(s); + return true; } + return false; } // static void next_send_step(stream_obj *s) { + gpr_log(GPR_DEBUG, "next_send_step cronet_send_state=%d", + s->cronet_send_state); switch (s->cronet_send_state) { case CRONET_SEND_IDLE: GPR_ASSERT( s->cbs); // cronet_bidirectional_stream is not initialized yet. - s->cronet_send_state = CRONET_REQ_STARTED; + s->cronet_send_state = CRONET_SEND_HEADER; if (grpc_cronet_trace) { gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_start to %s", s->url); } @@ -447,11 +563,51 @@ static void next_send_step(stream_obj *s) { gpr_free(s->header_array.headers); break; case CRONET_SEND_HEADER: - do_write(s); - s->cronet_send_state = CRONET_WRITE; + if (s->op_requested[OP_CANCEL_ERROR]) { + cronet_bidirectional_stream_cancel(s->cbs); + gpr_log(GPR_DEBUG, "W: cronet_bidirectional_stream_cancel(%p)", s->cbs); + s->cronet_send_state = CRONET_WAIT_FOR_CANCEL; + } else if (do_write(s) == false && + s->op_requested[OP_SEND_TRAILING_METADATA]) { + if (do_close_connection(s)) { + s->cronet_send_state = CRONET_STREAM_CLOSED; + } + } else { + s->cronet_send_state = CRONET_WRITE_PENDING; + } + break; + case CRONET_WRITE_PENDING: + if (s->op_requested[OP_CANCEL_ERROR]) { + cronet_bidirectional_stream_cancel(s->cbs); + gpr_log(GPR_DEBUG, "W: cronet_bidirectional_stream_cancel(%p)", s->cbs); + s->cronet_send_state = CRONET_WAIT_FOR_CANCEL; + } else if (do_write(s) == false && + s->op_requested[OP_SEND_TRAILING_METADATA]) { + if (do_close_connection(s)) { + s->cronet_send_state = CRONET_STREAM_CLOSED; + } + } else { + s->cronet_send_state = CRONET_WRITE_COMPLETED; + } break; case CRONET_WRITE_COMPLETED: - do_write(s); + if (s->op_requested[OP_CANCEL_ERROR]) { + cronet_bidirectional_stream_cancel(s->cbs); + gpr_log(GPR_DEBUG, "W: cronet_bidirectional_stream_cancel(%p)", s->cbs); + s->cronet_send_state = CRONET_WAIT_FOR_CANCEL; + } else if (do_write(s) == false && + s->op_requested[OP_SEND_TRAILING_METADATA]) { + if (do_close_connection(s)) { + s->cronet_send_state = CRONET_STREAM_CLOSED; + } + } + break; + case CRONET_STREAM_CLOSED: + s->cronet_send_state = CRONET_SEND_IDLE; + break; + case CRONET_WAIT_FOR_CANCEL: + invoke_closing_callback(s); + s->cronet_send_state = CRONET_SEND_IDLE; break; default: GPR_ASSERT(0); @@ -493,7 +649,7 @@ static void convert_metadata_to_cronet_headers(grpc_linked_mdelem *head, // Create URL by appending :path value to the hostname gpr_asprintf(&s->url, "https://%s%s", host, value); if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "extracted URL = %s", s->url); + // gpr_log(GPR_DEBUG, "extracted URL = %s", s->url); } continue; } @@ -511,6 +667,13 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_cronet_transport *ct = (grpc_cronet_transport *)gt; GPR_ASSERT(ct->engine); stream_obj *s = (stream_obj *)gs; + // Initialize a cronet bidirectional stream if it doesn't exist. + if (s->cbs == NULL) { + init_cronet_stream(s, gt); + } + + s->on_complete = op->on_complete; + if (op->recv_trailing_metadata) { if (grpc_cronet_trace) { gpr_log(GPR_DEBUG, @@ -518,8 +681,7 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, op->on_complete); } s->recv_trailing_metadata = op->recv_trailing_metadata; - GPR_ASSERT(!s->callback_list[CB_RECV_TRAILING_METADATA][0]); - s->callback_list[CB_RECV_TRAILING_METADATA][0] = op->on_complete; + s->op_requested[OP_RECV_TRAILING_METADATA] = true; } if (op->recv_message) { if (grpc_cronet_trace) { @@ -527,24 +689,19 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, op->on_complete); } s->recv_message = (grpc_byte_buffer **)op->recv_message; - GPR_ASSERT(!s->callback_list[CB_RECV_MESSAGE][0]); - GPR_ASSERT(!s->callback_list[CB_RECV_MESSAGE][1]); - s->callback_list[CB_RECV_MESSAGE][0] = op->recv_message_ready; - s->callback_list[CB_RECV_MESSAGE][1] = op->on_complete; - s->read_requested = true; - next_recv_step(s, PERFORM_STREAM_OP); + s->cb_recv_message_ready = op->recv_message_ready; + s->op_requested[OP_RECV_MESSAGE] = true; } if (op->recv_initial_metadata) { if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "perform_stream_op - recv_initial_metadata:=%p", - op->on_complete); + gpr_log(GPR_DEBUG, + "perform_stream_op - recv_initial_metadata on_complete=%p, " + "on_ready=%p", + op->on_complete, op->recv_initial_metadata_ready); } s->recv_initial_metadata = op->recv_initial_metadata; - GPR_ASSERT(!s->callback_list[CB_RECV_INITIAL_METADATA][0]); - GPR_ASSERT(!s->callback_list[CB_RECV_INITIAL_METADATA][1]); - s->callback_list[CB_RECV_INITIAL_METADATA][0] = - op->recv_initial_metadata_ready; - s->callback_list[CB_RECV_INITIAL_METADATA][1] = op->on_complete; + s->cb_recv_initial_metadata_ready = op->recv_initial_metadata_ready; + s->op_requested[OP_RECV_INITIAL_METADATA] = true; } if (op->send_initial_metadata) { if (grpc_cronet_trace) { @@ -558,8 +715,7 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, s->header_array.count = s->num_headers; s->header_array.capacity = s->num_headers; s->header_array.headers = s->headers; - GPR_ASSERT(!s->callback_list[CB_SEND_INITIAL_METADATA][0]); - s->callback_list[CB_SEND_INITIAL_METADATA][0] = op->on_complete; + s->op_requested[OP_SEND_INITIAL_METADATA] = true; } if (op->send_message) { if (grpc_cronet_trace) { @@ -572,21 +728,7 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, // TODO (makdharma): add compression support GPR_ASSERT(op->send_message->flags == 0); gpr_slice_buffer_add(&s->write_slice_buffer, s->slice); - if (s->cbs == NULL) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_create"); - } - s->cbs = cronet_bidirectional_stream_create(ct->engine, s, &callbacks); - GPR_ASSERT(s->cbs); - s->read_closed = false; - s->response_trailers_received = false; - s->response_headers_received = false; - s->cronet_send_state = CRONET_SEND_IDLE; - s->cronet_recv_state = CRONET_RECV_IDLE; - } - GPR_ASSERT(!s->callback_list[CB_SEND_MESSAGE][0]); - s->callback_list[CB_SEND_MESSAGE][0] = op->on_complete; - next_send_step(s); + s->op_requested[OP_SEND_MESSAGE] = true; } if (op->send_trailing_metadata) { if (grpc_cronet_trace) { @@ -594,27 +736,24 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, "perform_stream_op - send_trailing_metadata: on_complete=%p", op->on_complete); } - GPR_ASSERT(!s->callback_list[CB_SEND_TRAILING_METADATA][0]); - s->callback_list[CB_SEND_TRAILING_METADATA][0] = op->on_complete; - if (s->cbs) { - // Send an "empty" write to the far end to signal that we're done. - // This will induce the server to send down trailers. - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "W: cronet_bidirectional_stream_write"); - } - cronet_bidirectional_stream_write(s->cbs, "abc", 0, true); - } else { - // We never created a stream. This was probably an empty request. - invoke_closing_callback(s); + s->op_requested[OP_SEND_TRAILING_METADATA] = true; + } + if (op->cancel_error) { + if (grpc_cronet_trace) { + gpr_log(GPR_DEBUG, "perform_stream_op - cancel_error: on_complete=%p", + op->on_complete); } + s->op_requested[OP_CANCEL_ERROR] = true; } + next_send_step(s); + next_recv_step(s, PERFORM_STREAM_OP); } static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_stream *gs, grpc_stream_refcount *refcount, const void *server_data) { stream_obj *s = (stream_obj *)gs; - memset(s->callback_list, 0, sizeof(s->callback_list)); + memset(s, 0, sizeof(stream_obj)); s->cbs = NULL; gpr_mu_init(&s->recv_mu); s->read_buffer = gpr_malloc(GRPC_HEADER_SIZE_IN_BYTES); @@ -636,6 +775,7 @@ static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, gpr_free(s->read_buffer); gpr_free(s->write_buffer); gpr_free(s->url); + gpr_log(GPR_DEBUG, "destroying %p", &s->recv_mu); gpr_mu_destroy(&s->recv_mu); if (and_free_memory) { gpr_free(and_free_memory); @@ -650,13 +790,28 @@ static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { } } +static char *get_peer(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { + if (grpc_cronet_trace) { + gpr_log(GPR_DEBUG, "Unimplemented method"); + } + return NULL; +} + +static void perform_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, + grpc_transport_op *op) { + if (grpc_cronet_trace) { + gpr_log(GPR_DEBUG, "Unimplemented method"); + } + return NULL; +} + const grpc_transport_vtable grpc_cronet_vtable = {sizeof(stream_obj), "cronet_http", init_stream, set_pollset_do_nothing, set_pollset_set_do_nothing, perform_stream_op, - NULL, + perform_op, destroy_stream, destroy_transport, - NULL}; + get_peer}; From e7068c836ee7077c9e61d8e6a354420477b610c5 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Mon, 25 Jul 2016 17:30:45 -0700 Subject: [PATCH 066/279] Remove references to string_ref_helper --- Makefile | 1 - build.yaml | 2 -- test/cpp/util/grpc_tool.cc | 1 - tools/run_tests/sources_and_headers.json | 7 ++----- vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj | 3 --- .../vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters | 6 ------ 6 files changed, 2 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index 3f01664b41b..d5b2413ac37 100644 --- a/Makefile +++ b/Makefile @@ -4164,7 +4164,6 @@ LIBGRPC_CLI_LIBS_SRC = \ test/cpp/util/grpc_tool.cc \ test/cpp/util/proto_file_parser.cc \ test/cpp/util/proto_reflection_descriptor_database.cc \ - test/cpp/util/string_ref_helper.cc \ PUBLIC_HEADERS_CXX += \ diff --git a/build.yaml b/build.yaml index 5eff6f197ca..0937d1f6cdf 100644 --- a/build.yaml +++ b/build.yaml @@ -1045,13 +1045,11 @@ libs: - test/cpp/util/grpc_tool.h - test/cpp/util/proto_file_parser.h - test/cpp/util/proto_reflection_descriptor_database.h - - test/cpp/util/string_ref_helper.h src: - test/cpp/util/cli_call.cc - test/cpp/util/grpc_tool.cc - test/cpp/util/proto_file_parser.cc - test/cpp/util/proto_reflection_descriptor_database.cc - - test/cpp/util/string_ref_helper.cc deps: - grpc++_reflection - grpc++ diff --git a/test/cpp/util/grpc_tool.cc b/test/cpp/util/grpc_tool.cc index 5b3f565ff50..e227e6027dc 100644 --- a/test/cpp/util/grpc_tool.cc +++ b/test/cpp/util/grpc_tool.cc @@ -51,7 +51,6 @@ #include "test/cpp/util/proto_file_parser.h" #include "test/cpp/util/proto_reflection_descriptor_database.h" -#include "test/cpp/util/string_ref_helper.h" #include "test/cpp/util/test_config.h" DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls."); diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 21a2da9051a..4b5557dc682 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -4501,8 +4501,7 @@ "test/cpp/util/cli_call.h", "test/cpp/util/grpc_tool.h", "test/cpp/util/proto_file_parser.h", - "test/cpp/util/proto_reflection_descriptor_database.h", - "test/cpp/util/string_ref_helper.h" + "test/cpp/util/proto_reflection_descriptor_database.h" ], "language": "c++", "name": "grpc_cli_libs", @@ -4514,9 +4513,7 @@ "test/cpp/util/proto_file_parser.cc", "test/cpp/util/proto_file_parser.h", "test/cpp/util/proto_reflection_descriptor_database.cc", - "test/cpp/util/proto_reflection_descriptor_database.h", - "test/cpp/util/string_ref_helper.cc", - "test/cpp/util/string_ref_helper.h" + "test/cpp/util/proto_reflection_descriptor_database.h" ], "third_party": false, "type": "lib" diff --git a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj index 59b2923b037..09034dc33ef 100644 --- a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj +++ b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj @@ -151,7 +151,6 @@ - @@ -162,8 +161,6 @@ - - diff --git a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters index d400f8eccf2..cbce2f23120 100644 --- a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters @@ -13,9 +13,6 @@ test\cpp\util - - test\cpp\util - @@ -30,9 +27,6 @@ test\cpp\util - - test\cpp\util - From 636ef6fb63fb6873a302797376674abbf6d2d4d7 Mon Sep 17 00:00:00 2001 From: Makarand Dharmapurikar Date: Tue, 26 Jul 2016 10:15:26 -0700 Subject: [PATCH 067/279] minor compiler warning fix --- src/core/ext/transport/cronet/transport/cronet_transport.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c index d589d750be3..0a079927ea8 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.c +++ b/src/core/ext/transport/cronet/transport/cronet_transport.c @@ -509,7 +509,7 @@ static bool do_write(stream_obj *s) { } } -static bool init_cronet_stream(stream_obj *s, grpc_transport *gt) { +static void init_cronet_stream(stream_obj *s, grpc_transport *gt) { GPR_ASSERT(s->cbs == NULL); grpc_cronet_transport *ct = (grpc_cronet_transport *)gt; GPR_ASSERT(ct->engine); @@ -802,7 +802,6 @@ static void perform_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, if (grpc_cronet_trace) { gpr_log(GPR_DEBUG, "Unimplemented method"); } - return NULL; } const grpc_transport_vtable grpc_cronet_vtable = {sizeof(stream_obj), From 8c7618e88d6a272e17fc67072f6700e0dc4080ab Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Tue, 26 Jul 2016 10:30:36 -0700 Subject: [PATCH 068/279] Fix memory overwrite in proto decding; fix test for windows --- src/core/ext/census/resource.c | 6 ++++-- test/core/census/resource_test.c | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/core/ext/census/resource.c b/src/core/ext/census/resource.c index 905de2d63da..63bfb75b47d 100644 --- a/src/core/ext/census/resource.c +++ b/src/core/ext/census/resource.c @@ -156,9 +156,11 @@ static bool validate_units_helper(pb_istream_t *stream, int *count, gpr_free(*bup); } *bup = new_bup; - if (!pb_decode_varint(stream, (uint64_t *)(*bup + *count - 1))) { + uint64_t value; + if (!pb_decode_varint(stream, &value)) { return false; } + *(*bup + *count - 1) = (google_census_Resource_BasicUnit)value; } return true; } @@ -290,7 +292,7 @@ int32_t define_resource(const resource *base) { resources[id]->name = gpr_malloc(len); memcpy(resources[id]->name, base->name, len); if (base->description) { - len = strlen(base->description); + len = strlen(base->description) + 1; resources[id]->description = gpr_malloc(len); memcpy(resources[id]->description, base->description, len); } diff --git a/test/core/census/resource_test.c b/test/core/census/resource_test.c index 1375d56a6bc..e1556d7d7b0 100644 --- a/test/core/census/resource_test.c +++ b/test/core/census/resource_test.c @@ -66,10 +66,10 @@ static void test_empty_definition() { static int32_t define_resource_from_file(const char *file) { #define BUF_SIZE 512 uint8_t buffer[BUF_SIZE]; - FILE *input = fopen(file, "r"); + FILE *input = fopen(file, "rb"); GPR_ASSERT(input != NULL); size_t nbytes = fread(buffer, 1, BUF_SIZE, input); - GPR_ASSERT(nbytes != 0 && nbytes < BUF_SIZE); + GPR_ASSERT(nbytes != 0 && nbytes < BUF_SIZE && feof(input) && !ferror(input)); int32_t rid = census_define_resource(buffer, nbytes); GPR_ASSERT(fclose(input) == 0); return rid; From 41482d8f2772dd63006c9001982236402b83fac8 Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Tue, 26 Jul 2016 12:05:23 -0700 Subject: [PATCH 069/279] Fix comment typo --- src/core/ext/census/resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/census/resource.c b/src/core/ext/census/resource.c index 63bfb75b47d..7015ad6c33e 100644 --- a/src/core/ext/census/resource.c +++ b/src/core/ext/census/resource.c @@ -186,7 +186,7 @@ static bool validate_units(pb_istream_t *stream, const pb_field_t *field, return true; } -// Vlaidate the contents of a Resource proto. `id` is the intended resource id. +// Validate the contents of a Resource proto. `id` is the intended resource id. static bool validate_resource_pb(const uint8_t *resource_pb, size_t resource_pb_size, size_t id) { GPR_ASSERT(id < n_resources); From f4046cdcedbe6be6de173139f4217b34dc876fdd Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Tue, 26 Jul 2016 12:22:42 -0700 Subject: [PATCH 070/279] Fix thread leak --- test/cpp/util/grpc_tool_test.cc | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc index 77c3f3fc24d..57eeed7234a 100644 --- a/test/cpp/util/grpc_tool_test.cc +++ b/test/cpp/util/grpc_tool_test.cc @@ -79,29 +79,25 @@ class GrpcToolTest : public ::testing::Test { protected: GrpcToolTest() {} - void SetUp() GRPC_OVERRIDE { + // SetUpServer cannot be used with EXPECT_EXIT. grpc_pick_unused_port_or_die() + // uses atexit() to free chosen ports, and it will spawn a new thread in + // resolve_address_posix.c:192 at exit time. + const grpc::string SetUpServer() { + std::ostringstream server_address; int port = grpc_pick_unused_port_or_die(); - server_address_ << "localhost:" << port; + server_address << "localhost:" << port; // Setup server ServerBuilder builder; - builder.AddListeningPort(server_address_.str(), + builder.AddListeningPort(server_address.str(), InsecureServerCredentials()); builder.RegisterService(&service_); server_ = builder.BuildAndStart(); + return server_address.str(); } - void TearDown() GRPC_OVERRIDE { server_->Shutdown(); } + void ShutdownServer() { server_->Shutdown(); } - void ResetStub() { - channel_ = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); - stub_ = grpc::testing::EchoTestService::NewStub(channel_); - } - - std::shared_ptr channel_; - std::unique_ptr stub_; std::unique_ptr server_; - std::ostringstream server_address_; TestServiceImpl service_; reflection::ProtoServerReflectionPlugin plugin_; }; @@ -163,7 +159,8 @@ TEST_F(GrpcToolTest, HelpCommand) { TEST_F(GrpcToolTest, CallCommand) { // Test input "grpc_cli call Echo" std::stringstream output_stream; - grpc::string server_address = server_address_.str(); + + const grpc::string server_address = SetUpServer(); const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", "message: 'Hello'"}; @@ -173,12 +170,12 @@ TEST_F(GrpcToolTest, CallCommand) { // Expected output: "message: \"Hello\"" EXPECT_TRUE(NULL != strstr(output_stream.str().c_str(), "message: \"Hello\"")); + ShutdownServer(); } TEST_F(GrpcToolTest, TooFewArguments) { // Test input "grpc_cli call localhost: Echo "message: 'Hello'" std::stringstream output_stream; - grpc::string server_address = server_address_.str(); const char* argv[] = {"grpc_cli", "call", "Echo"}; // Exit with 1 @@ -194,8 +191,7 @@ TEST_F(GrpcToolTest, TooFewArguments) { TEST_F(GrpcToolTest, TooManyArguments) { // Test input "grpc_cli call localhost: Echo Echo "message: 'Hello'" std::stringstream output_stream; - grpc::string server_address = server_address_.str(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), + const char* argv[] = {"grpc_cli", "call", "localhost:10000", "Echo", "Echo", "message: 'Hello'"}; // Exit with 1 From f183ece782c11791b76423c06d410f024f13706f Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Tue, 26 Jul 2016 13:46:16 -0700 Subject: [PATCH 071/279] Full path names for header inclusion --- src/core/ext/census/base_resources.c | 4 ++-- src/core/ext/census/initialize.c | 4 ++-- src/core/ext/census/resource.c | 2 +- src/core/ext/census/resource.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/ext/census/base_resources.c b/src/core/ext/census/base_resources.c index f1ee41c5d97..f9aa4bb9945 100644 --- a/src/core/ext/census/base_resources.c +++ b/src/core/ext/census/base_resources.c @@ -30,7 +30,7 @@ * */ -#include "base_resources.h" +#include "src/core/ext/census/base_resources.h" #include #include @@ -38,7 +38,7 @@ #include #include -#include "resource.h" +#include "src/core/ext/census/resource.h" // Add base RPC resource definitions for use by RPC runtime. // diff --git a/src/core/ext/census/initialize.c b/src/core/ext/census/initialize.c index 118163512ad..55cbbe8e959 100644 --- a/src/core/ext/census/initialize.c +++ b/src/core/ext/census/initialize.c @@ -32,8 +32,8 @@ */ #include -#include "base_resources.h" -#include "resource.h" +#include "src/core/ext/census/base_resources.h" +#include "src/core/ext/census/resource.h" static int features_enabled = CENSUS_FEATURE_NONE; diff --git a/src/core/ext/census/resource.c b/src/core/ext/census/resource.c index 7015ad6c33e..ed44f004f91 100644 --- a/src/core/ext/census/resource.c +++ b/src/core/ext/census/resource.c @@ -31,7 +31,7 @@ * */ -#include "resource.h" +#include "src/core/ext/census/resource.h" #include "third_party/nanopb/pb_decode.h" #include diff --git a/src/core/ext/census/resource.h b/src/core/ext/census/resource.h index a0669f3a39b..591bff07da5 100644 --- a/src/core/ext/census/resource.h +++ b/src/core/ext/census/resource.h @@ -36,7 +36,7 @@ #define GRPC_CORE_EXT_CENSUS_RESOURCE_H #include -#include "gen/census.pb.h" +#include "src/core/ext/census/gen/census.pb.h" /* Internal representation of a resource. */ typedef struct { From 2f7060bad91c4e3f89b5e3c6818edb810b5058ca Mon Sep 17 00:00:00 2001 From: Makarand Dharmapurikar Date: Tue, 26 Jul 2016 16:03:28 -0700 Subject: [PATCH 072/279] test harness changes for compiling --- .../CoreCronetEnd2EndTests.m | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m index 58abb492cea..d2181120e93 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m @@ -77,7 +77,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( gpr_malloc(sizeof(fullstack_secure_fixture_data)); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + gpr_join_host_port(&ffd->localaddr, "127.0.0.1", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create(NULL); @@ -124,15 +124,24 @@ static void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { } static void cronet_init_client_simple_ssl_secure_fullstack( - grpc_end2end_test_fixture *f, grpc_channel_args *client_args) { + grpc_end2end_test_fixture *f, grpc_channel_args *client_args) { grpc_arg ssl_name_override = {GRPC_ARG_STRING, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, {"foo.test.google.fr"}}; grpc_channel_args *new_client_args = grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1); - [Cronet setHttp2Enabled:YES]; - [Cronet start]; + static bool done = false; + // TODO (makdharma): DO NOT CHECK IN THIS HACK!!! + if (!done) { + done = true; + [Cronet setHttp2Enabled:YES]; + NSURL *url = [[[NSFileManager defaultManager] + URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; + NSLog(@"Documents directory: %@", url); + [Cronet start]; + [Cronet startNetLogToFile: @"Documents/cronet_netlog.json" logBytes:YES]; + } cronet_engine *cronetEngine = [Cronet getGlobalEngine]; cronet_init_client_secure_fullstack(f, new_client_args, cronetEngine); @@ -236,7 +245,7 @@ static char *roots_filename; } - (void)testBinaryMetadata { - [self testIndividualCase:"binary_metadata"]; + //[self testIndividualCase:"binary_metadata"]; } - (void)testCallCreds { From 68ca3511264c8af56d70f7576ae84dc296e29989 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Tue, 26 Jul 2016 16:48:46 -0700 Subject: [PATCH 073/279] Fix sanity issues --- test/cpp/util/grpc_tool_test.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc index 57eeed7234a..0f3086b4428 100644 --- a/test/cpp/util/grpc_tool_test.cc +++ b/test/cpp/util/grpc_tool_test.cc @@ -88,8 +88,7 @@ class GrpcToolTest : public ::testing::Test { server_address << "localhost:" << port; // Setup server ServerBuilder builder; - builder.AddListeningPort(server_address.str(), - InsecureServerCredentials()); + builder.AddListeningPort(server_address.str(), InsecureServerCredentials()); builder.RegisterService(&service_); server_ = builder.BuildAndStart(); return server_address.str(); From 05d73af3d18ec301d2778f343edd1cae7d4acd1a Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 27 Jul 2016 15:52:46 +0000 Subject: [PATCH 074/279] Fixed asan failure and some refcounting bugs. --- src/core/ext/client_config/subchannel_call_holder.c | 2 +- src/core/lib/channel/channel_stack.c | 9 +++++++-- src/core/lib/channel/connected_channel.c | 2 +- src/core/lib/surface/call.c | 2 +- test/core/end2end/tests/filter_call_init_fails.c | 6 ++++-- third_party/protobuf | 2 +- 6 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/core/ext/client_config/subchannel_call_holder.c b/src/core/ext/client_config/subchannel_call_holder.c index ac286825f68..be6d054af4e 100644 --- a/src/core/ext/client_config/subchannel_call_holder.c +++ b/src/core/ext/client_config/subchannel_call_holder.c @@ -170,7 +170,7 @@ retry: &subchannel_call); if (error != GRPC_ERROR_NONE) { subchannel_call = CANCELLED_CALL; - fail_locked(exec_ctx, holder, error); + fail_locked(exec_ctx, holder, GRPC_ERROR_REF(error)); grpc_transport_stream_op_finish_with_failure(exec_ctx, op, error); } gpr_atm_rel_store(&holder->subchannel_call, diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c index 70062e0c3b0..7fcc0ef97f4 100644 --- a/src/core/lib/channel/channel_stack.c +++ b/src/core/lib/channel/channel_stack.c @@ -189,8 +189,13 @@ grpc_error *grpc_call_stack_init(grpc_exec_ctx *exec_ctx, call_elems[i].call_data = user_data; grpc_error *error = call_elems[i].filter->init_call_elem(exec_ctx, &call_elems[i], &args); - if (error != GRPC_ERROR_NONE && first_error == GRPC_ERROR_NONE) - first_error = error; + if (error != GRPC_ERROR_NONE) { + if (first_error == GRPC_ERROR_NONE) { + first_error = error; + } else { + GRPC_ERROR_UNREF(error); + } + } user_data += ROUND_UP_TO_ALIGNMENT_SIZE(call_elems[i].filter->sizeof_call_data); } diff --git a/src/core/lib/channel/connected_channel.c b/src/core/lib/channel/connected_channel.c index ecafcc99c79..bad1c50a71c 100644 --- a/src/core/lib/channel/connected_channel.c +++ b/src/core/lib/channel/connected_channel.c @@ -90,7 +90,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, exec_ctx, chand->transport, TRANSPORT_STREAM_FROM_CALL_DATA(calld), &args->call_stack->refcount, args->server_transport_data); return r == 0 ? GRPC_ERROR_NONE - : GRPC_ERROR_CREATE("transport initialization failed"); + : GRPC_ERROR_CREATE("transport stream initialization failed"); } static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 345698092a0..b3bf1427a3e 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -274,7 +274,7 @@ grpc_call *grpc_call_create( grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION); close_with_status(&exec_ctx, call, (grpc_status_code)status, error_str == NULL ? "unknown error" : error_str); - grpc_error_unref(error); + GRPC_ERROR_UNREF(error); } if (cq != NULL) { GPR_ASSERT( diff --git a/test/core/end2end/tests/filter_call_init_fails.c b/test/core/end2end/tests/filter_call_init_fails.c index 4980b372784..08c377a281c 100644 --- a/test/core/end2end/tests/filter_call_init_fails.c +++ b/test/core/end2end/tests/filter_call_init_fails.c @@ -246,8 +246,10 @@ static bool maybe_add_filter(grpc_channel_stack_builder *builder, void *arg) { grpc_channel_stack_builder_iterator *it = grpc_channel_stack_builder_create_iterator_at_last(builder); GPR_ASSERT(grpc_channel_stack_builder_move_prev(it)); - return grpc_channel_stack_builder_add_filter_before(it, &test_filter, NULL, - NULL); + const bool retval = grpc_channel_stack_builder_add_filter_before( + it, &test_filter, NULL, NULL); + grpc_channel_stack_builder_iterator_destroy(it); + return retval; } else { return true; } diff --git a/third_party/protobuf b/third_party/protobuf index bdeb215cab2..a1938b2aa9c 160000 --- a/third_party/protobuf +++ b/third_party/protobuf @@ -1 +1 @@ -Subproject commit bdeb215cab2985195325fcd5e70c3fa751f46e0f +Subproject commit a1938b2aa9ca86ce7ce50c27ff9737c1008d2a03 From f9eef0bfd32e4a9b18c6fcdb5f73b40baec792e9 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 27 Jul 2016 17:05:37 +0000 Subject: [PATCH 075/279] Undo accidental revert to old version of protobuf code. --- third_party/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/protobuf b/third_party/protobuf index a1938b2aa9c..ba52f2b6780 160000 --- a/third_party/protobuf +++ b/third_party/protobuf @@ -1 +1 @@ -Subproject commit a1938b2aa9ca86ce7ce50c27ff9737c1008d2a03 +Subproject commit ba52f2b6780fa5e6bee86cf7e8ee6f6ba617862c From 9fd00425c50800906f4deb2c5aafa9b64217b54c Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 27 Jul 2016 18:36:26 +0000 Subject: [PATCH 076/279] Yet another attempt to undo my protobuf version screw-up. --- third_party/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/protobuf b/third_party/protobuf index ba52f2b6780..bdeb215cab2 160000 --- a/third_party/protobuf +++ b/third_party/protobuf @@ -1 +1 @@ -Subproject commit ba52f2b6780fa5e6bee86cf7e8ee6f6ba617862c +Subproject commit bdeb215cab2985195325fcd5e70c3fa751f46e0f From 2a5072e80f80a4a668ddc89180b6e1b344cb3a6b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 27 Jul 2016 15:10:22 -0700 Subject: [PATCH 077/279] Fix Objective-C test pods for Cronet tests --- gRPC-Core.podspec | 10 +++++-- .../GRPCClient/private/GRPCChannel.h | 4 +-- src/objective-c/tests/Podfile | 30 ++++++++----------- templates/gRPC-Core.podspec.template | 10 +++++-- 4 files changed, 29 insertions(+), 25 deletions(-) diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 10e9d00d707..50fc9e9e7d7 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -770,12 +770,16 @@ Pod::Spec.new do |s| ss.source_files = 'include/grpc/grpc_cronet.h' end + s.subspec 'Cronet-Implement' do |ss| + ss.header_mappings_dir = '.' + ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c', + 'src/core/ext/transport/cronet/transport/cronet_transport.c' + end + s.subspec 'Cronet-Tests' do |ss| ss.header_mappings_dir = '.' - ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c', - 'src/core/ext/transport/cronet/transport/cronet_transport.c', - 'test/core/end2end/cq_verifier.{c,h}', + ss.source_files = 'test/core/end2end/cq_verifier.{c,h}', 'test/core/end2end/end2end_tests.{c,h}', 'test/core/end2end/tests/*.{c,h}', 'test/core/end2end/data/*.{c,h}', diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 40e78a92d6d..5bada2dd50c 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -59,8 +59,8 @@ struct grpc_channel_credentials; * Creates a secure channel to the specified @c host using Cronet as a transport mechanism. */ #ifdef GRPC_COMPILE_WITH_CRONET -+ (nullable GRPCChannel *)secureCronetChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *)channelArgs; ++ (nullable GRPCChannel *)secureCronetChannelWithHost:(nonnull NSString *)host + channelArgs:(nonnull NSDictionary *)channelArgs; #endif /** * Creates a secure channel to the specified @c host using the specified @c credentials and diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 3d0664a04f5..1db7321d212 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -14,6 +14,7 @@ GRPC_LOCAL_SRC = '../../..' InteropTestsRemote InteropTestsLocalSSL InteropTestsLocalCleartext + InteropTestsRemoteWithCronet ).each do |target_name| target target_name do pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true @@ -28,6 +29,11 @@ GRPC_LOCAL_SRC = '../../..' pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC pod 'RemoteTest', :path => "RemoteTestClient" + + if target_name == 'InteropTestsRemoteWithCronet' + pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" + pod 'gRPC-Core/Cronet-Implement', :path => GRPC_LOCAL_SRC + end end end @@ -36,25 +42,10 @@ target 'CoreCronetEnd2EndTests' do pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" pod 'gRPC-Core', :path => GRPC_LOCAL_SRC pod 'gRPC-Core/Cronet-Interface', :path => GRPC_LOCAL_SRC + pod 'gRPC-Core/Cronet-Implement', :path => GRPC_LOCAL_SRC pod 'gRPC-Core/Cronet-Tests', :path => GRPC_LOCAL_SRC end -target 'InteropTestsRemoteWithCronet' do - pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true - - pod '!ProtoCompiler', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" - pod '!ProtoCompiler-gRPCPlugin', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" - - pod 'BoringSSL', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true - pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" - - pod 'gRPC', :path => GRPC_LOCAL_SRC - pod 'gRPC-Core', :path => GRPC_LOCAL_SRC - pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC - pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC - pod 'RemoteTest', :path => "RemoteTestClient" -end - # gRPC-Core.podspec needs to be modified to be successfully used for local development. A Podfile's # pre_install hook lets us do that. The block passed to it runs after the podspecs are downloaded # and before they are installed in the user project. @@ -91,7 +82,7 @@ post_install do |installer| target.build_configurations.each do |config| config.build_settings['GCC_TREAT_WARNINGS_AS_ERRORS'] = 'YES' end - if target.name == 'gRPC-Core' or target.name == 'gRPC-Core.default-Cronet-Interface-Cronet-Tests' + if target.name == 'gRPC-Core' or target.name == 'gRPC-Core.default-Cronet-Implement-Cronet-Interface-Cronet-Tests' or target.name == 'gRPC-Core.default-Cronet-Implement' target.build_configurations.each do |config| # TODO(zyc): Remove this setting after the issue is resolved # GPR_UNREACHABLE_CODE causes "Control may reach end of non-void @@ -99,5 +90,10 @@ post_install do |installer| config.build_settings['GCC_WARN_ABOUT_RETURN_TYPE'] = 'NO' end end + if target.name == 'gRPC' + target.build_configurations.each do |config| + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_COMPILE_WITH_CRONET=1' + end + end end end diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index 12d06a7c8d9..6dd73414b6d 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -162,12 +162,16 @@ ss.source_files = 'include/grpc/grpc_cronet.h' end + s.subspec 'Cronet-Implement' do |ss| + ss.header_mappings_dir = '.' + ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c', + 'src/core/ext/transport/cronet/transport/cronet_transport.c' + end + s.subspec 'Cronet-Tests' do |ss| ss.header_mappings_dir = '.' - ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c', - 'src/core/ext/transport/cronet/transport/cronet_transport.c', - 'test/core/end2end/cq_verifier.{c,h}', + ss.source_files = 'test/core/end2end/cq_verifier.{c,h}', 'test/core/end2end/end2end_tests.{c,h}', 'test/core/end2end/tests/*.{c,h}', 'test/core/end2end/data/*.{c,h}', From f9d8e9064ba9aa20c944441f4890866ff3b98141 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 28 Jul 2016 09:31:56 -0700 Subject: [PATCH 078/279] Code review changes. --- src/core/lib/channel/context.h | 14 +++++++------- src/cpp/common/channel_filter.cc | 10 +--------- src/cpp/common/channel_filter.h | 27 ++++++++++++++++++++------- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/core/lib/channel/context.h b/src/core/lib/channel/context.h index 22f4cb62f3b..071c5f695c5 100644 --- a/src/core/lib/channel/context.h +++ b/src/core/lib/channel/context.h @@ -34,17 +34,17 @@ #ifndef GRPC_CORE_LIB_CHANNEL_CONTEXT_H #define GRPC_CORE_LIB_CHANNEL_CONTEXT_H -// Call object context pointers. +/// Call object context pointers. -// Call context is represented as an array of grpc_call_context_elements. -// This enum represents the indexes into the array, where each index -// contains a different type of value. +/// Call context is represented as an array of \a grpc_call_context_elements. +/// This enum represents the indexes into the array, where each index +/// contains a different type of value. typedef enum { - // Value is either a grpc_client_security_context or a - // grpc_server_security_context. + /// Value is either a \a grpc_client_security_context or a + /// \a grpc_server_security_context. GRPC_CONTEXT_SECURITY = 0, - // Value is a census_context. + /// Value is a \a census_context. GRPC_CONTEXT_TRACING, GRPC_CONTEXT_COUNT diff --git a/src/cpp/common/channel_filter.cc b/src/cpp/common/channel_filter.cc index 8a4149bbcae..25cd49cb7c9 100644 --- a/src/cpp/common/channel_filter.cc +++ b/src/cpp/common/channel_filter.cc @@ -38,9 +38,7 @@ namespace grpc { -// // MetadataBatch -// grpc_linked_mdelem *MetadataBatch::AddMetadata(const string &key, const string &value) { @@ -51,9 +49,7 @@ grpc_linked_mdelem *MetadataBatch::AddMetadata(const string &key, return storage; } -// // ChannelData -// void ChannelData::StartTransportOp(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, @@ -61,9 +57,7 @@ void ChannelData::StartTransportOp(grpc_exec_ctx *exec_ctx, grpc_channel_next_op(exec_ctx, elem, op->op()); } -// // CallData -// void CallData::StartTransportStreamOp(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, @@ -81,9 +75,7 @@ char *CallData::GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { return grpc_call_next_get_peer(exec_ctx, elem); } -// -// RegisterChannelFilter() -// +// internal code used by RegisterChannelFilter() namespace internal { diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h index f3cbdb6224c..6a405f567c0 100644 --- a/src/cpp/common/channel_filter.h +++ b/src/cpp/common/channel_filter.h @@ -47,7 +47,6 @@ #include "src/core/lib/surface/channel_init.h" #include "src/core/lib/transport/metadata_batch.h" -/// /// An interface to define filters. /// /// To define a filter, implement a subclass of each of \c CallData and @@ -56,20 +55,22 @@ /// RegisterChannelFilter( /// "name-of-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr); /// \endcode -/// namespace grpc { /// A C++ wrapper for the \c grpc_metadata_batch struct. class MetadataBatch { public: + /// Borrows a pointer to \a batch, but does NOT take ownership. + /// The caller must ensure that \a batch continues to exist for as + /// long as the MetadataBatch object does. explicit MetadataBatch(grpc_metadata_batch *batch) : batch_(batch) {} grpc_metadata_batch *batch() const { return batch_; } - // Adds metadata and returns the newly allocated storage. - // The caller takes ownership of the result, which must exist for the - // lifetime of the gRPC call. + /// Adds metadata and returns the newly allocated storage. + /// The caller takes ownership of the result, which must exist for the + /// lifetime of the gRPC call. grpc_linked_mdelem *AddMetadata(const string &key, const string &value); class const_iterator : public std::iteratorsend_initial_metadata), @@ -185,7 +192,7 @@ class TransportStreamOp { op_->send_message = send_message; } - // To be called only on clients and servers, respectively. + /// To be called only on clients and servers, respectively. grpc_client_security_context *client_security_context() const { return (grpc_client_security_context *)op_->context[GRPC_CONTEXT_SECURITY] .value; @@ -214,7 +221,7 @@ class ChannelData { if (peer_) gpr_free((void *)peer_); } - // Caller does NOT take ownership of result. + /// Caller does NOT take ownership of result. const char *peer() const { return peer_; } // TODO(roth): Find a way to avoid passing elem into these methods. @@ -234,18 +241,22 @@ class CallData { public: virtual ~CallData() {} + /// Initializes the call data. virtual grpc_error *Init() { return GRPC_ERROR_NONE; } // TODO(roth): Find a way to avoid passing elem into these methods. + /// Starts a new stream operation. virtual void StartTransportStreamOp(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, TransportStreamOp *op); + /// Sets a pollset or pollset set. virtual void SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_polling_entity *pollent); + /// Gets the peer name. virtual char *GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem); protected: @@ -255,6 +266,8 @@ class CallData { namespace internal { // Defines static members for passing to C core. +// Members of this class correspond to the members of the C +// grpc_channel_filter struct. template class ChannelFilter GRPC_FINAL { public: From 5d65eb6bbe237c2df71de61719c4372a366b0548 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 28 Jul 2016 14:49:52 -0700 Subject: [PATCH 079/279] Build the Node health-check package in the build_packages script --- tools/run_tests/build_package_node.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/run_tests/build_package_node.sh b/tools/run_tests/build_package_node.sh index ef4a10cca72..f20daeaea09 100755 --- a/tools/run_tests/build_package_node.sh +++ b/tools/run_tests/build_package_node.sh @@ -49,7 +49,12 @@ cp grpc-*.tgz $artifacts/grpc.tgz mkdir -p bin -cd src/node/tools +cd $base/src/node/health_check +npm update +npm pack +cp grpc-health-check-*.tgz $artifacts/ + +cd $base/src/node/tools npm update npm pack cp grpc-tools-*.tgz $artifacts/ From 6af4addd55a2a80768c63f0079b4c4ccf855bdda Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Thu, 28 Jul 2016 23:05:18 -0700 Subject: [PATCH 080/279] Let override default response size limit Still missing: Catch the C-library error to improve the error message. --- .../GRPCClient/GRPCCall+ChannelArg.h | 4 +- .../GRPCClient/GRPCCall+ChannelArg.m | 11 ++-- src/objective-c/GRPCClient/GRPCCall+Tests.h | 6 ++ src/objective-c/GRPCClient/GRPCCall+Tests.m | 3 + .../GRPCClient/private/GRPCChannel.m | 16 +++-- src/objective-c/GRPCClient/private/GRPCHost.h | 5 ++ src/objective-c/GRPCClient/private/GRPCHost.m | 12 +++- src/objective-c/tests/InteropTests.m | 64 +++++++++++++++++-- 8 files changed, 101 insertions(+), 20 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h index 646bf43b547..5c0d48d427c 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h @@ -43,7 +43,9 @@ * Use the provided @c userAgentPrefix at the beginning of the HTTP User Agent string for all calls * to the specified @c host. */ -+ (void)setUserAgentPrefix:(NSString *)userAgentPrefix forHost:(NSString *)host; ++ (void)setUserAgentPrefix:(nonnull NSString *)userAgentPrefix forHost:(nonnull NSString *)host; + ++ (void)setResponseSizeLimit:(NSUInteger)limit forHost:(nonnull NSString *)host; + (void)closeOpenConnections DEPRECATED_MSG_ATTRIBUTE("The API for this feature is experimental, " "and might be removed or modified at any " diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m index bcc3b915075..7fab357e932 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m @@ -37,15 +37,16 @@ @implementation GRPCCall (ChannelArg) -+ (void)setUserAgentPrefix:(NSString *)userAgentPrefix forHost:(NSString *)host { - if (!host) { - [NSException raise:NSInvalidArgumentException - format:@"host and userAgentPrefix must be provided."]; - } ++ (void)setUserAgentPrefix:(nonnull NSString *)userAgentPrefix forHost:(nonnull NSString *)host { GRPCHost *hostConfig = [GRPCHost hostWithAddress:host]; hostConfig.userAgentPrefix = userAgentPrefix; } ++ (void)setResponseSizeLimit:(NSUInteger)limit forHost:(nonnull NSString *)host { + GRPCHost *hostConfig = [GRPCHost hostWithAddress:host]; + hostConfig.responseSizeLimitOverride = @(limit); +} + + (void)closeOpenConnections { [GRPCHost flushChannelCache]; } diff --git a/src/objective-c/GRPCClient/GRPCCall+Tests.h b/src/objective-c/GRPCClient/GRPCCall+Tests.h index ccc5723ec70..fe2c3604774 100644 --- a/src/objective-c/GRPCClient/GRPCCall+Tests.h +++ b/src/objective-c/GRPCClient/GRPCCall+Tests.h @@ -57,4 +57,10 @@ * more than one invocation of the methods of this category. */ + (void)useInsecureConnectionsForHost:(NSString *)host; + +/** + * Resets all host configurations to their default values, and flushes all connections from the + * cache. + */ ++ (void)clearAllConfigurationsForTesting; @end diff --git a/src/objective-c/GRPCClient/GRPCCall+Tests.m b/src/objective-c/GRPCClient/GRPCCall+Tests.m index b9456691bd8..44d42f382c6 100644 --- a/src/objective-c/GRPCClient/GRPCCall+Tests.m +++ b/src/objective-c/GRPCClient/GRPCCall+Tests.m @@ -61,4 +61,7 @@ hostConfig.secure = NO; } ++ (void)clearAllConfigurationsForTesting { + [GRPCHost clearAllHostsForTesting]; +} @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 7b7b79e1c62..e49aceefe18 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -47,7 +47,7 @@ #endif #import "GRPCCompletionQueue.h" -void freeChannelArgs(grpc_channel_args *channel_args) { +static void FreeChannelArgs(grpc_channel_args *channel_args) { for (size_t i = 0; i < channel_args->num_args; ++i) { grpc_arg *arg = &channel_args->args[i]; gpr_free(arg->key); @@ -65,7 +65,7 @@ void freeChannelArgs(grpc_channel_args *channel_args) { * value responds to @c @selector(intValue). Otherwise, an exception will be raised. The caller of * this function is responsible for calling @c freeChannelArgs on a non-NULL returned value. */ -grpc_channel_args * buildChannelArgs(NSDictionary *dictionary) { +static grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) { if (!dictionary) { return NULL; } @@ -115,10 +115,12 @@ grpc_channel_args * buildChannelArgs(NSDictionary *dictionary) { } if (self = [super init]) { - _channelArgs = buildChannelArgs(channelArgs); + _channelArgs = BuildChannelArgs(channelArgs); _host = [host copy]; - _unmanagedChannel = grpc_cronet_secure_channel_create(cronetEngine, _host.UTF8String, _channelArgs, - NULL); + _unmanagedChannel = grpc_cronet_secure_channel_create(cronetEngine, + _host.UTF8String, + _channelArgs, + NULL); } return self; @@ -138,7 +140,7 @@ grpc_channel_args * buildChannelArgs(NSDictionary *dictionary) { } if (self = [super init]) { - _channelArgs = buildChannelArgs(channelArgs); + _channelArgs = BuildChannelArgs(channelArgs); _host = [host copy]; if (secure) { _unmanagedChannel = grpc_secure_channel_create(credentials, _host.UTF8String, _channelArgs, @@ -155,7 +157,7 @@ grpc_channel_args * buildChannelArgs(NSDictionary *dictionary) { // TODO(jcanizales): Be sure to add a test with a server that closes the connection prematurely, // as in the past that made this call to crash. grpc_channel_destroy(_unmanagedChannel); - freeChannelArgs(_channelArgs); + FreeChannelArgs(_channelArgs); } #ifdef GRPC_COMPILE_WITH_CRONET diff --git a/src/objective-c/GRPCClient/private/GRPCHost.h b/src/objective-c/GRPCClient/private/GRPCHost.h index 350c69bf8e8..48fe7854ff5 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.h +++ b/src/objective-c/GRPCClient/private/GRPCHost.h @@ -42,6 +42,7 @@ struct grpc_channel_credentials; @interface GRPCHost : NSObject + (void)flushChannelCache; ++ (void)clearAllHostsForTesting; @property(nonatomic, readonly) NSString *address; @property(nonatomic, copy, nullable) NSString *userAgentPrefix; @@ -53,6 +54,10 @@ struct grpc_channel_credentials; @property(nonatomic, copy, nullable) NSString *hostNameOverride; +/** The default response size limit is 4MB. Set this to override that default. */ +@property(nonatomic, strong, nullable) NSNumber *responseSizeLimitOverride; + + - (nullable instancetype)init NS_UNAVAILABLE; /** Host objects initialized with the same address are the same. */ + (nullable instancetype)hostWithAddress:(NSString *)address; diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 08c699f99e2..b46c24212b8 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -49,7 +49,7 @@ NS_ASSUME_NONNULL_BEGIN // TODO(jcanizales): Generate the version in a standalone header, from templates. Like // templates/src/core/surface/version.c.template . -#define GRPC_OBJC_VERSION_STRING @"0.13.0" +#define GRPC_OBJC_VERSION_STRING @"1.0.0-pre1" static NSMutableDictionary *kHostCache; @@ -113,6 +113,12 @@ static NSMutableDictionary *kHostCache; } } ++ (void)clearAllHostsForTesting { + @synchronized (kHostCache) { + kHostCache = [NSMutableDictionary dictionary]; + } +} + - (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path completionQueue:(GRPCCompletionQueue *)queue { GRPCChannel *channel; @@ -209,6 +215,10 @@ static NSMutableDictionary *kHostCache; if (_secure && _hostNameOverride) { args[@GRPC_SSL_TARGET_NAME_OVERRIDE_ARG] = _hostNameOverride; } + + if (_responseSizeLimitOverride) { + args[@GRPC_ARG_MAX_MESSAGE_LENGTH] = _responseSizeLimitOverride; + } return args; } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 494743d6041..33a944196ce 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -80,10 +80,6 @@ #pragma mark Tests -#ifdef GRPC_COMPILE_WITH_CRONET -static cronet_engine *cronetEngine = NULL; -#endif - @implementation InteropTests { RMTTestService *_service; } @@ -93,14 +89,17 @@ static cronet_engine *cronetEngine = NULL; } - (void)setUp { + self.continueAfterFailure = NO; + + [GRPCCall clearAllConfigurationsForTesting]; + _service = self.class.host ? [RMTTestService serviceWithHost:self.class.host] : nil; #ifdef GRPC_COMPILE_WITH_CRONET if (cronetEngine == NULL) { // Cronet setup [Cronet setHttp2Enabled:YES]; [Cronet start]; - cronetEngine = [Cronet getGlobalEngine]; - [GRPCCall useCronetWithEngine:cronetEngine]; + [GRPCCall useCronetWithEngine:[Cronet getGlobalEngine]]; } #endif } @@ -146,6 +145,59 @@ static cronet_engine *cronetEngine = NULL; [self waitForExpectationsWithTimeout:16 handler:nil]; } +- (void)test4MBResponsesAreAccepted { + XCTAssertNotNil(self.class.host); + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"MaxResponseSize"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + const size_t kPayloadSize = 4 * 1024 * 1024 - 12; // 4MB - 12B of protobuf encoding overhead + request.responseSize = kPayloadSize; + + [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", error); + XCTAssertEqual(response.payload.body.length, kPayloadSize); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:16 handler:nil]; +} + +- (void)testResponsesOverMaxSizeFailWithActionableMessage { + XCTAssertNotNil(self.class.host); + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ResponseOverMaxSize"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + const size_t kPayloadSize = 4 * 1024 * 1024 - 11; // 1B over max size (see above test) + request.responseSize = kPayloadSize; + + [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) { + XCTAssertEqualObjects(error.localizedDescription, @"Max message size exceeded"); // TODO: Improve + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:16 handler:nil]; +} + +- (void)testResponsesOver4MBAreAcceptedIfOptedIn { + XCTAssertNotNil(self.class.host); + __weak XCTestExpectation *expectation = + [self expectationWithDescription:@"HigherResponseSizeLimit"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + const size_t kPayloadSize = 5 * 1024 * 1024; // 5MB + request.responseSize = kPayloadSize; + + [GRPCCall setResponseSizeLimit:6 * 1024 * 1024 forHost:self.class.host]; + + [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", error); + XCTAssertEqual(response.payload.body.length, kPayloadSize); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:16 handler:nil]; +} + - (void)testClientStreamingRPC { XCTAssertNotNil(self.class.host); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ClientStreaming"]; From ec0743e6122c605598fd59fe656e00c2a1fcc46a Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 29 Jul 2016 01:50:06 -0700 Subject: [PATCH 081/279] Leave improving the error message as a TODO --- src/objective-c/tests/InteropTests.m | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 33a944196ce..67ab43329fe 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -171,7 +171,12 @@ request.responseSize = kPayloadSize; [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) { - XCTAssertEqualObjects(error.localizedDescription, @"Max message size exceeded"); // TODO: Improve + // TODO(jcanizales): Catch the error and rethrow it with an actionable message: + // - Use +[GRPCCall setResponseSizeLimit:forHost:] to set a higher limit. + // - If you're developing the server, consider using response streaming, or let clients filter + // responses by setting a google.protobuf.FieldMask in the request: + // https://github.com/google/protobuf/blob/master/src/google/protobuf/field_mask.proto + XCTAssertEqualObjects(error.localizedDescription, @"Max message size exceeded"); [expectation fulfill]; }]; From 4da5fd072874d8253e8e42fc7113cca587a1bd31 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 29 Jul 2016 04:26:40 -0700 Subject: [PATCH 082/279] Document --- src/objective-c/GRPCClient/GRPCCall+ChannelArg.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h index 5c0d48d427c..4a3f3fa4a1a 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h @@ -45,6 +45,7 @@ */ + (void)setUserAgentPrefix:(nonnull NSString *)userAgentPrefix forHost:(nonnull NSString *)host; +/** The default response size limit is 4MB. Set this to override that default. */ + (void)setResponseSizeLimit:(NSUInteger)limit forHost:(nonnull NSString *)host; + (void)closeOpenConnections DEPRECATED_MSG_ATTRIBUTE("The API for this feature is experimental, " From f8372c607a9751c951092ee5a34cc78f3c718d2d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 29 Jul 2016 09:58:55 -0700 Subject: [PATCH 083/279] Minor revisions --- gRPC-Core.podspec | 4 ++-- src/objective-c/tests/Podfile | 8 ++++---- templates/gRPC-Core.podspec.template | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 50fc9e9e7d7..ab5fbfaa6c2 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -770,13 +770,13 @@ Pod::Spec.new do |s| ss.source_files = 'include/grpc/grpc_cronet.h' end - s.subspec 'Cronet-Implement' do |ss| + s.subspec 'Cronet-Implementation' do |ss| ss.header_mappings_dir = '.' ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c', 'src/core/ext/transport/cronet/transport/cronet_transport.c' end - s.subspec 'Cronet-Tests' do |ss| + s.subspec 'Tests' do |ss| ss.header_mappings_dir = '.' ss.source_files = 'test/core/end2end/cq_verifier.{c,h}', diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 1db7321d212..067d37eccc1 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -32,7 +32,7 @@ GRPC_LOCAL_SRC = '../../..' if target_name == 'InteropTestsRemoteWithCronet' pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" - pod 'gRPC-Core/Cronet-Implement', :path => GRPC_LOCAL_SRC + pod 'gRPC-Core/Cronet-Implementation', :path => GRPC_LOCAL_SRC end end end @@ -42,8 +42,8 @@ target 'CoreCronetEnd2EndTests' do pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" pod 'gRPC-Core', :path => GRPC_LOCAL_SRC pod 'gRPC-Core/Cronet-Interface', :path => GRPC_LOCAL_SRC - pod 'gRPC-Core/Cronet-Implement', :path => GRPC_LOCAL_SRC - pod 'gRPC-Core/Cronet-Tests', :path => GRPC_LOCAL_SRC + pod 'gRPC-Core/Cronet-Implementation', :path => GRPC_LOCAL_SRC + pod 'gRPC-Core/Tests', :path => GRPC_LOCAL_SRC end # gRPC-Core.podspec needs to be modified to be successfully used for local development. A Podfile's @@ -82,7 +82,7 @@ post_install do |installer| target.build_configurations.each do |config| config.build_settings['GCC_TREAT_WARNINGS_AS_ERRORS'] = 'YES' end - if target.name == 'gRPC-Core' or target.name == 'gRPC-Core.default-Cronet-Implement-Cronet-Interface-Cronet-Tests' or target.name == 'gRPC-Core.default-Cronet-Implement' + if target.name == 'gRPC-Core' or target.name == 'gRPC-Core.default-Cronet-Implementation-Cronet-Interface-Tests' or target.name == 'gRPC-Core.default-Cronet-Implementation' target.build_configurations.each do |config| # TODO(zyc): Remove this setting after the issue is resolved # GPR_UNREACHABLE_CODE causes "Control may reach end of non-void diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index 6dd73414b6d..644dc4a6320 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -162,13 +162,13 @@ ss.source_files = 'include/grpc/grpc_cronet.h' end - s.subspec 'Cronet-Implement' do |ss| + s.subspec 'Cronet-Implementation' do |ss| ss.header_mappings_dir = '.' ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c', 'src/core/ext/transport/cronet/transport/cronet_transport.c' end - s.subspec 'Cronet-Tests' do |ss| + s.subspec 'Tests' do |ss| ss.header_mappings_dir = '.' ss.source_files = 'test/core/end2end/cq_verifier.{c,h}', From fcb5271105ec2c439f83ec3cce6456b73824b6be Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 29 Jul 2016 10:44:01 -0700 Subject: [PATCH 084/279] Update node protobuf dependency to 3.0.0 where applicable. Also update example dependency to grpc 1.0.0 --- examples/node/package.json | 4 ++-- package.json | 2 +- src/node/health_check/package.json | 4 ++-- templates/package.json.template | 2 +- templates/src/node/health_check/package.json.template | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/node/package.json b/examples/node/package.json index 2cae031175e..6317838295a 100644 --- a/examples/node/package.json +++ b/examples/node/package.json @@ -3,8 +3,8 @@ "version": "0.1.0", "dependencies": { "async": "^1.5.2", - "google-protobuf": "^3.0.0-alpha.5", - "grpc": "^0.14.0", + "google-protobuf": "^3.0.0", + "grpc": "^1.0.0", "lodash": "^4.6.1", "minimist": "^1.2.0" } diff --git a/package.json b/package.json index 35410642c78..ac936fea84c 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "devDependencies": { "async": "^1.5.0", "google-auth-library": "^0.9.2", - "google-protobuf": "^3.0.0-alpha.5", + "google-protobuf": "^3.0.0", "istanbul": "^0.3.21", "jsdoc": "^3.3.2", "jshint": "^2.5.0", diff --git a/src/node/health_check/package.json b/src/node/health_check/package.json index 582d5601016..bdacb66825d 100644 --- a/src/node/health_check/package.json +++ b/src/node/health_check/package.json @@ -15,9 +15,9 @@ } ], "dependencies": { - "grpc": "^0.15.0", + "grpc": "^1.0.0-pre1", "lodash": "^3.9.3", - "google-protobuf": "^3.0.0-alpha.5" + "google-protobuf": "^3.0.0" }, "files": [ "LICENSE", diff --git a/templates/package.json.template b/templates/package.json.template index f68f64d0475..e9596d4d4cb 100644 --- a/templates/package.json.template +++ b/templates/package.json.template @@ -37,7 +37,7 @@ "devDependencies": { "async": "^1.5.0", "google-auth-library": "^0.9.2", - "google-protobuf": "^3.0.0-alpha.5", + "google-protobuf": "^3.0.0", "istanbul": "^0.3.21", "jsdoc": "^3.3.2", "jshint": "^2.5.0", diff --git a/templates/src/node/health_check/package.json.template b/templates/src/node/health_check/package.json.template index 96b9748aa74..c2bb232245d 100644 --- a/templates/src/node/health_check/package.json.template +++ b/templates/src/node/health_check/package.json.template @@ -17,9 +17,9 @@ } ], "dependencies": { - "grpc": "^0.15.0", + "grpc": "^${settings.node_version}", "lodash": "^3.9.3", - "google-protobuf": "^3.0.0-alpha.5" + "google-protobuf": "^3.0.0" }, "files": [ "LICENSE", From 3ed66976f6a430d402670f7fa5886d9f164c4d12 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 29 Jul 2016 11:17:52 -0700 Subject: [PATCH 085/279] Update ruby google-protobuf dependency to 3.0 --- grpc.gemspec | 2 +- templates/grpc.gemspec.template | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/grpc.gemspec b/grpc.gemspec index 369851b0f24..00113cba924 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -27,7 +27,7 @@ Gem::Specification.new do |s| s.require_paths = %w( src/ruby/bin src/ruby/lib src/ruby/pb ) s.platform = Gem::Platform::RUBY - s.add_dependency 'google-protobuf', '~> 3.0.0.alpha.5.0.3' + s.add_dependency 'google-protobuf', '~> 3.0' s.add_dependency 'googleauth', '~> 0.5.1' s.add_development_dependency 'bundler', '~> 1.9' diff --git a/templates/grpc.gemspec.template b/templates/grpc.gemspec.template index ce775ffb90b..f95adaf30fa 100644 --- a/templates/grpc.gemspec.template +++ b/templates/grpc.gemspec.template @@ -29,7 +29,7 @@ s.require_paths = %w( src/ruby/bin src/ruby/lib src/ruby/pb ) s.platform = Gem::Platform::RUBY - s.add_dependency 'google-protobuf', '~> 3.0.0.alpha.5.0.3' + s.add_dependency 'google-protobuf', '~> 3.0' s.add_dependency 'googleauth', '~> 0.5.1' s.add_development_dependency 'bundler', '~> 1.9' From 660333a87b5c95e9e2ab40d9629e8f7727e5fbec Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 22 Jul 2016 15:32:05 -0700 Subject: [PATCH 086/279] update project.json templates to RTM .NET core nugets --- templates/src/csharp/Grpc.Auth/project.json.template | 6 +++--- templates/src/csharp/Grpc.Core.Tests/project.json.template | 2 +- templates/src/csharp/Grpc.Core/project.json.template | 4 ++-- .../csharp/Grpc.Examples.MathClient/project.json.template | 2 +- .../csharp/Grpc.Examples.MathServer/project.json.template | 2 +- .../src/csharp/Grpc.Examples.Tests/project.json.template | 2 +- templates/src/csharp/Grpc.Examples/project.json.template | 2 +- .../src/csharp/Grpc.HealthCheck.Tests/project.json.template | 2 +- templates/src/csharp/Grpc.HealthCheck/project.json.template | 2 +- .../Grpc.IntegrationTesting.Client/project.json.template | 2 +- .../Grpc.IntegrationTesting.QpsWorker/project.json.template | 2 +- .../Grpc.IntegrationTesting.Server/project.json.template | 2 +- .../project.json.template | 2 +- .../csharp/Grpc.IntegrationTesting/project.json.template | 4 ++-- 14 files changed, 18 insertions(+), 18 deletions(-) diff --git a/templates/src/csharp/Grpc.Auth/project.json.template b/templates/src/csharp/Grpc.Auth/project.json.template index d91bd8ce1df..b3244e4d3c9 100644 --- a/templates/src/csharp/Grpc.Auth/project.json.template +++ b/templates/src/csharp/Grpc.Auth/project.json.template @@ -34,9 +34,9 @@ "net45" ], "dependencies": { - "Microsoft.NETCore.Portable.Compatibility": "1.0.1-rc2-24027", - "NETStandard.Library": "1.5.0-rc2-24027", - "System.Threading.Tasks": "4.0.11-rc2-24027" + "Microsoft.NETCore.Portable.Compatibility": "1.0.1", + "NETStandard.Library": "1.6.0", + "System.Threading.Tasks": "4.0.11" } } } diff --git a/templates/src/csharp/Grpc.Core.Tests/project.json.template b/templates/src/csharp/Grpc.Core.Tests/project.json.template index bc9fa3e63a9..004265e19d5 100644 --- a/templates/src/csharp/Grpc.Core.Tests/project.json.template +++ b/templates/src/csharp/Grpc.Core.Tests/project.json.template @@ -17,7 +17,7 @@ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "NETStandard.Library": "1.6.0" } } }, diff --git a/templates/src/csharp/Grpc.Core/project.json.template b/templates/src/csharp/Grpc.Core/project.json.template index 6355db53892..bd0e8b2c138 100644 --- a/templates/src/csharp/Grpc.Core/project.json.template +++ b/templates/src/csharp/Grpc.Core/project.json.template @@ -42,8 +42,8 @@ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027", - "System.Threading.Thread": "4.0.0-rc2-24027" + "NETStandard.Library": "1.6.0", + "System.Threading.Thread": "4.0.0" } } } diff --git a/templates/src/csharp/Grpc.Examples.MathClient/project.json.template b/templates/src/csharp/Grpc.Examples.MathClient/project.json.template index fba401c3a47..194c1a3798a 100644 --- a/templates/src/csharp/Grpc.Examples.MathClient/project.json.template +++ b/templates/src/csharp/Grpc.Examples.MathClient/project.json.template @@ -14,7 +14,7 @@ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.Examples.MathServer/project.json.template b/templates/src/csharp/Grpc.Examples.MathServer/project.json.template index fba401c3a47..194c1a3798a 100644 --- a/templates/src/csharp/Grpc.Examples.MathServer/project.json.template +++ b/templates/src/csharp/Grpc.Examples.MathServer/project.json.template @@ -14,7 +14,7 @@ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.Examples.Tests/project.json.template b/templates/src/csharp/Grpc.Examples.Tests/project.json.template index 21765f0565c..eb6bc5dde78 100644 --- a/templates/src/csharp/Grpc.Examples.Tests/project.json.template +++ b/templates/src/csharp/Grpc.Examples.Tests/project.json.template @@ -16,7 +16,7 @@ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.Examples/project.json.template b/templates/src/csharp/Grpc.Examples/project.json.template index 715fc087256..d5d63f658e4 100644 --- a/templates/src/csharp/Grpc.Examples/project.json.template +++ b/templates/src/csharp/Grpc.Examples/project.json.template @@ -20,7 +20,7 @@ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template b/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template index 79e67226cb4..5fb1c024fb8 100644 --- a/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template +++ b/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template @@ -16,7 +16,7 @@ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.HealthCheck/project.json.template b/templates/src/csharp/Grpc.HealthCheck/project.json.template index 264ed292050..cd2da0089bb 100644 --- a/templates/src/csharp/Grpc.HealthCheck/project.json.template +++ b/templates/src/csharp/Grpc.HealthCheck/project.json.template @@ -39,7 +39,7 @@ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.IntegrationTesting.Client/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.Client/project.json.template index 10ed5493477..7709c60241c 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting.Client/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting.Client/project.json.template @@ -15,7 +15,7 @@ "net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template index 10ed5493477..7709c60241c 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template @@ -15,7 +15,7 @@ "net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.IntegrationTesting.Server/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.Server/project.json.template index 10ed5493477..7709c60241c 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting.Server/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting.Server/project.json.template @@ -15,7 +15,7 @@ "net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template index 10ed5493477..7709c60241c 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template @@ -15,7 +15,7 @@ "net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.IntegrationTesting/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting/project.json.template index 31815114857..f446fac7efb 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting/project.json.template @@ -30,8 +30,8 @@ "net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027", - "System.Linq.Expressions": "4.0.11-rc2-24027" + "NETStandard.Library": "1.6.0", + "System.Linq.Expressions": "4.1.0" } } } From 36d15404f56760e0756d146fa2dc03d2dc72d09a Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 26 Jul 2016 16:01:13 -0700 Subject: [PATCH 087/279] use netcoreapp1.0 for executable projects --- templates/src/csharp/Grpc.Core.Tests/project.json.template | 3 ++- .../src/csharp/Grpc.Examples.MathClient/project.json.template | 3 ++- .../src/csharp/Grpc.Examples.MathServer/project.json.template | 3 ++- templates/src/csharp/Grpc.Examples.Tests/project.json.template | 3 ++- .../src/csharp/Grpc.HealthCheck.Tests/project.json.template | 3 ++- .../Grpc.IntegrationTesting.Client/project.json.template | 3 ++- .../Grpc.IntegrationTesting.QpsWorker/project.json.template | 3 ++- .../Grpc.IntegrationTesting.Server/project.json.template | 3 ++- .../Grpc.IntegrationTesting.StressClient/project.json.template | 3 ++- .../src/csharp/Grpc.IntegrationTesting/project.json.template | 3 ++- 10 files changed, 20 insertions(+), 10 deletions(-) diff --git a/templates/src/csharp/Grpc.Core.Tests/project.json.template b/templates/src/csharp/Grpc.Core.Tests/project.json.template index 004265e19d5..9a8dcc13d85 100644 --- a/templates/src/csharp/Grpc.Core.Tests/project.json.template +++ b/templates/src/csharp/Grpc.Core.Tests/project.json.template @@ -12,11 +12,12 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45" ], "dependencies": { + "Microsoft.NETCore.App": "1.0.0", "NETStandard.Library": "1.6.0" } } diff --git a/templates/src/csharp/Grpc.Examples.MathClient/project.json.template b/templates/src/csharp/Grpc.Examples.MathClient/project.json.template index 194c1a3798a..67151dbcfa8 100644 --- a/templates/src/csharp/Grpc.Examples.MathClient/project.json.template +++ b/templates/src/csharp/Grpc.Examples.MathClient/project.json.template @@ -9,11 +9,12 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45" ], "dependencies": { + "Microsoft.NETCore.App": "1.0.0", "NETStandard.Library": "1.6.0" } } diff --git a/templates/src/csharp/Grpc.Examples.MathServer/project.json.template b/templates/src/csharp/Grpc.Examples.MathServer/project.json.template index 194c1a3798a..67151dbcfa8 100644 --- a/templates/src/csharp/Grpc.Examples.MathServer/project.json.template +++ b/templates/src/csharp/Grpc.Examples.MathServer/project.json.template @@ -9,11 +9,12 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45" ], "dependencies": { + "Microsoft.NETCore.App": "1.0.0", "NETStandard.Library": "1.6.0" } } diff --git a/templates/src/csharp/Grpc.Examples.Tests/project.json.template b/templates/src/csharp/Grpc.Examples.Tests/project.json.template index eb6bc5dde78..af13cb58501 100644 --- a/templates/src/csharp/Grpc.Examples.Tests/project.json.template +++ b/templates/src/csharp/Grpc.Examples.Tests/project.json.template @@ -11,11 +11,12 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45" ], "dependencies": { + "Microsoft.NETCore.App": "1.0.0", "NETStandard.Library": "1.6.0" } } diff --git a/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template b/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template index 5fb1c024fb8..417b773a428 100644 --- a/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template +++ b/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template @@ -11,11 +11,12 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45" ], "dependencies": { + "Microsoft.NETCore.App": "1.0.0", "NETStandard.Library": "1.6.0" } } diff --git a/templates/src/csharp/Grpc.IntegrationTesting.Client/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.Client/project.json.template index 7709c60241c..93151f2b89e 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting.Client/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting.Client/project.json.template @@ -9,12 +9,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45", "net45" ], "dependencies": { + "Microsoft.NETCore.App": "1.0.0", "NETStandard.Library": "1.6.0" } } diff --git a/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template index 7709c60241c..93151f2b89e 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template @@ -9,12 +9,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45", "net45" ], "dependencies": { + "Microsoft.NETCore.App": "1.0.0", "NETStandard.Library": "1.6.0" } } diff --git a/templates/src/csharp/Grpc.IntegrationTesting.Server/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.Server/project.json.template index 7709c60241c..93151f2b89e 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting.Server/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting.Server/project.json.template @@ -9,12 +9,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45", "net45" ], "dependencies": { + "Microsoft.NETCore.App": "1.0.0", "NETStandard.Library": "1.6.0" } } diff --git a/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template index 7709c60241c..93151f2b89e 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template @@ -9,12 +9,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45", "net45" ], "dependencies": { + "Microsoft.NETCore.App": "1.0.0", "NETStandard.Library": "1.6.0" } } diff --git a/templates/src/csharp/Grpc.IntegrationTesting/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting/project.json.template index f446fac7efb..0a7d5e9af40 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting/project.json.template @@ -24,12 +24,13 @@ "System.IO": "" } }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45", "net45" ], "dependencies": { + "Microsoft.NETCore.App": "1.0.0", "NETStandard.Library": "1.6.0", "System.Linq.Expressions": "4.1.0" } From 3fc8c8a9ff0402e3aa699c8ae4f9acf893c61fc9 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 22 Jul 2016 15:33:29 -0700 Subject: [PATCH 088/279] regenerate --- src/csharp/Grpc.Auth/project.json | 6 +++--- src/csharp/Grpc.Core.Tests/project.json | 5 +++-- src/csharp/Grpc.Core/project.json | 4 ++-- src/csharp/Grpc.Examples.MathClient/project.json | 5 +++-- src/csharp/Grpc.Examples.MathServer/project.json | 5 +++-- src/csharp/Grpc.Examples.Tests/project.json | 5 +++-- src/csharp/Grpc.Examples/project.json | 2 +- src/csharp/Grpc.HealthCheck.Tests/project.json | 5 +++-- src/csharp/Grpc.HealthCheck/project.json | 2 +- src/csharp/Grpc.IntegrationTesting.Client/project.json | 5 +++-- src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json | 5 +++-- src/csharp/Grpc.IntegrationTesting.Server/project.json | 5 +++-- .../Grpc.IntegrationTesting.StressClient/project.json | 5 +++-- src/csharp/Grpc.IntegrationTesting/project.json | 7 ++++--- 14 files changed, 38 insertions(+), 28 deletions(-) diff --git a/src/csharp/Grpc.Auth/project.json b/src/csharp/Grpc.Auth/project.json index 34a4e2f1b69..7216cf15041 100644 --- a/src/csharp/Grpc.Auth/project.json +++ b/src/csharp/Grpc.Auth/project.json @@ -32,9 +32,9 @@ "net45" ], "dependencies": { - "Microsoft.NETCore.Portable.Compatibility": "1.0.1-rc2-24027", - "NETStandard.Library": "1.5.0-rc2-24027", - "System.Threading.Tasks": "4.0.11-rc2-24027" + "Microsoft.NETCore.Portable.Compatibility": "1.0.1", + "NETStandard.Library": "1.6.0", + "System.Threading.Tasks": "4.0.11" } } } diff --git a/src/csharp/Grpc.Core.Tests/project.json b/src/csharp/Grpc.Core.Tests/project.json index d4c9a2ef316..b2bb7b716eb 100644 --- a/src/csharp/Grpc.Core.Tests/project.json +++ b/src/csharp/Grpc.Core.Tests/project.json @@ -58,12 +58,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } }, diff --git a/src/csharp/Grpc.Core/project.json b/src/csharp/Grpc.Core/project.json index 7a676f59a64..de428c2fd9f 100644 --- a/src/csharp/Grpc.Core/project.json +++ b/src/csharp/Grpc.Core/project.json @@ -40,8 +40,8 @@ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027", - "System.Threading.Thread": "4.0.0-rc2-24027" + "NETStandard.Library": "1.6.0", + "System.Threading.Thread": "4.0.0" } } } diff --git a/src/csharp/Grpc.Examples.MathClient/project.json b/src/csharp/Grpc.Examples.MathClient/project.json index 206d6c59824..ad319478ab0 100644 --- a/src/csharp/Grpc.Examples.MathClient/project.json +++ b/src/csharp/Grpc.Examples.MathClient/project.json @@ -55,12 +55,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.Examples.MathServer/project.json b/src/csharp/Grpc.Examples.MathServer/project.json index 206d6c59824..ad319478ab0 100644 --- a/src/csharp/Grpc.Examples.MathServer/project.json +++ b/src/csharp/Grpc.Examples.MathServer/project.json @@ -55,12 +55,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.Examples.Tests/project.json b/src/csharp/Grpc.Examples.Tests/project.json index b4c4c5f6910..1cd1848e99f 100644 --- a/src/csharp/Grpc.Examples.Tests/project.json +++ b/src/csharp/Grpc.Examples.Tests/project.json @@ -57,12 +57,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.Examples/project.json b/src/csharp/Grpc.Examples/project.json index 7d3f4dcbb1e..48ec530abb1 100644 --- a/src/csharp/Grpc.Examples/project.json +++ b/src/csharp/Grpc.Examples/project.json @@ -20,7 +20,7 @@ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.HealthCheck.Tests/project.json b/src/csharp/Grpc.HealthCheck.Tests/project.json index f44a3225ae6..faa44003044 100644 --- a/src/csharp/Grpc.HealthCheck.Tests/project.json +++ b/src/csharp/Grpc.HealthCheck.Tests/project.json @@ -57,12 +57,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.HealthCheck/project.json b/src/csharp/Grpc.HealthCheck/project.json index 906dda36247..f11e13e9e68 100644 --- a/src/csharp/Grpc.HealthCheck/project.json +++ b/src/csharp/Grpc.HealthCheck/project.json @@ -37,7 +37,7 @@ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.IntegrationTesting.Client/project.json b/src/csharp/Grpc.IntegrationTesting.Client/project.json index 6b61a4b76e8..287950720fe 100644 --- a/src/csharp/Grpc.IntegrationTesting.Client/project.json +++ b/src/csharp/Grpc.IntegrationTesting.Client/project.json @@ -57,13 +57,14 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45", "net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json index 6b61a4b76e8..287950720fe 100644 --- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json +++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json @@ -57,13 +57,14 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45", "net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.IntegrationTesting.Server/project.json b/src/csharp/Grpc.IntegrationTesting.Server/project.json index 6b61a4b76e8..287950720fe 100644 --- a/src/csharp/Grpc.IntegrationTesting.Server/project.json +++ b/src/csharp/Grpc.IntegrationTesting.Server/project.json @@ -57,13 +57,14 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45", "net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json index 6b61a4b76e8..287950720fe 100644 --- a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json +++ b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json @@ -57,13 +57,14 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45", "net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.IntegrationTesting/project.json b/src/csharp/Grpc.IntegrationTesting/project.json index dcd9ccabd29..bb61a679c1f 100644 --- a/src/csharp/Grpc.IntegrationTesting/project.json +++ b/src/csharp/Grpc.IntegrationTesting/project.json @@ -72,14 +72,15 @@ "System.IO": "" } }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45", "net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027", - "System.Linq.Expressions": "4.0.11-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0", + "System.Linq.Expressions": "4.1.0" } } } From d083c148a249f089bbed832961982d0c5690c1e4 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Fri, 29 Jul 2016 13:39:26 -0700 Subject: [PATCH 089/279] php: missed a macro --- src/php/ext/grpc/channel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c index e96ead582f4..b5a2c9f6baf 100644 --- a/src/php/ext/grpc/channel.c +++ b/src/php/ext/grpc/channel.c @@ -84,7 +84,7 @@ void php_grpc_read_args_array(zval *args_array, array_hash = Z_ARRVAL_P(args_array); if (!array_hash) { zend_throw_exception(spl_ce_InvalidArgumentException, - "array_hash is NULL", 1); + "array_hash is NULL", 1 TSRMLS_CC); return; } args->num_args = zend_hash_num_elements(array_hash); From 3260a1731a0e3cb492b09775847e60b22f8ec08a Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 29 Jul 2016 22:56:12 +0200 Subject: [PATCH 090/279] Bumping to 1.0.0-pre2. --- CMakeLists.txt | 2 +- Makefile | 2 +- build.yaml | 2 +- package.json | 2 +- src/core/lib/surface/version.c | 2 +- src/csharp/Grpc.Auth/project.json | 4 ++-- src/csharp/Grpc.Core/VersionInfo.cs | 2 +- src/csharp/Grpc.Core/project.json | 2 +- src/csharp/Grpc.HealthCheck/project.json | 4 ++-- src/csharp/build_packages.bat | 2 +- src/node/health_check/package.json | 2 +- src/node/tools/package.json | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_health_checking/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 +- tools/doxygen/Doxyfile.core | 2 +- tools/doxygen/Doxyfile.core.internal | 2 +- 22 files changed, 24 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c605319aa5..2f498c083f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.0.0-pre1") +set(PACKAGE_VERSION "1.0.0-pre2") 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 ed362f9752b..ad2ff32d419 100644 --- a/Makefile +++ b/Makefile @@ -415,7 +415,7 @@ E = @echo Q = @ endif -VERSION = 1.0.0-pre1 +VERSION = 1.0.0-pre2 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/build.yaml b/build.yaml index 42ea3cb810b..c474f66cb2c 100644 --- a/build.yaml +++ b/build.yaml @@ -7,7 +7,7 @@ settings: '#3': Use "-preN" suffixes to identify pre-release versions '#4': Per-language overrides are possible with (eg) ruby_version tag here '#5': See the expand_version.py for all the quirks here - version: 1.0.0-pre1 + version: 1.0.0-pre2 filegroups: - name: census public_headers: diff --git a/package.json b/package.json index 35410642c78..0a6a45f6b95 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "grpc", - "version": "1.0.0-pre1", + "version": "1.0.0-pre2", "author": "Google Inc.", "description": "gRPC Library for Node", "homepage": "http://www.grpc.io/", diff --git a/src/core/lib/surface/version.c b/src/core/lib/surface/version.c index f0005363d56..dab7f542ee6 100644 --- a/src/core/lib/surface/version.c +++ b/src/core/lib/surface/version.c @@ -36,4 +36,4 @@ #include -const char *grpc_version_string(void) { return "1.0.0-pre1"; } +const char *grpc_version_string(void) { return "1.0.0-pre2"; } diff --git a/src/csharp/Grpc.Auth/project.json b/src/csharp/Grpc.Auth/project.json index 34a4e2f1b69..979ab40e925 100644 --- a/src/csharp/Grpc.Auth/project.json +++ b/src/csharp/Grpc.Auth/project.json @@ -1,5 +1,5 @@ { - "version": "1.0.0-pre1", + "version": "1.0.0-pre2", "title": "gRPC C# Auth", "authors": [ "Google Inc." ], "copyright": "Copyright 2015, Google Inc.", @@ -22,7 +22,7 @@ } }, "dependencies": { - "Grpc.Core": "1.0.0-pre1", + "Grpc.Core": "1.0.0-pre2", "Google.Apis.Auth": "1.11.1" }, "frameworks": { diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index e9f5c63372f..37df7ff4891 100644 --- a/src/csharp/Grpc.Core/VersionInfo.cs +++ b/src/csharp/Grpc.Core/VersionInfo.cs @@ -53,6 +53,6 @@ namespace Grpc.Core /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.0.0-pre1"; + public const string CurrentVersion = "1.0.0-pre2"; } } diff --git a/src/csharp/Grpc.Core/project.json b/src/csharp/Grpc.Core/project.json index 7a676f59a64..20cff429f4f 100644 --- a/src/csharp/Grpc.Core/project.json +++ b/src/csharp/Grpc.Core/project.json @@ -1,5 +1,5 @@ { - "version": "1.0.0-pre1", + "version": "1.0.0-pre2", "title": "gRPC C# Core", "authors": [ "Google Inc." ], "copyright": "Copyright 2015, Google Inc.", diff --git a/src/csharp/Grpc.HealthCheck/project.json b/src/csharp/Grpc.HealthCheck/project.json index 906dda36247..99da06a026d 100644 --- a/src/csharp/Grpc.HealthCheck/project.json +++ b/src/csharp/Grpc.HealthCheck/project.json @@ -1,5 +1,5 @@ { - "version": "1.0.0-pre1", + "version": "1.0.0-pre2", "title": "gRPC C# Healthchecking", "authors": [ "Google Inc." ], "copyright": "Copyright 2015, Google Inc.", @@ -22,7 +22,7 @@ } }, "dependencies": { - "Grpc.Core": "1.0.0-pre1", + "Grpc.Core": "1.0.0-pre2", "Google.Protobuf": "3.0.0-beta3" }, "frameworks": { diff --git a/src/csharp/build_packages.bat b/src/csharp/build_packages.bat index ffb70addad5..1d40ef9eb2d 100644 --- a/src/csharp/build_packages.bat +++ b/src/csharp/build_packages.bat @@ -30,7 +30,7 @@ @rem Builds gRPC NuGet packages @rem Current package versions -set VERSION=1.0.0-pre1 +set VERSION=1.0.0-pre2 set PROTOBUF_VERSION=3.0.0-beta3 @rem Packages that depend on prerelease packages (like Google.Protobuf) need to have prerelease suffix as well. diff --git a/src/node/health_check/package.json b/src/node/health_check/package.json index 582d5601016..1bb946adbdf 100644 --- a/src/node/health_check/package.json +++ b/src/node/health_check/package.json @@ -1,6 +1,6 @@ { "name": "grpc-health-check", - "version": "1.0.0-pre1", + "version": "1.0.0-pre2", "author": "Google Inc.", "description": "Health check service for use with gRPC", "repository": { diff --git a/src/node/tools/package.json b/src/node/tools/package.json index 7efa0d3f402..8ae51741785 100644 --- a/src/node/tools/package.json +++ b/src/node/tools/package.json @@ -1,6 +1,6 @@ { "name": "grpc-tools", - "version": "1.0.0-pre1", + "version": "1.0.0-pre2", "author": "Google Inc.", "description": "Tools for developing with gRPC on Node.js", "homepage": "http://www.grpc.io/", diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index d1e2d418c32..c5c358cbb9d 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -29,4 +29,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION='1.0.0rc1' +VERSION='1.0.0rc2' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 2e48fde8931..4bc1f3ffb18 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -29,4 +29,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION='1.0.0rc1' +VERSION='1.0.0rc2' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index a2387857c6c..16e4eb8ba73 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -29,4 +29,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION='1.0.0rc1' +VERSION='1.0.0rc2' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index e57fb3c14f8..9e53780e447 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -29,5 +29,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.0.0.pre1' + VERSION = '1.0.0.pre2' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 2e318b82ad5..84c03b255d5 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -29,6 +29,6 @@ module GRPC module Tools - VERSION = '1.0.0.pre1' + VERSION = '1.0.0.pre2' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 7938b3d0293..91f6849e476 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -29,4 +29,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION='1.0.0rc1' +VERSION='1.0.0rc2' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index fa4b50f8f3c..db3d27c5f6b 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.0.0-pre1 +PROJECT_NUMBER = 1.0.0-pre2 # 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 1473594dfc6..9ff396a7cf3 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.0.0-pre1 +PROJECT_NUMBER = 1.0.0-pre2 # 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.core b/tools/doxygen/Doxyfile.core index 7619b957343..696bf4c7dc3 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.0.0-pre1 +PROJECT_NUMBER = 1.0.0-pre2 # 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.core.internal b/tools/doxygen/Doxyfile.core.internal index 66d615664f1..44c17f36157 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.0.0-pre1 +PROJECT_NUMBER = 1.0.0-pre2 # 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 4bb2eb2241ce3793b57245abfd4164825badbd59 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 29 Jul 2016 13:59:43 -0700 Subject: [PATCH 091/279] Reset all host configs *before* setting what we need Not after :) This fixes the local server tests failing to SSL handshake. --- src/objective-c/tests/InteropTestsLocalCleartext.m | 4 ++-- src/objective-c/tests/InteropTestsLocalSSL.m | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/objective-c/tests/InteropTestsLocalCleartext.m b/src/objective-c/tests/InteropTestsLocalCleartext.m index 56927a8af6d..c4ee0de7054 100644 --- a/src/objective-c/tests/InteropTestsLocalCleartext.m +++ b/src/objective-c/tests/InteropTestsLocalCleartext.m @@ -48,10 +48,10 @@ static NSString * const kLocalCleartextHost = @"localhost:5050"; } - (void)setUp { + [super setUp]; + // Register test server as non-SSL. [GRPCCall useInsecureConnectionsForHost:kLocalCleartextHost]; - - [super setUp]; } @end diff --git a/src/objective-c/tests/InteropTestsLocalSSL.m b/src/objective-c/tests/InteropTestsLocalSSL.m index f0f4b1d71f0..27f025e6143 100644 --- a/src/objective-c/tests/InteropTestsLocalSSL.m +++ b/src/objective-c/tests/InteropTestsLocalSSL.m @@ -48,13 +48,13 @@ static NSString * const kLocalSSLHost = @"localhost:5051"; } - (void)setUp { + [super setUp]; + // Register test server certificates and name. NSBundle *bundle = [NSBundle bundleForClass:self.class]; NSString *certsPath = [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; [GRPCCall useTestCertsPath:certsPath testName:@"foo.test.google.fr" forHost:kLocalSSLHost]; - - [super setUp]; } - (void)testExceptions { From 4343c904e23a49e6e568579374c6b3d99e9afda7 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 29 Jul 2016 15:39:45 -0700 Subject: [PATCH 092/279] Update Protobuf submodule to v3.0.0 (GA) --- .gitmodules | 2 +- examples/cpp/helloworld/Makefile | 2 +- examples/cpp/route_guide/Makefile | 2 +- third_party/protobuf | 2 +- tools/run_tests/sanity/check_submodules.sh | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitmodules b/.gitmodules index 98bedade522..d41b8d5213f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,7 +4,7 @@ [submodule "third_party/protobuf"] path = third_party/protobuf url = https://github.com/google/protobuf.git - branch = 3.0.0-beta-4 + branch = 3.0.0-GA [submodule "third_party/gflags"] path = third_party/gflags url = https://github.com/gflags/gflags.git diff --git a/examples/cpp/helloworld/Makefile b/examples/cpp/helloworld/Makefile index 8e6bd96c6ac..67a16f2585b 100644 --- a/examples/cpp/helloworld/Makefile +++ b/examples/cpp/helloworld/Makefile @@ -97,7 +97,7 @@ ifneq ($(HAS_VALID_PROTOC),true) @echo "Please install Google protocol buffers 3.0.0 and its compiler." @echo "You can find it here:" @echo - @echo " https://github.com/google/protobuf/releases/tag/v3.0.0-beta-4" + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0" @echo @echo "Here is what I get when trying to evaluate your version of protoc:" @echo diff --git a/examples/cpp/route_guide/Makefile b/examples/cpp/route_guide/Makefile index c29bcaf9fe7..df40b04f32d 100644 --- a/examples/cpp/route_guide/Makefile +++ b/examples/cpp/route_guide/Makefile @@ -86,7 +86,7 @@ ifneq ($(HAS_VALID_PROTOC),true) @echo "Please install Google protocol buffers 3.0.0 and its compiler." @echo "You can find it here:" @echo - @echo " https://github.com/google/protobuf/releases/tag/v3.0.0-beta-4" + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0" @echo @echo "Here is what I get when trying to evaluate your version of protoc:" @echo diff --git a/third_party/protobuf b/third_party/protobuf index 4b36284bdfd..e8ae137c964 160000 --- a/third_party/protobuf +++ b/third_party/protobuf @@ -1 +1 @@ -Subproject commit 4b36284bdfdc77896d7c4cb9645433cf86efb069 +Subproject commit e8ae137c96444ea313485ed1118c5e43b2099cf1 diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh index a03d6f07171..04123ee5d8a 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -45,7 +45,7 @@ cat << EOF | awk '{ print $1 }' | sort > $want_submodules 05b155ff59114735ec8cd089f669c4c3d8f59029 third_party/gflags (v2.1.0-45-g05b155f) c99458533a9b4c743ed51537e25989ea55944908 third_party/googletest (release-1.7.0) f8ac463766281625ad710900479130c7fcb4d63b third_party/nanopb (nanopb-0.3.4-29-gf8ac463) - 4b36284bdfdc77896d7c4cb9645433cf86efb069 third_party/protobuf (v3.0.0-beta-4-3-g4b36284) + e8ae137c96444ea313485ed1118c5e43b2099cf1 third_party/protobuf (v3.0.0-beta-4-74-ge8ae137) 50893291621658f355bc5b4d450a8d06a563053d third_party/zlib (v1.2.8) EOF From 72dce2dfbca4503f6d99c59b793c8e6cfe0ce849 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 29 Jul 2016 15:42:00 -0700 Subject: [PATCH 093/279] Update podspecs to use Protobuf 3.0.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SwiftSample doesn’t build in this commit, but I need to sync with head anyway so I’ll first merge v1.0.x into this branch and then debug. --- examples/objective-c/auth_sample/AuthTestService.podspec | 2 +- examples/objective-c/helloworld/HelloWorld.podspec | 2 +- examples/objective-c/route_guide/RouteGuide.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 4 ++-- src/objective-c/!ProtoCompiler.podspec | 4 ++-- src/objective-c/README.md | 2 +- src/objective-c/examples/RemoteTestClient/RemoteTest.podspec | 2 +- src/objective-c/tests/RemoteTestClient/RemoteTest.podspec | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/objective-c/auth_sample/AuthTestService.podspec b/examples/objective-c/auth_sample/AuthTestService.podspec index b03b3fe82d3..afccf08bbf1 100644 --- a/examples/objective-c/auth_sample/AuthTestService.podspec +++ b/examples/objective-c/auth_sample/AuthTestService.podspec @@ -14,7 +14,7 @@ Pod::Spec.new do |s| src = "../../protos" # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.1" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.2" # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = 'Pods' diff --git a/examples/objective-c/helloworld/HelloWorld.podspec b/examples/objective-c/helloworld/HelloWorld.podspec index 8168e8a492c..9f07bd6b305 100644 --- a/examples/objective-c/helloworld/HelloWorld.podspec +++ b/examples/objective-c/helloworld/HelloWorld.podspec @@ -14,7 +14,7 @@ Pod::Spec.new do |s| src = "../../protos" # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.1" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.2" # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = 'Pods' diff --git a/examples/objective-c/route_guide/RouteGuide.podspec b/examples/objective-c/route_guide/RouteGuide.podspec index 50a2e5c9620..7e7e01d8781 100644 --- a/examples/objective-c/route_guide/RouteGuide.podspec +++ b/examples/objective-c/route_guide/RouteGuide.podspec @@ -14,7 +14,7 @@ Pod::Spec.new do |s| src = "../../protos" # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.1" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.2" # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = 'Pods' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 741067b23f4..b75be448ef2 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -61,7 +61,7 @@ Pod::Spec.new do |s| s.dependency 'gRPC', version s.dependency 'gRPC-RxLibrary', version - s.dependency 'Protobuf', '~> 3.0.0-beta-3.1' + s.dependency 'Protobuf', '~> 3.0' # This is needed by all pods that depend on Protobuf: s.pod_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 4e8a8de3040..07d62d20479 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -37,7 +37,7 @@ Pod::Spec.new do |s| # before them. s.name = '!ProtoCompiler-gRPCPlugin' v = '1.0.0-pre1' - s.version = "#{v}.1" # .1 to depend on protoc 3.0.0-beta-4 + s.version = "#{v}.2" # .2 to depend on protoc 3.0.0 s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC This podspec only downloads the gRPC protoc plugin so that local pods generating protos can use @@ -96,7 +96,7 @@ Pod::Spec.new do |s| s.preserve_paths = plugin # Restrict the protoc version to the one supported by this plugin. - s.dependency '!ProtoCompiler', '3.0.0-beta-4' + s.dependency '!ProtoCompiler', '3.0.0' # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.1' s.osx.deployment_target = '10.9' diff --git a/src/objective-c/!ProtoCompiler.podspec b/src/objective-c/!ProtoCompiler.podspec index 45fc1356719..5018dedc066 100644 --- a/src/objective-c/!ProtoCompiler.podspec +++ b/src/objective-c/!ProtoCompiler.podspec @@ -36,7 +36,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' - v = '3.0.0-beta-4' + v = '3.0.0' s.version = v s.summary = 'The Protobuf Compiler (protoc) generates Objective-C files from .proto files' s.description = <<-DESC @@ -108,7 +108,7 @@ Pod::Spec.new do |s| 'google/**/*.proto' # Well-known protobuf types # Restrict the protobuf runtime version to the one supported by this version of protoc. - s.dependency 'Protobuf', v + s.dependency 'Protobuf', '~> 3.0' # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.1' s.osx.deployment_target = '10.9' diff --git a/src/objective-c/README.md b/src/objective-c/README.md index 6e917ddd813..909b12bab2d 100644 --- a/src/objective-c/README.md +++ b/src/objective-c/README.md @@ -48,7 +48,7 @@ Pod::Spec.new do |s| src = '.' # We'll use protoc with the gRPC plugin. - s.dependency '!ProtoCompiler-gRPCPlugin', '~> 1.0.0-pre1' + s.dependency '!ProtoCompiler-gRPCPlugin', '~> 1.0.0-pre1.2' # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = '/Pods' diff --git a/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec b/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec index e1ed9b69d3c..974a6765c70 100644 --- a/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec +++ b/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec @@ -11,7 +11,7 @@ Pod::Spec.new do |s| s.osx.deployment_target = '10.9' # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.1" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.2" repo_root = '../../../..' bin_dir = "#{repo_root}/bins/$CONFIG" diff --git a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec index 711061b6041..3d28234fa23 100644 --- a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec +++ b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec @@ -11,7 +11,7 @@ Pod::Spec.new do |s| s.osx.deployment_target = '10.9' # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.1" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.2" repo_root = '../../../..' bin_dir = "#{repo_root}/bins/$CONFIG" From 8a9fe2ad9705089b91bff9ab3b2ef5a6011326ee Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 29 Jul 2016 15:44:47 -0700 Subject: [PATCH 094/279] nit: format ObjC test targets better So they can be commented out. --- tools/run_tests/run_tests.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 95d53e5f9e5..6e1db97f3b3 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -649,14 +649,16 @@ class ObjCLanguage(object): _check_compiler(self.args.compiler, ['default']) def test_specs(self): - return [self.config.job_spec(['src/objective-c/tests/run_tests.sh'], - timeout_seconds=None, - shortname='objc-tests', - environ=_FORCE_ENVIRON_FOR_WRAPPERS), - self.config.job_spec(['src/objective-c/tests/build_example_test.sh'], - timeout_seconds=15*60, - shortname='objc-examples-build', - environ=_FORCE_ENVIRON_FOR_WRAPPERS)] + return [ + self.config.job_spec(['src/objective-c/tests/run_tests.sh'], + timeout_seconds=None, + shortname='objc-tests', + environ=_FORCE_ENVIRON_FOR_WRAPPERS), + self.config.job_spec(['src/objective-c/tests/build_example_test.sh'], + timeout_seconds=15*60, + shortname='objc-examples-build', + environ=_FORCE_ENVIRON_FOR_WRAPPERS), + ] def pre_build_steps(self): return [] From fb3a71d9c095623eacde0a42ec6ad118c69fb2b2 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 29 Jul 2016 15:58:10 -0700 Subject: [PATCH 095/279] Fix usage of proto message parsing On account of https://github.com/google/protobuf/pull/1712 --- src/objective-c/examples/SwiftSample/ViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/examples/SwiftSample/ViewController.swift b/src/objective-c/examples/SwiftSample/ViewController.swift index e7bab137620..66d4fa9412c 100644 --- a/src/objective-c/examples/SwiftSample/ViewController.swift +++ b/src/objective-c/examples/SwiftSample/ViewController.swift @@ -91,7 +91,7 @@ class ViewController: UIViewController { call.startWithWriteable(GRXWriteable { response, error in if let response = response as? NSData { - NSLog("3. Received response:\n\(RMTSimpleResponse(data: response, error: nil))") + NSLog("3. Received response:\n\(try! RMTSimpleResponse(data: response))") } else { NSLog("3. Finished with error: \(error!)") } From 4d440bbd452cec3f7c6aa798943b0b4c3fc6e9e9 Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Fri, 29 Jul 2016 16:09:15 -0700 Subject: [PATCH 096/279] added windows to INSTALL.md --- INSTALL.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/INSTALL.md b/INSTALL.md index 6718aad120d..14be87f8782 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -55,3 +55,55 @@ gRPC C Core library. $ make $ [sudo] make install ``` + +##Windows + +There are several way to build under Windows, of varying complexity depending on +experience with the tools involved. + + + +###msys2 + +This approach requires having [msys2](https://msys2.github.io/) installed. + +- The Makefile (and source code) should support msys2's mingw32 and mingw64 + compilers. Building with msys2's native compiler is also possible, but + difficult. +- The Makefile is expecting the Windows versions of OpenSSL (see + https://slproweb.com/products/Win32OpenSSL.html). It's also possible to build + the Windows version of OpenSSL from scratch. The output should be `libeay32` + and `ssleay32`. +- If you are not installing the above files under msys2's path, you may specify + it, for instance, in the following way: + ```CPPFLAGS=â€-I/c/OpenSSL-Win32/include†LDFLAGS=â€-L/c/OpenSSL-Win32/lib†make static_c``` +- [protobuf3](https://github.com/google/protobuf/blob/master/src/README.md#c-installation---windows) + must be installed on the msys2 path. + +###Cmake (experimental) + +- Install [CMake](https://cmake.org/download/). +- Run it over [grpc's + CMakeLists.txt](https://github.com/grpc/grpc/blob/master/CMakeLists.txt) to + generate "projects" for your compiler. +- Build with your compiler of choice. The generated build files should have the + protobuf3 dependency baked in. From ff47bc0daf9c6081506e4ec462208cc990c7cde1 Mon Sep 17 00:00:00 2001 From: Makarand Dharmapurikar Date: Fri, 29 Jul 2016 16:55:35 -0700 Subject: [PATCH 097/279] rewrite the core logic to work with end to end tests. --- .../cronet/transport/cronet_transport.c | 992 +++++++----------- 1 file changed, 380 insertions(+), 612 deletions(-) diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c index 0a079927ea8..694d346fc33 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.c +++ b/src/core/ext/transport/cronet/transport/cronet_transport.c @@ -51,8 +51,41 @@ #define GRPC_HEADER_SIZE_IN_BYTES 5 -// Global flag that gets set with GRPC_TRACE env variable -int grpc_cronet_trace = 1; +enum OP_ID { + OP_SEND_INITIAL_METADATA = 0, + OP_SEND_MESSAGE, + OP_SEND_TRAILING_METADATA, + OP_RECV_MESSAGE, + OP_RECV_INITIAL_METADATA, + OP_RECV_TRAILING_METADATA, + OP_CANCEL_ERROR, + OP_ON_COMPLETE, + OP_NUM_OPS +}; + +/* Cronet callbacks */ + +static void on_request_headers_sent(cronet_bidirectional_stream *); +static void on_response_headers_received(cronet_bidirectional_stream *, + const cronet_bidirectional_stream_header_array *, + const char *); +static void on_write_completed(cronet_bidirectional_stream *, const char *); +static void on_read_completed(cronet_bidirectional_stream *, char *, int); +static void on_response_trailers_received(cronet_bidirectional_stream *, + const cronet_bidirectional_stream_header_array *); +static void on_succeeded(cronet_bidirectional_stream *); +static void on_failed(cronet_bidirectional_stream *, int); +//static void on_canceled(cronet_bidirectional_stream *); +static cronet_bidirectional_stream_callback cronet_callbacks = { + on_request_headers_sent, + on_response_headers_received, + on_read_completed, + on_write_completed, + on_response_trailers_received, + on_succeeded, + on_failed, + NULL //on_canceled +}; // Cronet transport object struct grpc_cronet_transport { @@ -60,428 +93,198 @@ struct grpc_cronet_transport { cronet_engine *engine; char *host; }; - typedef struct grpc_cronet_transport grpc_cronet_transport; -enum send_state { - CRONET_SEND_IDLE = 0, - CRONET_SEND_HEADER, - CRONET_WRITE_PENDING, - CRONET_WRITE_COMPLETED, - CRONET_WAIT_FOR_CANCEL, - CRONET_STREAM_CLOSED, -}; +struct read_state { + // vars to store data coming from cronet + char *read_buffer; + bool length_field_received; + int received_bytes; + int remaining_bytes; + int length_field; + char grpc_header_bytes[GRPC_HEADER_SIZE_IN_BYTES]; + char *payload_field; + + // vars for holding data destined for the application + struct grpc_slice_buffer_stream sbs; + gpr_slice_buffer read_slice_buffer; -enum recv_state { - CRONET_RECV_IDLE = 0, - CRONET_RECV_READ_LENGTH, - CRONET_RECV_READ_DATA, - CRONET_RECV_CLOSED, -}; + // vars for trailing metadata + grpc_chttp2_incoming_metadata_buffer trailing_metadata; + bool trailing_metadata_valid; -static const char *recv_state_name[] = { - "CRONET_RECV_IDLE", "CRONET_RECV_READ_LENGTH", "CRONET_RECV_READ_DATA,", - "CRONET_RECV_CLOSED"}; + // vars for initial metadata + grpc_chttp2_incoming_metadata_buffer initial_metadata; +}; -// Enum that identifies calling function. -enum e_caller { - PERFORM_STREAM_OP, - ON_READ_COMPLETE, - ON_RESPONSE_HEADERS_RECEIVED, - ON_RESPONSE_TRAILERS_RECEIVED +struct write_state { + char *write_buffer; }; -enum callback_id { - OP_SEND_INITIAL_METADATA = 0, - OP_SEND_MESSAGE, - OP_SEND_TRAILING_METADATA, - OP_RECV_MESSAGE, - OP_RECV_INITIAL_METADATA, - OP_RECV_TRAILING_METADATA, - OP_CANCEL_ERROR, - OP_NUM_CALLBACKS +#define MAX_PENDING_OPS 10 +struct op_storage { + grpc_transport_stream_op pending_ops[MAX_PENDING_OPS]; + int wrptr; + int rdptr; + int num_pending_ops; }; struct stream_obj { - // we store received bytes here as they trickle in. - gpr_slice_buffer write_slice_buffer; + grpc_transport_stream_op *curr_op; + grpc_cronet_transport curr_ct; + grpc_stream *curr_gs; cronet_bidirectional_stream *cbs; - gpr_slice slice; - gpr_slice_buffer read_slice_buffer; - struct grpc_slice_buffer_stream sbs; - char *read_buffer; - int remaining_read_bytes; - int total_read_bytes; - - char *write_buffer; - size_t write_buffer_size; - // Hold the URL - char *url; + // TODO (makdharma) : make a sub structure for tracking state + bool state_op_done[OP_NUM_OPS]; + bool state_callback_received[OP_NUM_OPS]; - // One bit per operation - bool op_requested[OP_NUM_CALLBACKS]; - bool op_done[OP_NUM_CALLBACKS]; - // Set to true when server indicates no more data will be sent - bool read_closed; - - // Recv message stuff - grpc_byte_buffer **recv_message; - // Initial metadata stuff - grpc_metadata_batch *recv_initial_metadata; - grpc_chttp2_incoming_metadata_buffer initial_metadata; - // Trailing metadata stuff - grpc_metadata_batch *recv_trailing_metadata; - grpc_chttp2_incoming_metadata_buffer imb; - bool imb_valid; // true if there are any valid entries in imb. - - // This mutex protects receive state machine execution - gpr_mu recv_mu; - - // Callbacks to be called when operations complete - grpc_closure *cb_recv_initial_metadata_ready; - grpc_closure *cb_recv_message_ready; - grpc_closure *on_complete; - - // storage for header - cronet_bidirectional_stream_header *headers; - uint32_t num_headers; - cronet_bidirectional_stream_header_array header_array; - // state tracking - enum recv_state cronet_recv_state; - enum send_state cronet_send_state; + // Read state + struct read_state rs; + // Write state + struct write_state ws; + // OP storage + struct op_storage storage; }; - typedef struct stream_obj stream_obj; -static void next_send_step(stream_obj *s); -static void next_recv_step(stream_obj *s, enum e_caller caller); +/* Globals */ +cronet_bidirectional_stream_header_array header_array; -static void set_pollset_do_nothing(grpc_exec_ctx *exec_ctx, grpc_transport *gt, - grpc_stream *gs, grpc_pollset *pollset) {} - -static void set_pollset_set_do_nothing(grpc_exec_ctx *exec_ctx, - grpc_transport *gt, grpc_stream *gs, - grpc_pollset_set *pollset_set) {} - -// Client creates a bunch of operations and invokes "call_start_batch" -// call_start_batch creates a stream_op structure. this structure has info -// needed for executing all the ops. It has on_complete callback that needs -// to be called when all ops are executed. This function keeps track of all -// outstanding operations. It returns true if all operations that were part of -// the stream_op have been completed. -static bool is_op_complete(stream_obj *s) { - int i; - // Check if any requested op is pending - for (i = 0; i < OP_NUM_CALLBACKS; i++) { - if (s->op_requested[i] && !s->op_done[i]) { - gpr_log(GPR_DEBUG, "is_op_complete is FALSE because of %d", i); - return false; - } - } - // Clear the requested/done bits and return true - for (i = 0; i < OP_NUM_CALLBACKS; i++) { - s->op_requested[i] = s->op_done[i] = false; - } - return true; -} - -static void enqueue_callback(grpc_closure *callback) { - GPR_ASSERT(callback); - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_exec_ctx_sched(&exec_ctx, callback, GRPC_ERROR_NONE, NULL); - grpc_exec_ctx_finish(&exec_ctx); +// +static void execute_curr_stream_op(stream_obj *s); + +/************************************************************* + Op Storage +*/ + +static void add_pending_op(struct op_storage *storage, grpc_transport_stream_op *op) { + GPR_ASSERT(storage->num_pending_ops < MAX_PENDING_OPS); + storage->num_pending_ops++; + gpr_log(GPR_DEBUG, "adding new op @wrptr=%d. %d in the queue.", + storage->wrptr, storage->num_pending_ops); + memcpy(&storage->pending_ops[storage->wrptr], op, sizeof(grpc_transport_stream_op)); + storage->wrptr = (storage->wrptr + 1) % MAX_PENDING_OPS; } -static void on_canceled(cronet_bidirectional_stream *stream) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "on_canceled(%p)", stream); - } - stream_obj *s = (stream_obj *)stream->annotation; - s->op_done[OP_CANCEL_ERROR] = true; - - // Terminate any read callback - if (s->cb_recv_message_ready) { - enqueue_callback(s->cb_recv_message_ready); - s->cb_recv_message_ready = 0; - s->op_done[OP_RECV_MESSAGE] = true; - } - // Don't wait to get any trailing metadata - s->op_done[OP_RECV_TRAILING_METADATA] = true; - - next_send_step(s); +static grpc_transport_stream_op *pop_pending_op(struct op_storage *storage) { + if (storage->num_pending_ops == 0) return NULL; + grpc_transport_stream_op *result = &storage->pending_ops[storage->rdptr]; + storage->rdptr = (storage->rdptr + 1) % MAX_PENDING_OPS; + storage->num_pending_ops--; + gpr_log(GPR_DEBUG, "popping op @rdptr=%d. %d more left in queue", + storage->rdptr, storage->num_pending_ops); + return result; } +/************************************************************* +Cronet Callback Ipmlementation +*/ static void on_failed(cronet_bidirectional_stream *stream, int net_error) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "on_failed(%p, %d)", stream, net_error); - } + gpr_log(GPR_DEBUG, "on_failed(%p, %d)", stream, net_error); } static void on_succeeded(cronet_bidirectional_stream *stream) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "on_succeeded(%p)", stream); - } -} - -static void on_response_trailers_received( - cronet_bidirectional_stream *stream, - const cronet_bidirectional_stream_header_array *trailers) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "R: on_response_trailers_received(%p,%p)", stream, - trailers); - } - stream_obj *s = (stream_obj *)stream->annotation; - - memset(&s->imb, 0, sizeof(s->imb)); - s->imb_valid = false; - grpc_chttp2_incoming_metadata_buffer_init(&s->imb); - unsigned int i = 0; - for (i = 0; i < trailers->count; i++) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "trailer key=%s, value=%s", trailers->headers[i].key, - trailers->headers[i].value); - } - - grpc_chttp2_incoming_metadata_buffer_add( - &s->imb, grpc_mdelem_from_metadata_strings( - grpc_mdstr_from_string(trailers->headers[i].key), - grpc_mdstr_from_string(trailers->headers[i].value))); - s->imb_valid = true; - } - s->op_done[OP_RECV_TRAILING_METADATA] = true; - next_recv_step(s, ON_RESPONSE_TRAILERS_RECEIVED); + gpr_log(GPR_DEBUG, "on_succeeded(%p)", stream); } -static void on_write_completed(cronet_bidirectional_stream *stream, - const char *data) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "W: on_write_completed(%p, %s)", stream, data); - } - stream_obj *s = (stream_obj *)stream->annotation; - s->op_done[OP_SEND_MESSAGE] = true; - next_send_step(s); -} -static void process_recv_message(stream_obj *s, const uint8_t *recv_data) { - gpr_slice read_data_slice = gpr_slice_malloc((uint32_t)s->total_read_bytes); - uint8_t *dst_p = GPR_SLICE_START_PTR(read_data_slice); - if (s->total_read_bytes > 0) { - // Only copy if there is non-zero number of bytes - memcpy(dst_p, recv_data, (size_t)s->total_read_bytes); - gpr_slice_buffer_add(&s->read_slice_buffer, read_data_slice); - } - grpc_slice_buffer_stream_init(&s->sbs, &s->read_slice_buffer, 0); - *s->recv_message = (grpc_byte_buffer *)&s->sbs; -} - -static int parse_grpc_header(const uint8_t *data) { - const uint8_t *p = data + 1; - int length = 0; - length |= ((uint8_t)*p++) << 24; - length |= ((uint8_t)*p++) << 16; - length |= ((uint8_t)*p++) << 8; - length |= ((uint8_t)*p++); - return length; -} - -static void on_read_completed(cronet_bidirectional_stream *stream, char *data, - int count) { +static void on_request_headers_sent(cronet_bidirectional_stream *stream) { + gpr_log(GPR_DEBUG, "W: on_request_headers_sent(%p)", stream); stream_obj *s = (stream_obj *)stream->annotation; - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "R: on_read_completed(%p, %p, %d)", stream, data, count); - } - if (count > 0) { - GPR_ASSERT(s->recv_message); - s->remaining_read_bytes -= count; - next_recv_step(s, ON_READ_COMPLETE); - } else { - gpr_log(GPR_DEBUG, "read_closed = true"); - s->read_closed = true; - next_recv_step(s, ON_READ_COMPLETE); - } + s->state_op_done[OP_SEND_INITIAL_METADATA] = true; + s->state_callback_received[OP_SEND_INITIAL_METADATA] = true; + execute_curr_stream_op(s); } static void on_response_headers_received( cronet_bidirectional_stream *stream, const cronet_bidirectional_stream_header_array *headers, const char *negotiated_protocol) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "R: on_response_headers_received(%p, %p, %s)", stream, + gpr_log(GPR_DEBUG, "R: on_response_headers_received(%p, %p, %s)", stream, headers, negotiated_protocol); - } - stream_obj *s = (stream_obj *)stream->annotation; - memset(&s->initial_metadata, 0, sizeof(s->initial_metadata)); - grpc_chttp2_incoming_metadata_buffer_init(&s->initial_metadata); + stream_obj *s = (stream_obj *)stream->annotation; + memset(&s->rs.initial_metadata, 0, sizeof(s->rs.initial_metadata)); + grpc_chttp2_incoming_metadata_buffer_init(&s->rs.initial_metadata); unsigned int i = 0; for (i = 0; i < headers->count; i++) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "header key=%s, value=%s", headers->headers[i].key, - headers->headers[i].value); - } grpc_chttp2_incoming_metadata_buffer_add( - &s->initial_metadata, + &s->rs.initial_metadata, grpc_mdelem_from_metadata_strings( grpc_mdstr_from_string(headers->headers[i].key), grpc_mdstr_from_string(headers->headers[i].value))); } - - grpc_chttp2_incoming_metadata_buffer_publish(&s->initial_metadata, - s->recv_initial_metadata); - enqueue_callback(s->cb_recv_initial_metadata_ready); - s->op_done[OP_RECV_INITIAL_METADATA] = true; - next_recv_step(s, ON_RESPONSE_HEADERS_RECEIVED); + s->state_callback_received[OP_RECV_INITIAL_METADATA] = true; + execute_curr_stream_op(s); } -static void on_request_headers_sent(cronet_bidirectional_stream *stream) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "W: on_request_headers_sent(%p)", stream); - } +static void on_write_completed(cronet_bidirectional_stream *stream, + const char *data) { + gpr_log(GPR_DEBUG, "W: on_write_completed(%p, %s)", stream, data); stream_obj *s = (stream_obj *)stream->annotation; - s->op_done[OP_SEND_INITIAL_METADATA] = true; - next_send_step(s); -} - -// Callback function pointers (invoked by cronet in response to events) -static cronet_bidirectional_stream_callback callbacks = { - on_request_headers_sent, - on_response_headers_received, - on_read_completed, - on_write_completed, - on_response_trailers_received, - on_succeeded, - on_failed, - on_canceled}; - -static void invoke_closing_callback(stream_obj *s) { - if (!is_op_complete(s)) return; - - if (s->imb_valid) { - grpc_chttp2_incoming_metadata_buffer_publish(&s->imb, - s->recv_trailing_metadata); + if (s->ws.write_buffer) { + gpr_free(s->ws.write_buffer); + s->ws.write_buffer = NULL; } - enqueue_callback(s->on_complete); + s->state_callback_received[OP_SEND_MESSAGE] = true; + execute_curr_stream_op(s); } -static void set_recv_state(stream_obj *s, enum recv_state state) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "next_state = %s", recv_state_name[state]); +static void on_read_completed(cronet_bidirectional_stream *stream, char *data, + int count) { + stream_obj *s = (stream_obj *)stream->annotation; + gpr_log(GPR_DEBUG, "R: on_read_completed(%p, %p, %d)", stream, data, count); + if (count > 0) { + s->rs.received_bytes += count; + s->rs.remaining_bytes -= count; + if (s->rs.remaining_bytes > 0) { + gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_read"); + cronet_bidirectional_stream_read(s->cbs, s->rs.read_buffer + s->rs.received_bytes, s->rs.remaining_bytes); + } else { + execute_curr_stream_op(s); + } + s->state_callback_received[OP_RECV_MESSAGE] = true; } - s->cronet_recv_state = state; } -// This is invoked from perform_stream_op, and all on_xxxx callbacks. -static void next_recv_step(stream_obj *s, enum e_caller caller) { - // gpr_log(GPR_DEBUG, "locking mutex %p", &s->recv_mu); - gpr_mu_lock(&s->recv_mu); - switch (s->cronet_recv_state) { - case CRONET_RECV_IDLE: - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "cronet_recv_state = CRONET_RECV_IDLE, caller=%d", - caller); - } - if (caller == PERFORM_STREAM_OP || - caller == ON_RESPONSE_HEADERS_RECEIVED) { - if (s->read_closed && s->op_done[OP_RECV_TRAILING_METADATA]) { - set_recv_state(s, CRONET_RECV_CLOSED); - } else if (s->op_done[OP_RECV_INITIAL_METADATA] == true && - s->op_requested[OP_RECV_MESSAGE]) { - set_recv_state(s, CRONET_RECV_READ_LENGTH); - s->total_read_bytes = s->remaining_read_bytes = - GRPC_HEADER_SIZE_IN_BYTES; - GPR_ASSERT(s->read_buffer); - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "R: cronet_bidirectional_stream_read(%p,%p,%d)", - s->cbs, s->read_buffer, s->remaining_read_bytes); - } - cronet_bidirectional_stream_read(s->cbs, s->read_buffer, - s->remaining_read_bytes); - } - } else if (caller == ON_RESPONSE_TRAILERS_RECEIVED) { - // We get here when we receive trailers directly, i.e. without - // going through a data read operation. - set_recv_state(s, CRONET_RECV_CLOSED); - } - break; - case CRONET_RECV_READ_LENGTH: - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "cronet_recv_state = CRONET_RECV_READ_LENGTH"); - } - if (caller == ON_READ_COMPLETE) { - if (s->read_closed) { - enqueue_callback(s->cb_recv_message_ready); - s->op_done[OP_RECV_MESSAGE] = true; - set_recv_state(s, CRONET_RECV_CLOSED); - } else { - GPR_ASSERT(s->remaining_read_bytes == 0); - set_recv_state(s, CRONET_RECV_READ_DATA); - s->total_read_bytes = s->remaining_read_bytes = - parse_grpc_header((const uint8_t *)s->read_buffer); - s->read_buffer = - gpr_realloc(s->read_buffer, (uint32_t)s->remaining_read_bytes); - GPR_ASSERT(s->read_buffer); - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "R: cronet_bidirectional_stream_read(%p,%p,%d)", - s->cbs, s->read_buffer, s->remaining_read_bytes); - } - if (s->remaining_read_bytes > 0) { - cronet_bidirectional_stream_read(s->cbs, (char *)s->read_buffer, - s->remaining_read_bytes); - } else { - // Calling the closing callback directly since this is a 0 byte read - // for an empty message. - process_recv_message(s, NULL); - enqueue_callback(s->cb_recv_message_ready); - s->op_done[OP_RECV_MESSAGE] = true; - set_recv_state(s, CRONET_RECV_CLOSED); - } - } - } - break; - case CRONET_RECV_READ_DATA: - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "cronet_recv_state = CRONET_RECV_READ_DATA"); - } - if (caller == ON_READ_COMPLETE) { - if (s->remaining_read_bytes > 0) { - int offset = s->total_read_bytes - s->remaining_read_bytes; - GPR_ASSERT(s->read_buffer); - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "R: cronet_bidirectional_stream_read()"); - } - cronet_bidirectional_stream_read( - s->cbs, (char *)s->read_buffer + offset, s->remaining_read_bytes); - } else { - gpr_slice_buffer_init(&s->read_slice_buffer); - uint8_t *p = (uint8_t *)s->read_buffer; - process_recv_message(s, p); - set_recv_state(s, CRONET_RECV_IDLE); - enqueue_callback(s->cb_recv_message_ready); - s->op_done[OP_RECV_MESSAGE] = true; - } - } - break; - case CRONET_RECV_CLOSED: - break; - default: - GPR_ASSERT(0); // Should not reach here - break; +static void on_response_trailers_received( + cronet_bidirectional_stream *stream, + const cronet_bidirectional_stream_header_array *trailers) { + gpr_log(GPR_DEBUG, "R: on_response_trailers_received(%p,%p)", stream, + trailers); + stream_obj *s = (stream_obj *)stream->annotation; + memset(&s->rs.trailing_metadata, 0, sizeof(s->rs.trailing_metadata)); + s->rs.trailing_metadata_valid = false; + grpc_chttp2_incoming_metadata_buffer_init(&s->rs.trailing_metadata); + unsigned int i = 0; + for (i = 0; i < trailers->count; i++) { + gpr_log(GPR_DEBUG, "trailer key=%s, value=%s", trailers->headers[i].key, + trailers->headers[i].value); + grpc_chttp2_incoming_metadata_buffer_add( + &s->rs.trailing_metadata, grpc_mdelem_from_metadata_strings( + grpc_mdstr_from_string(trailers->headers[i].key), + grpc_mdstr_from_string(trailers->headers[i].value))); + s->rs.trailing_metadata_valid = true; } - invoke_closing_callback(s); - gpr_mu_unlock(&s->recv_mu); - // gpr_log(GPR_DEBUG, "unlocking mutex %p", &s->recv_mu); + s->state_callback_received[OP_RECV_TRAILING_METADATA] = true; + execute_curr_stream_op(s); } +/************************************************************* +Utility functions. Can be in their own file +*/ // This function takes the data from s->write_slice_buffer and assembles into // a contiguous byte stream with 5 byte gRPC header prepended. -static void create_grpc_frame(stream_obj *s) { - gpr_slice slice = gpr_slice_buffer_take_first(&s->write_slice_buffer); - uint8_t *raw_data = GPR_SLICE_START_PTR(slice); +static void create_grpc_frame(gpr_slice_buffer *write_slice_buffer, + char **pp_write_buffer, int *p_write_buffer_size) { + gpr_slice slice = gpr_slice_buffer_take_first(write_slice_buffer); size_t length = GPR_SLICE_LENGTH(slice); - s->write_buffer_size = length + GRPC_HEADER_SIZE_IN_BYTES; - s->write_buffer = gpr_realloc(s->write_buffer, s->write_buffer_size); - uint8_t *p = (uint8_t *)s->write_buffer; + // TODO (makdharma): FREE THIS!! HACK! + *p_write_buffer_size = (int)length + GRPC_HEADER_SIZE_IN_BYTES; + char *write_buffer = gpr_malloc(length + GRPC_HEADER_SIZE_IN_BYTES); + *pp_write_buffer = write_buffer; + uint8_t *p = (uint8_t *)write_buffer; // Append 5 byte header *p++ = 0; *p++ = (uint8_t)(length >> 24); @@ -489,135 +292,22 @@ static void create_grpc_frame(stream_obj *s) { *p++ = (uint8_t)(length >> 8); *p++ = (uint8_t)(length); // append actual data - memcpy(p, raw_data, length); -} -// Return false if there is no data to write -static bool do_write(stream_obj *s) { - gpr_slice_buffer *sb = &s->write_slice_buffer; - GPR_ASSERT(sb->count <= 1); - if (sb->count > 0) { - create_grpc_frame(s); - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "W: cronet_bidirectional_stream_write(%p,%p,%d,%d)", - s->cbs, s->write_buffer, (int)s->write_buffer_size, false); - } - cronet_bidirectional_stream_write(s->cbs, s->write_buffer, - (int)s->write_buffer_size, false); - return true; - } else { - return false; - } + memcpy(p, GPR_SLICE_START_PTR(slice), length); } -static void init_cronet_stream(stream_obj *s, grpc_transport *gt) { - GPR_ASSERT(s->cbs == NULL); - grpc_cronet_transport *ct = (grpc_cronet_transport *)gt; - GPR_ASSERT(ct->engine); - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_create"); - } - s->cbs = cronet_bidirectional_stream_create(ct->engine, s, &callbacks); - GPR_ASSERT(s->cbs); - s->read_closed = false; - - for (int i = 0; i < OP_NUM_CALLBACKS; i++) { - s->op_requested[i] = s->op_done[i] = false; - } - s->cronet_send_state = CRONET_SEND_IDLE; - s->cronet_recv_state = CRONET_RECV_IDLE; -} - -static bool do_close_connection(stream_obj *s) { - s->op_done[OP_SEND_TRAILING_METADATA] = true; - if (s->cbs) { - // Send an "empty" write to the far end to signal that we're done. - // This will induce the server to send down trailers. - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "W: cronet_bidirectional_stream_write length 0"); - } - cronet_bidirectional_stream_write(s->cbs, "abc", 0, true); - return true; - } else { - // We never created a stream. This was probably an empty request. - invoke_closing_callback(s); - return true; - } - return false; -} - -// -static void next_send_step(stream_obj *s) { - gpr_log(GPR_DEBUG, "next_send_step cronet_send_state=%d", - s->cronet_send_state); - switch (s->cronet_send_state) { - case CRONET_SEND_IDLE: - GPR_ASSERT( - s->cbs); // cronet_bidirectional_stream is not initialized yet. - s->cronet_send_state = CRONET_SEND_HEADER; - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_start to %s", s->url); - } - cronet_bidirectional_stream_start(s->cbs, s->url, 0, "POST", - &s->header_array, false); - // we no longer need the memory that was allocated earlier. - gpr_free(s->header_array.headers); - break; - case CRONET_SEND_HEADER: - if (s->op_requested[OP_CANCEL_ERROR]) { - cronet_bidirectional_stream_cancel(s->cbs); - gpr_log(GPR_DEBUG, "W: cronet_bidirectional_stream_cancel(%p)", s->cbs); - s->cronet_send_state = CRONET_WAIT_FOR_CANCEL; - } else if (do_write(s) == false && - s->op_requested[OP_SEND_TRAILING_METADATA]) { - if (do_close_connection(s)) { - s->cronet_send_state = CRONET_STREAM_CLOSED; - } - } else { - s->cronet_send_state = CRONET_WRITE_PENDING; - } - break; - case CRONET_WRITE_PENDING: - if (s->op_requested[OP_CANCEL_ERROR]) { - cronet_bidirectional_stream_cancel(s->cbs); - gpr_log(GPR_DEBUG, "W: cronet_bidirectional_stream_cancel(%p)", s->cbs); - s->cronet_send_state = CRONET_WAIT_FOR_CANCEL; - } else if (do_write(s) == false && - s->op_requested[OP_SEND_TRAILING_METADATA]) { - if (do_close_connection(s)) { - s->cronet_send_state = CRONET_STREAM_CLOSED; - } - } else { - s->cronet_send_state = CRONET_WRITE_COMPLETED; - } - break; - case CRONET_WRITE_COMPLETED: - if (s->op_requested[OP_CANCEL_ERROR]) { - cronet_bidirectional_stream_cancel(s->cbs); - gpr_log(GPR_DEBUG, "W: cronet_bidirectional_stream_cancel(%p)", s->cbs); - s->cronet_send_state = CRONET_WAIT_FOR_CANCEL; - } else if (do_write(s) == false && - s->op_requested[OP_SEND_TRAILING_METADATA]) { - if (do_close_connection(s)) { - s->cronet_send_state = CRONET_STREAM_CLOSED; - } - } - break; - case CRONET_STREAM_CLOSED: - s->cronet_send_state = CRONET_SEND_IDLE; - break; - case CRONET_WAIT_FOR_CANCEL: - invoke_closing_callback(s); - s->cronet_send_state = CRONET_SEND_IDLE; - break; - default: - GPR_ASSERT(0); - break; - } +static void enqueue_callback(grpc_closure *callback) { + GPR_ASSERT(callback); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_exec_ctx_sched(&exec_ctx, callback, GRPC_ERROR_NONE, NULL); + grpc_exec_ctx_finish(&exec_ctx); } -static void convert_metadata_to_cronet_headers(grpc_linked_mdelem *head, - const char *host, - stream_obj *s) { +static void convert_metadata_to_cronet_headers( + grpc_linked_mdelem *head, + const char *host, + char **pp_url, + cronet_bidirectional_stream_header **pp_headers, + size_t *p_num_headers) { grpc_linked_mdelem *curr = head; // Walk the linked list and get number of header fields uint32_t num_headers_available = 0; @@ -625,17 +315,19 @@ static void convert_metadata_to_cronet_headers(grpc_linked_mdelem *head, curr = curr->next; num_headers_available++; } - // Allocate enough memory - s->headers = (cronet_bidirectional_stream_header *)gpr_malloc( + // Allocate enough memory. TODO (makdharma): FREE MEMORY! HACK HACK + cronet_bidirectional_stream_header *headers = + (cronet_bidirectional_stream_header *)gpr_malloc( sizeof(cronet_bidirectional_stream_header) * num_headers_available); + *pp_headers = headers; // Walk the linked list again, this time copying the header fields. // s->num_headers // can be less than num_headers_available, as some headers are not used for // cronet curr = head; - s->num_headers = 0; - while (s->num_headers < num_headers_available) { + int num_headers = 0; + while (num_headers < num_headers_available) { grpc_mdelem *mdelem = curr->md; curr = curr->next; const char *key = grpc_mdstr_as_c_string(mdelem->key); @@ -647,161 +339,237 @@ static void convert_metadata_to_cronet_headers(grpc_linked_mdelem *head, } if (strcmp(key, ":path") == 0) { // Create URL by appending :path value to the hostname - gpr_asprintf(&s->url, "https://%s%s", host, value); - if (grpc_cronet_trace) { - // gpr_log(GPR_DEBUG, "extracted URL = %s", s->url); - } + gpr_asprintf(pp_url, "https://%s%s", host, value); continue; } - s->headers[s->num_headers].key = key; - s->headers[s->num_headers].value = value; - s->num_headers++; + headers[num_headers].key = key; + headers[num_headers].value = value; + num_headers++; if (curr == NULL) { break; } } + *p_num_headers = num_headers; } -static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, - grpc_stream *gs, grpc_transport_stream_op *op) { - grpc_cronet_transport *ct = (grpc_cronet_transport *)gt; - GPR_ASSERT(ct->engine); - stream_obj *s = (stream_obj *)gs; - // Initialize a cronet bidirectional stream if it doesn't exist. - if (s->cbs == NULL) { - init_cronet_stream(s, gt); - } - - s->on_complete = op->on_complete; +static int parse_grpc_header(const uint8_t *data) { + const uint8_t *p = data + 1; + int length = 0; + length |= ((uint8_t)*p++) << 24; + length |= ((uint8_t)*p++) << 16; + length |= ((uint8_t)*p++) << 8; + length |= ((uint8_t)*p++); + return length; +} - if (op->recv_trailing_metadata) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, - "perform_stream_op - recv_trailing_metadata: on_complete=%p", - op->on_complete); - } - s->recv_trailing_metadata = op->recv_trailing_metadata; - s->op_requested[OP_RECV_TRAILING_METADATA] = true; - } - if (op->recv_message) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "perform_stream_op - recv_message: on_complete=%p", - op->on_complete); - } - s->recv_message = (grpc_byte_buffer **)op->recv_message; - s->cb_recv_message_ready = op->recv_message_ready; - s->op_requested[OP_RECV_MESSAGE] = true; - } - if (op->recv_initial_metadata) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, - "perform_stream_op - recv_initial_metadata on_complete=%p, " - "on_ready=%p", - op->on_complete, op->recv_initial_metadata_ready); - } - s->recv_initial_metadata = op->recv_initial_metadata; - s->cb_recv_initial_metadata_ready = op->recv_initial_metadata_ready; - s->op_requested[OP_RECV_INITIAL_METADATA] = true; - } - if (op->send_initial_metadata) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, - "perform_stream_op - send_initial_metadata: on_complete=%p", - op->on_complete); - } - s->num_headers = 0; - convert_metadata_to_cronet_headers(op->send_initial_metadata->list.head, - ct->host, s); - s->header_array.count = s->num_headers; - s->header_array.capacity = s->num_headers; - s->header_array.headers = s->headers; - s->op_requested[OP_SEND_INITIAL_METADATA] = true; +/* +Op Execution +*/ + +static bool op_can_be_run(stream_obj *s, enum OP_ID op_id) { + if (op_id == OP_SEND_INITIAL_METADATA) { + // already executed + if (s->state_op_done[OP_SEND_INITIAL_METADATA]) return false; + } + if (op_id == OP_RECV_INITIAL_METADATA) { + // already executed + if (s->state_op_done[OP_RECV_INITIAL_METADATA]) return false; + // we haven't sent headers yet. + if (!s->state_callback_received[OP_SEND_INITIAL_METADATA]) return false; + // we haven't received headers yet. + if (!s->state_callback_received[OP_RECV_INITIAL_METADATA]) return false; + } + if (op_id == OP_SEND_MESSAGE) { + // already executed + if (s->state_op_done[OP_SEND_MESSAGE]) return false; + // we haven't received headers yet. + if (!s->state_callback_received[OP_RECV_INITIAL_METADATA]) return false; + } + if (op_id == OP_RECV_MESSAGE) { + // already executed + if (s->state_op_done[OP_RECV_MESSAGE]) return false; + // we haven't received headers yet. + if (!s->state_callback_received[OP_RECV_INITIAL_METADATA]) return false; + } + if (op_id == OP_RECV_TRAILING_METADATA) { + // already executed + if (s->state_op_done[OP_RECV_TRAILING_METADATA]) return false; + // we haven't received trailers yet. + if (!s->state_callback_received[OP_RECV_TRAILING_METADATA]) return false; + } + if (op_id == OP_SEND_TRAILING_METADATA) { + // already executed + if (s->state_op_done[OP_SEND_TRAILING_METADATA]) return false; + // we haven't sent message yet + if (s->curr_op->send_message && !s->state_op_done[OP_SEND_MESSAGE]) return false; + } + + if (op_id == OP_ON_COMPLETE) { + // already executed + if (s->state_op_done[OP_ON_COMPLETE]) return false; + // Check if every op that was asked for is done. + if (s->curr_op->send_initial_metadata && !s->state_op_done[OP_SEND_INITIAL_METADATA]) return false; + if (s->curr_op->send_message && !s->state_op_done[OP_SEND_MESSAGE]) return false; + if (s->curr_op->send_trailing_metadata && !s->state_op_done[OP_SEND_TRAILING_METADATA]) return false; + if (s->curr_op->recv_initial_metadata && !s->state_op_done[OP_RECV_INITIAL_METADATA]) return false; + if (s->curr_op->recv_message && !s->state_op_done[OP_RECV_MESSAGE]) return false; + if (s->curr_op->recv_trailing_metadata && !s->state_op_done[OP_RECV_TRAILING_METADATA]) return false; } - if (op->send_message) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "perform_stream_op - send_message: on_complete=%p", - op->on_complete); - } - grpc_byte_stream_next(exec_ctx, op->send_message, &s->slice, - op->send_message->length, NULL); + return true; +} + +static void execute_curr_stream_op(stream_obj *s) { + if (s->curr_op->send_initial_metadata && op_can_be_run(s, OP_SEND_INITIAL_METADATA)) { + // This OP is the beginning. Reset various states + memset(&s->rs, 0, sizeof(s->rs)); + memset(&s->ws, 0, sizeof(s->ws)); + memset(s->state_op_done, 0, sizeof(s->state_op_done)); + memset(s->state_callback_received, 0, sizeof(s->state_callback_received)); + // Start new cronet stream + GPR_ASSERT(s->cbs == NULL); + gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_create"); + s->cbs = cronet_bidirectional_stream_create(s->curr_ct.engine, s->curr_gs, &cronet_callbacks); + char *url; + convert_metadata_to_cronet_headers(s->curr_op->send_initial_metadata->list.head, + s->curr_ct.host, &url, &header_array.headers, &header_array.count); + header_array.capacity = header_array.count; + gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_start"); + cronet_bidirectional_stream_start(s->cbs, url, 0, "POST", &header_array, false); + s->state_op_done[OP_SEND_INITIAL_METADATA] = true; + } else if (s->curr_op->recv_initial_metadata && + op_can_be_run(s, OP_RECV_INITIAL_METADATA)) { + grpc_chttp2_incoming_metadata_buffer_publish(&s->rs.initial_metadata, + s->curr_op->recv_initial_metadata); + enqueue_callback(s->curr_op->recv_initial_metadata_ready); + s->state_op_done[OP_RECV_INITIAL_METADATA] = true; + // We are ready to execute send_message. + execute_curr_stream_op(s); + } else if (s->curr_op->send_message && op_can_be_run(s, OP_SEND_MESSAGE)) { + // TODO (makdharma): Make into a standalone function + gpr_slice_buffer write_slice_buffer; + gpr_slice slice; + gpr_slice_buffer_init(&write_slice_buffer); + grpc_byte_stream_next(NULL, s->curr_op->send_message, &slice, + s->curr_op->send_message->length, NULL); // Check that compression flag is not ON. We don't support compression yet. // TODO (makdharma): add compression support - GPR_ASSERT(op->send_message->flags == 0); - gpr_slice_buffer_add(&s->write_slice_buffer, s->slice); - s->op_requested[OP_SEND_MESSAGE] = true; - } - if (op->send_trailing_metadata) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, - "perform_stream_op - send_trailing_metadata: on_complete=%p", - op->on_complete); + GPR_ASSERT(s->curr_op->send_message->flags == 0); + gpr_slice_buffer_add(&write_slice_buffer, slice); + GPR_ASSERT(write_slice_buffer.count == 1); // Empty request not handled yet + if (write_slice_buffer.count > 0) { + int write_buffer_size; + create_grpc_frame(&write_slice_buffer, &s->ws.write_buffer, &write_buffer_size); + gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_write (%p)", s->ws.write_buffer); + cronet_bidirectional_stream_write(s->cbs, s->ws.write_buffer, + write_buffer_size, false); // TODO: What if this is not the last write? } - s->op_requested[OP_SEND_TRAILING_METADATA] = true; - } - if (op->cancel_error) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "perform_stream_op - cancel_error: on_complete=%p", - op->on_complete); + s->state_op_done[OP_SEND_MESSAGE] = true; + } else if (s->curr_op->recv_message && op_can_be_run(s, OP_RECV_MESSAGE)) { + if (s->rs.length_field_received == false) { + if (s->rs.received_bytes == GRPC_HEADER_SIZE_IN_BYTES && s->rs.remaining_bytes == 0) { + // Start a read operation for data + s->rs.length_field_received = true; + s->rs.length_field = s->rs.remaining_bytes = + parse_grpc_header((const uint8_t *)s->rs.read_buffer); + GPR_ASSERT(s->rs.length_field > 0); // Empty message? + gpr_log(GPR_DEBUG, "length field = %d", s->rs.length_field); + s->rs.read_buffer = gpr_malloc(s->rs.length_field); + GPR_ASSERT(s->rs.read_buffer); + s->rs.remaining_bytes = s->rs.length_field; + s->rs.received_bytes = 0; + gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_read"); + cronet_bidirectional_stream_read(s->cbs, s->rs.read_buffer, + s->rs.remaining_bytes); + } else if (s->rs.remaining_bytes == 0) { + // Start a read operation for first 5 bytes (GRPC header) + s->rs.read_buffer = s->rs.grpc_header_bytes; + s->rs.remaining_bytes = GRPC_HEADER_SIZE_IN_BYTES; + s->rs.received_bytes = 0; + gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_read"); + cronet_bidirectional_stream_read(s->cbs, s->rs.read_buffer, + s->rs.remaining_bytes); + } + } else if (s->rs.remaining_bytes == 0) { + gpr_log(GPR_DEBUG, "read operation complete"); + gpr_slice read_data_slice = gpr_slice_malloc((uint32_t)s->rs.length_field); + uint8_t *dst_p = GPR_SLICE_START_PTR(read_data_slice); + memcpy(dst_p, s->rs.read_buffer, (size_t)s->rs.length_field); + gpr_slice_buffer_init(&s->rs.read_slice_buffer); + gpr_slice_buffer_add(&s->rs.read_slice_buffer, read_data_slice); + grpc_slice_buffer_stream_init(&s->rs.sbs, &s->rs.read_slice_buffer, 0); + *((grpc_byte_buffer **)s->curr_op->recv_message) = (grpc_byte_buffer *)&s->rs.sbs; + enqueue_callback(s->curr_op->recv_message_ready); + s->state_op_done[OP_RECV_MESSAGE] = true; + execute_curr_stream_op(s); + } + } else if (s->curr_op->recv_trailing_metadata && + op_can_be_run(s, OP_RECV_TRAILING_METADATA)) { + if (s->rs.trailing_metadata_valid) { + grpc_chttp2_incoming_metadata_buffer_publish( + &s->rs.trailing_metadata, s->curr_op->recv_trailing_metadata); + s->rs.trailing_metadata_valid = false; } - s->op_requested[OP_CANCEL_ERROR] = true; + s->state_op_done[OP_RECV_TRAILING_METADATA] = true; + execute_curr_stream_op(s); + } else if (s->curr_op->send_trailing_metadata && + op_can_be_run(s, OP_SEND_TRAILING_METADATA)) { + + gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_write (0)"); + cronet_bidirectional_stream_write(s->cbs, "", 0, true); + s->state_op_done[OP_SEND_TRAILING_METADATA] = true; + } else if (op_can_be_run(s, OP_ON_COMPLETE)) { + // All ops are complete. Call the on_complete callback + enqueue_callback(s->curr_op->on_complete); + s->state_op_done[OP_ON_COMPLETE] = true; + cronet_bidirectional_stream_destroy(s->cbs); + s->cbs = NULL; } - next_send_step(s); - next_recv_step(s, PERFORM_STREAM_OP); } +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_stream *gs, grpc_stream_refcount *refcount, const void *server_data) { stream_obj *s = (stream_obj *)gs; - memset(s, 0, sizeof(stream_obj)); - s->cbs = NULL; - gpr_mu_init(&s->recv_mu); - s->read_buffer = gpr_malloc(GRPC_HEADER_SIZE_IN_BYTES); - s->write_buffer = gpr_malloc(GRPC_HEADER_SIZE_IN_BYTES); - gpr_slice_buffer_init(&s->write_slice_buffer); - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "cronet_transport - init_stream"); - } + memset(&s->storage, 0, sizeof(s->storage)); + s->curr_op = NULL; return 0; } -static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, - grpc_stream *gs, void *and_free_memory) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "Destroy stream"); - } +static void set_pollset_do_nothing(grpc_exec_ctx *exec_ctx, grpc_transport *gt, + grpc_stream *gs, grpc_pollset *pollset) {} + +static void set_pollset_set_do_nothing(grpc_exec_ctx *exec_ctx, + grpc_transport *gt, grpc_stream *gs, + grpc_pollset_set *pollset_set) {} + +static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, + grpc_stream *gs, grpc_transport_stream_op *op) { + gpr_log(GPR_DEBUG, "perform_stream_op"); stream_obj *s = (stream_obj *)gs; - s->cbs = NULL; - gpr_free(s->read_buffer); - gpr_free(s->write_buffer); - gpr_free(s->url); - gpr_log(GPR_DEBUG, "destroying %p", &s->recv_mu); - gpr_mu_destroy(&s->recv_mu); - if (and_free_memory) { - gpr_free(and_free_memory); + memcpy(&s->curr_ct, gt, sizeof(grpc_cronet_transport)); + add_pending_op(&s->storage, op); + if (s->curr_op == NULL) { + s->curr_op = pop_pending_op(&s->storage); } + s->curr_gs = gs; + execute_curr_stream_op(s); +} + +static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, + grpc_stream *gs, void *and_free_memory) { } static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { - grpc_cronet_transport *ct = (grpc_cronet_transport *)gt; - gpr_free(ct->host); - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "Destroy transport"); - } } static char *get_peer(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "Unimplemented method"); - } return NULL; } static void perform_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_transport_op *op) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "Unimplemented method"); - } } const grpc_transport_vtable grpc_cronet_vtable = {sizeof(stream_obj), From 32fde7af294808f43dc92749b1c008eaba5f65b9 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 29 Jul 2016 17:31:07 -0700 Subject: [PATCH 098/279] Better names for the methods to clear all host settings --- src/objective-c/GRPCClient/GRPCCall+Tests.h | 2 +- src/objective-c/GRPCClient/GRPCCall+Tests.m | 4 ++-- src/objective-c/GRPCClient/private/GRPCHost.h | 2 +- src/objective-c/GRPCClient/private/GRPCHost.m | 2 +- src/objective-c/tests/InteropTests.m | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall+Tests.h b/src/objective-c/GRPCClient/GRPCCall+Tests.h index fe2c3604774..184ad09c5c8 100644 --- a/src/objective-c/GRPCClient/GRPCCall+Tests.h +++ b/src/objective-c/GRPCClient/GRPCCall+Tests.h @@ -62,5 +62,5 @@ * Resets all host configurations to their default values, and flushes all connections from the * cache. */ -+ (void)clearAllConfigurationsForTesting; ++ (void)resetHostSettings; @end diff --git a/src/objective-c/GRPCClient/GRPCCall+Tests.m b/src/objective-c/GRPCClient/GRPCCall+Tests.m index 44d42f382c6..656cba8fec6 100644 --- a/src/objective-c/GRPCClient/GRPCCall+Tests.m +++ b/src/objective-c/GRPCClient/GRPCCall+Tests.m @@ -61,7 +61,7 @@ hostConfig.secure = NO; } -+ (void)clearAllConfigurationsForTesting { - [GRPCHost clearAllHostsForTesting]; ++ (void)resetHostSettings { + [GRPCHost resetAllHostSettings]; } @end diff --git a/src/objective-c/GRPCClient/private/GRPCHost.h b/src/objective-c/GRPCClient/private/GRPCHost.h index 48fe7854ff5..c8b5dd315b0 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.h +++ b/src/objective-c/GRPCClient/private/GRPCHost.h @@ -42,7 +42,7 @@ struct grpc_channel_credentials; @interface GRPCHost : NSObject + (void)flushChannelCache; -+ (void)clearAllHostsForTesting; ++ (void)resetAllHostSettings; @property(nonatomic, readonly) NSString *address; @property(nonatomic, copy, nullable) NSString *userAgentPrefix; diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index b46c24212b8..477ddf51d97 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -113,7 +113,7 @@ static NSMutableDictionary *kHostCache; } } -+ (void)clearAllHostsForTesting { ++ (void)resetAllHostSettings { @synchronized (kHostCache) { kHostCache = [NSMutableDictionary dictionary]; } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 67ab43329fe..1ae0d7a848a 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -91,7 +91,7 @@ - (void)setUp { self.continueAfterFailure = NO; - [GRPCCall clearAllConfigurationsForTesting]; + [GRPCCall resetHostSettings]; _service = self.class.host ? [RMTTestService serviceWithHost:self.class.host] : nil; #ifdef GRPC_COMPILE_WITH_CRONET From 6e5c33c3e26ee1d43e2083034e05ffd0dc105934 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Sat, 30 Jul 2016 02:56:46 -0700 Subject: [PATCH 099/279] Don't assert if we're not able to set affinity for some reason --- test/cpp/qps/limit_cores.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/qps/limit_cores.cc b/test/cpp/qps/limit_cores.cc index 59ed369067f..b5c222542be 100644 --- a/test/cpp/qps/limit_cores.cc +++ b/test/cpp/qps/limit_cores.cc @@ -68,9 +68,9 @@ int LimitCores(const int* cores, int cores_size) { cores_set++; } } - GPR_ASSERT(sched_setaffinity(0, size, cpup) == 0); + bool affinity_set = (sched_setaffinity(0, size, cpup) == 0); CPU_FREE(cpup); - return cores_set; + return affinity_set ? cores_set : num_cores; } } // namespace testing From 1c0f30c4a8fc1f2d9bd8dd1702ee4563060f3637 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sat, 30 Jul 2016 03:59:16 +0800 Subject: [PATCH 100/279] fix conditional compilation for netcoreapp1.0 projects --- src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs | 2 +- src/csharp/Grpc.Core.Tests/NUnitMain.cs | 2 +- src/csharp/Grpc.Core.Tests/SanityTest.cs | 2 +- src/csharp/Grpc.Examples.Tests/NUnitMain.cs | 2 +- src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs | 2 +- .../Grpc.IntegrationTesting/GeneratedClientTest.cs | 2 +- src/csharp/Grpc.IntegrationTesting/InteropClient.cs | 10 +++++----- src/csharp/Grpc.IntegrationTesting/NUnitMain.cs | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs b/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs index 064bc13cabb..d7ebdb4201e 100644 --- a/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs +++ b/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs @@ -40,7 +40,7 @@ namespace Grpc.Core.Tests { public class AppDomainUnloadTest { -#if NETSTANDARD1_5 +#if NETCOREAPP1_0 [Test] [Ignore("Not supported for CoreCLR")] public void AppDomainUnloadHookCanCleanupAbandonedCall() diff --git a/src/csharp/Grpc.Core.Tests/NUnitMain.cs b/src/csharp/Grpc.Core.Tests/NUnitMain.cs index 24a9f846d10..870c726ac0e 100644 --- a/src/csharp/Grpc.Core.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.Core.Tests/NUnitMain.cs @@ -49,7 +49,7 @@ namespace Grpc.Core.Tests { // Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406. GrpcEnvironment.SetLogger(new TextWriterLogger(Console.Error)); -#if NETSTANDARD1_5 +#if NETCOREAPP1_0 return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); #else return new AutoRun().Execute(args); diff --git a/src/csharp/Grpc.Core.Tests/SanityTest.cs b/src/csharp/Grpc.Core.Tests/SanityTest.cs index 501992c5695..19c7a0b4401 100644 --- a/src/csharp/Grpc.Core.Tests/SanityTest.cs +++ b/src/csharp/Grpc.Core.Tests/SanityTest.cs @@ -46,7 +46,7 @@ namespace Grpc.Core.Tests public class SanityTest { // TODO: make sanity test work for CoreCLR as well -#if !NETSTANDARD1_5 +#if !NETCOREAPP1_0 /// /// Because we depend on a native library, sometimes when things go wrong, the /// entire NUnit test process crashes. To be able to track down problems better, diff --git a/src/csharp/Grpc.Examples.Tests/NUnitMain.cs b/src/csharp/Grpc.Examples.Tests/NUnitMain.cs index 1a522cab932..7ba1074d441 100644 --- a/src/csharp/Grpc.Examples.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.Examples.Tests/NUnitMain.cs @@ -49,7 +49,7 @@ namespace Grpc.Examples.Tests { // Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406. GrpcEnvironment.SetLogger(new TextWriterLogger(Console.Error)); -#if NETSTANDARD1_5 +#if NETCOREAPP1_0 return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); #else return new AutoRun().Execute(args); diff --git a/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs b/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs index 44634671ce5..dca61e3f966 100644 --- a/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs @@ -49,7 +49,7 @@ namespace Grpc.HealthCheck.Tests { // Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406. GrpcEnvironment.SetLogger(new TextWriterLogger(Console.Error)); -#if NETSTANDARD1_5 +#if NETCOREAPP1_0 return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); #else return new AutoRun().Execute(args); diff --git a/src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs b/src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs index eb7b55a2863..c17ede75610 100644 --- a/src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs +++ b/src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs @@ -49,7 +49,7 @@ namespace Grpc.IntegrationTesting TestService.TestServiceClient unimplementedClient = new UnimplementedTestServiceClient(); // TODO: replace Moq by some mocking library with CoreCLR support. -#if !NETSTANDARD1_5 +#if !NETCOREAPP1_0 [Test] public void ExpandedParamOverloadCanBeMocked() { diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs index e27fe5b3d80..ec407d3fcf4 100644 --- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs +++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs @@ -145,7 +145,7 @@ namespace Grpc.IntegrationTesting if (options.TestCase == "jwt_token_creds") { -#if !NETSTANDARD1_5 +#if !NETCOREAPP1_0 var googleCredential = await GoogleCredential.GetApplicationDefaultAsync(); Assert.IsTrue(googleCredential.IsCreateScopedRequired); credentials = ChannelCredentials.Create(credentials, googleCredential.ToCallCredentials()); @@ -157,7 +157,7 @@ namespace Grpc.IntegrationTesting if (options.TestCase == "compute_engine_creds") { -#if !NETSTANDARD1_5 +#if !NETCOREAPP1_0 var googleCredential = await GoogleCredential.GetApplicationDefaultAsync(); Assert.IsFalse(googleCredential.IsCreateScopedRequired); credentials = ChannelCredentials.Create(credentials, googleCredential.ToCallCredentials()); @@ -395,7 +395,7 @@ namespace Grpc.IntegrationTesting public static async Task RunOAuth2AuthTokenAsync(TestService.TestServiceClient client, string oauthScope) { -#if !NETSTANDARD1_5 +#if !NETCOREAPP1_0 Console.WriteLine("running oauth2_auth_token"); ITokenAccess credential = (await GoogleCredential.GetApplicationDefaultAsync()).CreateScoped(new[] { oauthScope }); string oauth2Token = await credential.GetAccessTokenForRequestAsync(); @@ -421,7 +421,7 @@ namespace Grpc.IntegrationTesting public static async Task RunPerRpcCredsAsync(TestService.TestServiceClient client, string oauthScope) { -#if !NETSTANDARD1_5 +#if !NETCOREAPP1_0 Console.WriteLine("running per_rpc_creds"); ITokenAccess googleCredential = await GoogleCredential.GetApplicationDefaultAsync(); @@ -731,7 +731,7 @@ namespace Grpc.IntegrationTesting // extracts the client_email field from service account file used for auth test cases private static string GetEmailFromServiceAccountFile() { -#if !NETSTANDARD1_5 +#if !NETCOREAPP1_0 string keyFile = Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS"); Assert.IsNotNull(keyFile); var jobject = JObject.Parse(File.ReadAllText(keyFile)); diff --git a/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs b/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs index 100ff0b5de9..21c8adb45c7 100644 --- a/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs +++ b/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs @@ -49,7 +49,7 @@ namespace Grpc.IntegrationTesting { // Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406. GrpcEnvironment.SetLogger(new TextWriterLogger(Console.Error)); -#if NETSTANDARD1_5 +#if NETCOREAPP1_0 return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); #else return new AutoRun().Execute(args); From 0a5a0cab7b9823fa5e929379fe6a4e6b59beaa10 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sat, 30 Jul 2016 04:13:24 +0800 Subject: [PATCH 101/279] build everything --- tools/run_tests/build_csharp_coreclr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/build_csharp_coreclr.sh b/tools/run_tests/build_csharp_coreclr.sh index 733b1a2083c..02cf0d39cb5 100755 --- a/tools/run_tests/build_csharp_coreclr.sh +++ b/tools/run_tests/build_csharp_coreclr.sh @@ -35,4 +35,4 @@ cd $(dirname $0)/../../src/csharp # TODO(jtattermusch): introduce caching dotnet restore . -dotnet build -f netstandard1.5 --configuration $MSBUILD_CONFIG '**/project.json' +dotnet build --configuration $MSBUILD_CONFIG '**/project.json' From 4d8283f93bed3b9d35362cad2c4fb38474b547d6 Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 15:11:49 -0700 Subject: [PATCH 102/279] Add thrift module --- .gitmodules | 3 +++ third_party/thrift | 1 + 2 files changed, 4 insertions(+) create mode 160000 third_party/thrift diff --git a/.gitmodules b/.gitmodules index ce647f3c455..3bfd3c9ce10 100644 --- a/.gitmodules +++ b/.gitmodules @@ -17,3 +17,6 @@ [submodule "third_party/nanopb"] path = third_party/nanopb url = https://github.com/nanopb/nanopb.git +[submodule "third_party/thrift"] + path = third_party/thrift + url = https://github.com/apache/thrift.git diff --git a/third_party/thrift b/third_party/thrift new file mode 160000 index 00000000000..bcad91771b7 --- /dev/null +++ b/third_party/thrift @@ -0,0 +1 @@ +Subproject commit bcad91771b7f0bff28a1cac1981d7ef2b9bcef3c From bc618eed71f1c2a2b69351a6aa60e8bb460773b9 Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 15:35:51 -0700 Subject: [PATCH 103/279] thrift serializer --- Makefile | 3 + build.yaml | 9 + .../grpc++/impl/codegen/thrift_serializer.h | 148 +++++++++++++++ .../impl/codegen/thrift_serializer_inl.h | 169 ++++++++++++++++++ include/grpc++/impl/codegen/thrift_utils.h | 90 ++++++++++ tools/run_tests/sources_and_headers.json | 22 ++- .../grpc++_test_util/grpc++_test_util.vcxproj | 3 + .../grpc++_test_util.vcxproj.filters | 9 + 8 files changed, 452 insertions(+), 1 deletion(-) create mode 100644 include/grpc++/impl/codegen/thrift_serializer.h create mode 100644 include/grpc++/impl/codegen/thrift_serializer_inl.h create mode 100644 include/grpc++/impl/codegen/thrift_utils.h diff --git a/Makefile b/Makefile index 8b6114bd7f9..986c25780f2 100644 --- a/Makefile +++ b/Makefile @@ -3923,6 +3923,9 @@ PUBLIC_HEADERS_CXX += \ include/grpc/impl/codegen/time.h \ include/grpc++/impl/codegen/proto_utils.h \ include/grpc++/impl/codegen/config_protobuf.h \ + include/grpc++/impl/codegen/thrift_serializer.h \ + include/grpc++/impl/codegen/thrift_serializer_inl.h \ + include/grpc++/impl/codegen/thrift_utils.h \ LIBGRPC++_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_UTIL_SRC)))) diff --git a/build.yaml b/build.yaml index 37c95ccdc0a..35af7a6c7a5 100644 --- a/build.yaml +++ b/build.yaml @@ -780,6 +780,14 @@ filegroups: - src/cpp/ext/reflection.pb.cc uses: - grpc++_codegen_proto +- name: thrift_util + language: c++ + public_headers: + - include/grpc++/impl/codegen/thrift_serializer.h + - include/grpc++/impl/codegen/thrift_serializer_inl.h + - include/grpc++/impl/codegen/thrift_utils.h + uses: + - grpc++_codegen_base libs: - name: gpr build: all @@ -1021,6 +1029,7 @@ libs: - grpc++_codegen_base_src - grpc++_codegen_proto - grpc++_config_proto + - thrift_util - name: grpc++_unsecure build: all language: c++ diff --git a/include/grpc++/impl/codegen/thrift_serializer.h b/include/grpc++/impl/codegen/thrift_serializer.h new file mode 100644 index 00000000000..315d76cf2a5 --- /dev/null +++ b/include/grpc++/impl/codegen/thrift_serializer.h @@ -0,0 +1,148 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + #ifndef GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H + #define GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H + +#include +#include + +#include +#include +#include +#include +#include + +namespace apache { +namespace thrift { +namespace util { + +using apache::thrift::protocol::TBinaryProtocolT; +using apache::thrift::protocol::TCompactProtocolT; +using apache::thrift::protocol::TNetworkBigEndian; +using apache::thrift::transport::TMemoryBuffer; +using apache::thrift::transport::TBufferBase; +using apache::thrift::transport::TTransport; +using std::shared_ptr; + + +template +class ThriftSerializer { +public: + ThriftSerializer() + : prepared_ (false) + , lastDeserialized_ (false) + , serializeVersion_ (false) {} + + /** + * Serialize the passed type into the internal buffer + * and returns a pointer to internal buffer and its size + * + */ + template + void serialize(const T& fields, const uint8_t** serializedBuffer, + size_t* serializedLen); + + /** + * Serialize the passed type into the byte buffer + */ + template + void serialize(const T& fields, grpc_byte_buffer** bp); + + /** + * Deserialize the passed char array into the passed type, returns the number + * of bytes that have been consumed from the passed string. + */ + template + uint32_t deserialize(const uint8_t* serializedBuffer, size_t length, + T* fields); + + /** + * Deserialize the passed byte buffer to passed type, returns the number + * of bytes consumed from byte buffer + */ + template + uint32_t deserialize(grpc_byte_buffer* buffer, T* msg); + + void setSerializeVersion(bool value); + + virtual ~ThriftSerializer() {} + + + /** + * Set the container size limit to deserialize + * This function should be called after buffer_ is initialized + */ + void setContainerSizeLimit(int32_t container_limit) { + if (!prepared_) { + prepare(); + } + protocol_->setContainerSizeLimit(container_limit); + } + + /** + * Set the string size limit to deserialize + * This function should be called after buffer_ is initialized + */ + void setStringSizeLimit(int32_t string_limit) { + if (!prepared_) { + prepare(); + } + protocol_->setStringSizeLimit(string_limit); + } + + + private: + void prepare(); + + private: + typedef P Protocol; + bool prepared_; + bool lastDeserialized_; + boost::shared_ptr buffer_; + shared_ptr protocol_; + bool serializeVersion_; +}; // ThriftSerializer + +template +struct ThriftSerializerBinary : public ThriftSerializer > {}; + + +template +struct ThriftSerializerCompact : public ThriftSerializer >{ }; + +}}} // namespace apache::thrift::util + +#include + +#endif diff --git a/include/grpc++/impl/codegen/thrift_serializer_inl.h b/include/grpc++/impl/codegen/thrift_serializer_inl.h new file mode 100644 index 00000000000..866ecf6312d --- /dev/null +++ b/include/grpc++/impl/codegen/thrift_serializer_inl.h @@ -0,0 +1,169 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + #ifndef GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_INL_H + #define GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_INL_H + +#include +#include +#include +#include +#include +#include +#include + +namespace apache { +namespace thrift { +namespace util { + +using apache::thrift::protocol::TMessageType; + +template +template +void ThriftSerializer::serialize(const T& fields, + const uint8_t** serializedBuffer, size_t* serializedLen) { + + // prepare or reset buffer + if (!prepared_ || lastDeserialized_) { + prepare(); + } else { + buffer_->resetBuffer(); + } + lastDeserialized_ = false; + + // if required serialize protocol version + if (serializeVersion_) { + protocol_->writeMessageBegin("", TMessageType(0), 0); + } + + // serilaize fields into buffer + fields.write(protocol_.get()); + + // write the end of message + if (serializeVersion_) { + protocol_->writeMessageEnd(); + } + + // assign buffer to string + uint8_t* byteBuffer; + uint32_t byteBufferSize; + buffer_->getBuffer(&byteBuffer, &byteBufferSize); + *serializedBuffer = byteBuffer; + *serializedLen = byteBufferSize; +} + +template +template +void ThriftSerializer::serialize(const T& fields, grpc_byte_buffer** bp) { + + const uint8_t* byteBuffer; + size_t byteBufferSize; + serialize(fields, &byteBuffer, &byteBufferSize); + + gpr_slice slice = gpr_slice_from_copied_buffer((char*)byteBuffer,byteBufferSize); + + *bp = grpc_raw_byte_buffer_create(&slice, 1); + + gpr_slice_unref(slice); +} + +template +template +uint32_t ThriftSerializer::deserialize(const uint8_t* serializedBuffer, + size_t length, T* fields) { + // prepare buffer if necessary + if (!prepared_) { + prepare(); + } + lastDeserialized_ = true; + + //reset buffer transport + buffer_->resetBuffer((uint8_t*)serializedBuffer, length); + + // read the protocol version if necessary + if (serializeVersion_) { + std::string name = ""; + TMessageType mt = (TMessageType) 0; + int32_t seq_id = 0; + protocol_->readMessageBegin(name, mt, seq_id); + } + + // deserialize buffer into fields + uint32_t len = fields->read(protocol_.get()); + + // read the end of message + if (serializeVersion_) { + protocol_->readMessageEnd(); + } + + return len; +} + +template +template +uint32_t ThriftSerializer::deserialize(grpc_byte_buffer* bp, T* fields) { + grpc_byte_buffer_reader reader; + grpc_byte_buffer_reader_init(&reader, bp); + + gpr_slice slice = grpc_byte_buffer_reader_readall(&reader); + + uint32_t len = deserialize(GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice), fields); + + gpr_slice_unref(slice); + + grpc_byte_buffer_reader_destroy(&reader); + + return len; +} + +template +void ThriftSerializer::setSerializeVersion(bool value) { + serializeVersion_ = value; +} + +template +void +ThriftSerializer::prepare() +{ + + buffer_.reset(new TMemoryBuffer()); + + // create a protocol for the memory buffer transport + protocol_.reset(new Protocol(buffer_)); + + prepared_ = true; +} + +}}} // namespace apache::thrift::util + +#endif diff --git a/include/grpc++/impl/codegen/thrift_utils.h b/include/grpc++/impl/codegen/thrift_utils.h new file mode 100644 index 00000000000..629441149fd --- /dev/null +++ b/include/grpc++/impl/codegen/thrift_utils.h @@ -0,0 +1,90 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H +#define GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace grpc { + +using apache::thrift::util::ThriftSerializerCompact; + +template +class SerializationTraits::value>::type> { + public: + + static Status Serialize(const T& msg, + grpc_byte_buffer** bp, bool* own_buffer) { + + *own_buffer = true; + + ThriftSerializerCompact serializer; + + serializer.serialize(msg, bp); + + return Status(StatusCode::OK, "ok"); + } + + static Status Deserialize(grpc_byte_buffer* buffer, + T* msg, + int max_message_size) { + if (!buffer) { + return Status(StatusCode::INTERNAL, "No payload"); + } + + ThriftSerializerCompact deserializer; + deserializer.deserialize(buffer, msg); + + grpc_byte_buffer_destroy(buffer); + + return Status(StatusCode::OK, "ok"); + } +}; + +} // namespace grpc + +#endif // GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index e85dd2c8200..06ac86fc9c4 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -4411,7 +4411,8 @@ "grpc++_codegen_base_src", "grpc++_codegen_proto", "grpc++_config_proto", - "grpc_test_util" + "grpc_test_util", + "thrift_util" ], "headers": [ "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h", @@ -6784,5 +6785,24 @@ ], "third_party": false, "type": "filegroup" + }, + { + "deps": [ + "grpc++_codegen_base" + ], + "headers": [ + "include/grpc++/impl/codegen/thrift_serializer.h", + "include/grpc++/impl/codegen/thrift_serializer_inl.h", + "include/grpc++/impl/codegen/thrift_utils.h" + ], + "language": "c++", + "name": "thrift_util", + "src": [ + "include/grpc++/impl/codegen/thrift_serializer.h", + "include/grpc++/impl/codegen/thrift_serializer_inl.h", + "include/grpc++/impl/codegen/thrift_utils.h" + ], + "third_party": false, + "type": "filegroup" } ] diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj index d0fca9ba65a..96ce3b89164 100644 --- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj +++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj @@ -200,6 +200,9 @@ + + + diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters index cc98c604080..2105e672df9 100644 --- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters @@ -192,6 +192,15 @@ include\grpc++\impl\codegen + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + + + include\grpc++\impl\codegen + From dd7a2a35e23042413c232ea9f00a4b7dbbce5648 Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 21:57:47 -0700 Subject: [PATCH 104/279] gthrift codegen and Dockerfile --- tools/grift/Dockerfile | 63 + tools/grift/grpc_plugins_generator.patch | 2417 ++++++++++++++++++++++ 2 files changed, 2480 insertions(+) create mode 100644 tools/grift/Dockerfile create mode 100644 tools/grift/grpc_plugins_generator.patch diff --git a/tools/grift/Dockerfile b/tools/grift/Dockerfile new file mode 100644 index 00000000000..5238010ea92 --- /dev/null +++ b/tools/grift/Dockerfile @@ -0,0 +1,63 @@ +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +FROM ubuntu:14.04 + +RUN apt-get update && \ + apt-get install -y \ + git build-essential \ + pkg-config flex \ + bison \ + libkrb5-dev \ + libsasl2-dev \ + libnuma-dev \ + pkg-config \ + libssl-dev \ + autoconf libtool \ + cmake \ + libiberty-dev \ + g++ unzip \ + curl make automake libtool + +# Configure git +RUN git config --global user.name " " && \ + git config --global user.email " " + +RUN git clone https://github.com/grpc/grpc + +RUN cd grpc && git submodule update --init + +RUN cd grpc/third_party/thrift && git am --signoff < ../../tools/grift/grpc_plugins_generator.patch + +RUN cd grpc/third_party/protobuf && ./autogen.sh && ./configure && \ + make -j && make check -j && make install && ldconfig + +RUN cd grpc && make -j && make install + +RUN cd grpc/third_party/thrift && ./bootstrap.sh && ./configure && make -j && make install \ No newline at end of file diff --git a/tools/grift/grpc_plugins_generator.patch b/tools/grift/grpc_plugins_generator.patch new file mode 100644 index 00000000000..2779dfb59eb --- /dev/null +++ b/tools/grift/grpc_plugins_generator.patch @@ -0,0 +1,2417 @@ +From 0894590b5020c38106d4ebb2291994668c64f9dd Mon Sep 17 00:00:00 2001 +From: chedeti +Date: Sun, 31 Jul 2016 15:47:47 -0700 +Subject: [PATCH 1/3] don't build tests + +--- + Makefile.am | 7 ++----- + lib/cpp/Makefile.am | 7 ++----- + 2 files changed, 4 insertions(+), 10 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index 10fe49a..d49caac 100755 +--- a/Makefile.am ++++ b/Makefile.am +@@ -21,10 +21,6 @@ ACLOCAL_AMFLAGS = -I ./aclocal + + SUBDIRS = compiler/cpp lib + +-if WITH_TESTS +-SUBDIRS += test +-endif +- + if WITH_TUTORIAL + SUBDIRS += tutorial + endif +@@ -117,4 +113,5 @@ EXTRA_DIST = \ + CHANGES \ + NOTICE \ + README.md \ +- Thrift.podspec ++ Thrift.podspec \ ++ test +diff --git a/lib/cpp/Makefile.am b/lib/cpp/Makefile.am +index 6fd15d2..7de1fad 100755 +--- a/lib/cpp/Makefile.am ++++ b/lib/cpp/Makefile.am +@@ -27,10 +27,6 @@ moc__%.cpp: %.h + + SUBDIRS = . + +-if WITH_TESTS +-SUBDIRS += test +-endif +- + pkgconfigdir = $(libdir)/pkgconfig + + lib_LTLIBRARIES = libthrift.la +@@ -277,7 +273,8 @@ EXTRA_DIST = \ + thrift-qt.pc.in \ + thrift-qt5.pc.in \ + src/thrift/qt/CMakeLists.txt \ +- $(WINDOWS_DIST) ++ $(WINDOWS_DIST) \ ++ test + + style-local: + $(CPPSTYLE_CMD) +-- +2.8.0.rc3.226.g39d4020 + + +From 04244fa7805740761db757e4c44251f723d85839 Mon Sep 17 00:00:00 2001 +From: chedeti +Date: Sun, 31 Jul 2016 16:16:40 -0700 +Subject: [PATCH 2/3] grpc cpp plugins generator with example + +--- + compiler/cpp/src/generate/t_cpp_generator.cc | 476 +++++++++++++++++++++++---- + tutorial/cpp/CMakeLists.txt | 53 --- + tutorial/cpp/CppClient.cpp | 134 ++++---- + tutorial/cpp/CppServer.cpp | 226 ++++--------- + tutorial/cpp/Makefile.am | 58 ++-- + tutorial/cpp/test.thrift | 13 + + 6 files changed, 590 insertions(+), 370 deletions(-) + delete mode 100644 tutorial/cpp/CMakeLists.txt + create mode 100644 tutorial/cpp/test.thrift + +diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc +index 6c04899..9c3399b 100644 +--- a/compiler/cpp/src/generate/t_cpp_generator.cc ++++ b/compiler/cpp/src/generate/t_cpp_generator.cc +@@ -162,6 +162,8 @@ public: + bool specialized = false); + void generate_function_helpers(t_service* tservice, t_function* tfunction); + void generate_service_async_skeleton(t_service* tservice); ++ void generate_service_stub_interface(t_service* tservice); ++ void generate_service_stub(t_service* tservice); + + /** + * Serialization constructs +@@ -883,10 +885,10 @@ void t_cpp_generator::generate_struct_declaration(ofstream& out, + bool is_user_struct) { + string extends = ""; + if (is_exception) { +- extends = " : public ::apache::thrift::TException"; ++ extends = " : public apache::thrift::TException"; + } else { +- if (is_user_struct && !gen_templates_) { +- extends = " : public virtual ::apache::thrift::TBase"; ++ if (!gen_templates_) { ++ extends = " : public virtual apache::thrift::TBase"; + } + } + +@@ -1130,9 +1132,15 @@ void t_cpp_generator::generate_struct_definition(ofstream& out, + vector::const_iterator m_iter; + const vector& members = tstruct->get_members(); + ++ string method_prefix = ""; ++ if (service_name_ != "") { ++ method_prefix = service_name_ + "::"; ++ } ++ + // Destructor + if (tstruct->annotations_.find("final") == tstruct->annotations_.end()) { +- force_cpp_out << endl << indent() << tstruct->get_name() << "::~" << tstruct->get_name() ++ force_cpp_out << endl << indent() << method_prefix << ++ tstruct->get_name() << "::~" << tstruct->get_name() + << "() throw() {" << endl; + indent_up(); + +@@ -1145,12 +1153,14 @@ void t_cpp_generator::generate_struct_definition(ofstream& out, + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + if (is_reference((*m_iter))) { + std::string type = type_name((*m_iter)->get_type()); +- out << endl << indent() << "void " << tstruct->get_name() << "::__set_" ++ out << endl << indent() << "void " << method_prefix ++ << tstruct->get_name() << "::__set_" + << (*m_iter)->get_name() << "(boost::shared_ptr<" + << type_name((*m_iter)->get_type(), false, false) << ">"; + out << " val) {" << endl; + } else { +- out << endl << indent() << "void " << tstruct->get_name() << "::__set_" ++ out << endl << indent() << "void " << method_prefix ++ << tstruct->get_name() << "::__set_" + << (*m_iter)->get_name() << "(" << type_name((*m_iter)->get_type(), false, true); + out << " val) {" << endl; + } +@@ -1177,11 +1187,16 @@ void t_cpp_generator::generate_struct_definition(ofstream& out, + * @param tstruct The struct + */ + void t_cpp_generator::generate_struct_reader(ofstream& out, t_struct* tstruct, bool pointers) { ++ string method_prefix = ""; ++ if (service_name_ != "") { ++ method_prefix = service_name_ + "::"; ++ } ++ + if (gen_templates_) { + out << indent() << "template " << endl << indent() << "uint32_t " +- << tstruct->get_name() << "::read(Protocol_* iprot) {" << endl; ++ << method_prefix << tstruct->get_name() << "::read(Protocol_* iprot) {" << endl; + } else { +- indent(out) << "uint32_t " << tstruct->get_name() ++ indent(out) << "uint32_t " << method_prefix << tstruct->get_name() + << "::read(::apache::thrift::protocol::TProtocol* iprot) {" << endl; + } + indent_up(); +@@ -1301,14 +1316,18 @@ void t_cpp_generator::generate_struct_reader(ofstream& out, t_struct* tstruct, b + */ + void t_cpp_generator::generate_struct_writer(ofstream& out, t_struct* tstruct, bool pointers) { + string name = tstruct->get_name(); ++ string method_prefix = ""; ++ if (service_name_ != "") { ++ method_prefix = service_name_ + "::"; ++ } + const vector& fields = tstruct->get_sorted_members(); + vector::const_iterator f_iter; + + if (gen_templates_) { + out << indent() << "template " << endl << indent() << "uint32_t " +- << tstruct->get_name() << "::write(Protocol_* oprot) const {" << endl; ++ << method_prefix << tstruct->get_name() << "::write(Protocol_* oprot) const {" << endl; + } else { +- indent(out) << "uint32_t " << tstruct->get_name() ++ indent(out) << "uint32_t " << method_prefix << tstruct->get_name() + << "::write(::apache::thrift::protocol::TProtocol* oprot) const {" << endl; + } + indent_up(); +@@ -1369,14 +1388,18 @@ void t_cpp_generator::generate_struct_result_writer(ofstream& out, + t_struct* tstruct, + bool pointers) { + string name = tstruct->get_name(); ++ string method_prefix = ""; ++ if (service_name_ != "") { ++ method_prefix = service_name_ + "::"; ++ } + const vector& fields = tstruct->get_sorted_members(); + vector::const_iterator f_iter; + + if (gen_templates_) { + out << indent() << "template " << endl << indent() << "uint32_t " +- << tstruct->get_name() << "::write(Protocol_* oprot) const {" << endl; ++ << method_prefix << tstruct->get_name() << "::write(Protocol_* oprot) const {" << endl; + } else { +- indent(out) << "uint32_t " << tstruct->get_name() ++ indent(out) << "uint32_t " << method_prefix << tstruct->get_name() + << "::write(::apache::thrift::protocol::TProtocol* oprot) const {" << endl; + } + indent_up(); +@@ -1385,18 +1408,7 @@ void t_cpp_generator::generate_struct_result_writer(ofstream& out, + + indent(out) << "xfer += oprot->writeStructBegin(\"" << name << "\");" << endl; + +- bool first = true; + for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { +- if (first) { +- first = false; +- out << endl << indent() << "if "; +- } else { +- out << " else if "; +- } +- +- out << "(this->__isset." << (*f_iter)->get_name() << ") {" << endl; +- +- indent_up(); + + // Write field header + out << indent() << "xfer += oprot->writeFieldBegin(" +@@ -1410,9 +1422,6 @@ void t_cpp_generator::generate_struct_result_writer(ofstream& out, + } + // Write field closer + indent(out) << "xfer += oprot->writeFieldEnd();" << endl; +- +- indent_down(); +- indent(out) << "}"; + } + + // Write the struct map +@@ -1478,9 +1487,13 @@ void t_cpp_generator::generate_struct_ostream_operator(std::ofstream& out, t_str + } + + void t_cpp_generator::generate_struct_print_method_decl(std::ofstream& out, t_struct* tstruct) { ++ string method_prefix = ""; ++ if (service_name_ != "") { ++ method_prefix = service_name_ + "::"; ++ } + out << "void "; + if (tstruct) { +- out << tstruct->get_name() << "::"; ++ out << method_prefix << tstruct->get_name() << "::"; + } + out << "printTo(std::ostream& out) const"; + } +@@ -1601,11 +1614,13 @@ void t_cpp_generator::generate_exception_what_method(std::ofstream& out, t_struc + */ + void t_cpp_generator::generate_service(t_service* tservice) { + string svcname = tservice->get_name(); ++ string ns = tservice->get_program()->get_namespace("cpp"); + + // Make output files +- string f_header_name = get_out_dir() + svcname + ".h"; ++ string f_header_name = get_out_dir() + svcname + ".grpc.thrift.h"; + f_header_.open(f_header_name.c_str()); + ++ + // Print header file includes + f_header_ << autogen_comment(); + f_header_ << "#ifndef " << svcname << "_H" << endl << "#define " << svcname << "_H" << endl +@@ -1621,15 +1636,38 @@ void t_cpp_generator::generate_service(t_service* tservice) { + f_header_ << "#include " << endl; + } + f_header_ << "#include " << endl; ++ + f_header_ << "#include \"" << get_include_prefix(*get_program()) << program_name_ << "_types.h\"" + << endl; + + t_service* extends_service = tservice->get_extends(); +- if (extends_service != NULL) { ++ if (extends_service != nullptr) { + f_header_ << "#include \"" << get_include_prefix(*(extends_service->get_program())) +- << extends_service->get_name() << ".h\"" << endl; ++ << extends_service->get_name() << ".grpc.thrift.h\"" << endl; + } + ++ ++ f_header_ << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl; ++ ++ ++ f_header_ << ++ endl << ++ "namespace grpc {" << endl << ++ "class CompletionQueue;" << endl << ++ "class Channel;" << endl << ++ "class RpcService;" << endl << ++ "class ServerCompletionQueue;" << endl << ++ "class ServerContext;" << endl << ++ "}" << endl; ++ + f_header_ << endl << ns_open_ << endl << endl; + + f_header_ << "#ifdef _WIN32\n" +@@ -1638,10 +1676,13 @@ void t_cpp_generator::generate_service(t_service* tservice) { + "#endif\n\n"; + + // Service implementation file includes +- string f_service_name = get_out_dir() + svcname + ".cpp"; ++ string f_service_name = get_out_dir() + svcname + ".grpc.thrift.cpp"; + f_service_.open(f_service_name.c_str()); + f_service_ << autogen_comment(); +- f_service_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" << endl; ++ ++ f_service_ << "#include \"" << ++ get_include_prefix(*get_program()) << svcname << ".grpc.thrift.h\"" << endl; ++ + if (gen_cob_style_) { + f_service_ << "#include \"thrift/async/TAsyncChannel.h\"" << endl; + } +@@ -1652,7 +1693,7 @@ void t_cpp_generator::generate_service(t_service* tservice) { + string f_service_tcc_name = get_out_dir() + svcname + ".tcc"; + f_service_tcc_.open(f_service_tcc_name.c_str()); + f_service_tcc_ << autogen_comment(); +- f_service_tcc_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" ++ f_service_tcc_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".grpc.thrift.h\"" + << endl; + + f_service_tcc_ << "#ifndef " << svcname << "_TCC" << endl << "#define " << svcname << "_TCC" +@@ -1663,19 +1704,66 @@ void t_cpp_generator::generate_service(t_service* tservice) { + } + } + ++ f_service_ << ++ endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ "#include " << endl << ++ endl; ++ + f_service_ << endl << ns_open_ << endl << endl; + f_service_tcc_ << endl << ns_open_ << endl << endl; + ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ ++ f_service_ << ++ "static const char* " << service_name_ << "_method_names[] = {" << endl; ++ ++ ++ indent_up(); ++ ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "\"/" << ns << "." << service_name_ << "/" << (*f_iter)->get_name() << "\"," << endl; ++ } ++ ++ if (extends_service != nullptr) { ++ vector functions = extends_service->get_functions(); ++ vector::iterator f_iter; ++ ++ for ( f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "\"/" << extends_service->get_program()->get_namespace("cpp") << ++ "." << extends_service->get_name() << "/" << (*f_iter)->get_name() << "\"," << endl; ++ } ++ } ++ ++ indent_down(); ++ f_service_ << ++ "};" << endl; ++ ++ // Generate service class ++ if ( extends_service != nullptr ) { ++ f_header_ << "class " << service_name_ << " : public " << ++ extends_service->get_name() << " {" << endl << ++ "public:" << endl; ++ } ++ else { ++ f_header_ << "class " << service_name_ << "{" << endl << ++ "public:" << endl; ++ } ++ + // Generate all the components +- generate_service_interface(tservice, ""); +- generate_service_interface_factory(tservice, ""); +- generate_service_null(tservice, ""); + generate_service_helpers(tservice); +- generate_service_client(tservice, ""); +- generate_service_processor(tservice, ""); +- generate_service_multiface(tservice); +- generate_service_skeleton(tservice); +- generate_service_client(tservice, "Concurrent"); ++ generate_service_interface(tservice, ""); ++ generate_service_stub_interface(tservice); ++ generate_service_stub(tservice); + + // Generate all the cob components + if (gen_cob_style_) { +@@ -1688,10 +1776,14 @@ void t_cpp_generator::generate_service(t_service* tservice) { + generate_service_async_skeleton(tservice); + } + ++ // Close service class ++ f_header_ << "};" << endl; ++ + f_header_ << "#ifdef _WIN32\n" + " #pragma warning( pop )\n" + "#endif\n\n"; + ++ + // Close the namespace + f_service_ << ns_close_ << endl << endl; + f_service_tcc_ << ns_close_ << endl << endl; +@@ -1729,15 +1821,11 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) { + string name_orig = ts->get_name(); + + // TODO(dreiss): Why is this stuff not in generate_function_helpers? +- ts->set_name(tservice->get_name() + "_" + (*f_iter)->get_name() + "_args"); ++ ts->set_name((*f_iter)->get_name() + "Req"); + generate_struct_declaration(f_header_, ts, false); +- generate_struct_definition(out, f_service_, ts, false); ++ generate_struct_definition(out, f_service_, ts, true); + generate_struct_reader(out, ts); + generate_struct_writer(out, ts); +- ts->set_name(tservice->get_name() + "_" + (*f_iter)->get_name() + "_pargs"); +- generate_struct_declaration(f_header_, ts, false, true, false, true); +- generate_struct_definition(out, f_service_, ts, false); +- generate_struct_writer(out, ts, true); + ts->set_name(name_orig); + + generate_function_helpers(tservice, *f_iter); +@@ -1745,13 +1833,210 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) { + } + + /** ++ * Generates a service Stub Interface ++ * ++ * @param tservice The service to generate a stub for. ++ * ++ */ ++void t_cpp_generator::generate_service_stub_interface(t_service* tservice) { ++ ++ string extends = ""; ++ if (tservice->get_extends() != nullptr) { ++ extends = " : virtual public " + type_name(tservice->get_extends()) + "::StubInterface"; ++ } ++ ++ f_header_ << ++ endl << ++ "class StubInterface " << extends << " {" << endl; ++ indent_up(); ++ f_header_ << ++ " public:" << endl << ++ indent() << "virtual ~StubInterface() {}" << endl; ++ ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ string function_name = (*f_iter)->get_name(); ++ f_header_ << ++ indent() << "virtual ::grpc::Status " << function_name << ++ "(::grpc::ClientContext* context, const " << function_name << ++ "Req& request, " << function_name << "Resp* response) = 0;" << endl; ++ } ++ indent_down(); ++ f_header_ << ++ "};" << endl << endl; ++ ++} ++void t_cpp_generator::generate_service_stub(t_service* tservice) { ++ f_header_ << ++ endl << ++ "class Stub : public StubInterface {" << ++ endl; ++ ++ indent_up(); ++ f_header_ << ++ " public:" << endl << ++ indent() << "Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);" << ++ endl; ++ ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ string function_name = (*f_iter)->get_name(); ++ f_header_ << ++ indent() << "::grpc::Status " << function_name << ++ "(::grpc::ClientContext* context, const " << function_name << ++ "Req& request, " << function_name << "Resp* response) override;" << endl; ++ } ++ ++ t_service* extends_service = tservice->get_extends(); ++ if (extends_service != nullptr) { ++ // generate inherited methods ++ vector functions = extends_service->get_functions(); ++ vector::iterator f_iter; ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ string function_name = (*f_iter)->get_name(); ++ f_header_ << ++ indent() << "::grpc::Status " << function_name << ++ "(::grpc::ClientContext* context, const " << function_name << ++ "Req& request, " << function_name << "Resp* response) override;" << endl; ++ } ++ } ++ ++ f_header_ << ++ endl << ++ " private:" << endl << ++ indent() << "std::shared_ptr< ::grpc::ChannelInterface> channel_;" << ++ endl; ++ ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_header_ << ++ indent() << "const ::grpc::RpcMethod rpcmethod_" << (*f_iter)->get_name() << "_;" << endl; ++ } ++ ++ if (extends_service != nullptr) { ++ // generate inherited methods ++ vector functions = extends_service->get_functions(); ++ vector::iterator f_iter; ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_header_ << ++ indent() << "const ::grpc::RpcMethod rpcmethod_" << (*f_iter)->get_name() << "_;" << endl; ++ } ++ } ++ ++ indent_down(); ++ f_header_ << ++ "};" << endl << endl; ++ ++ // generate the implementaion of Stub ++ f_service_ << ++ endl << ++ service_name_ << "::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel)" << endl; ++ ++ indent_up(); ++ f_service_ << ++ indent() << ": channel_(channel)" << endl; ++ int i=0; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter , ++i) { ++ f_service_ << ++ indent() << ++ ", rpcmethod_" << (*f_iter)->get_name() << "_(" << ++ service_name_ << "_method_names[" << i << "], ::grpc::RpcMethod::NORMAL_RPC, channel)" << endl; ++ } ++ ++ if (extends_service != nullptr) { ++ // generate inherited methods ++ vector functions = extends_service->get_functions(); ++ vector::iterator f_iter; ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter, ++i) { ++ f_service_ << ++ indent() << ++ ", rpcmethod_" << (*f_iter)->get_name() << "_(" << ++ service_name_ << "_method_names[" << i << "], ::grpc::RpcMethod::NORMAL_RPC, channel)" << endl; ++ } ++ } ++ f_service_ << ++ indent() << "{}" << endl; ++ indent_down(); ++ ++ // generate NewStub ++ f_header_ << ++ endl << ++ "static std::unique_ptr NewStub(const std::shared_ptr\ ++ < ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());" << ++ endl; ++ ++ // generate NewStub Implementation ++ f_service_ << ++ endl << ++ "std::unique_ptr< " << service_name_ << "::Stub> " << service_name_ << "::NewStub(const std::shared_ptr\ ++ < ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {" << endl; ++ ++ indent_up(); ++ f_service_ << ++ indent() << "std::unique_ptr< " << service_name_ << "::Stub> stub(new " << service_name_ << ++ "::Stub(channel));" << endl << ++ indent() << "return stub;" << endl; ++ indent_down(); ++ f_service_ << ++ "}" << endl; ++ ++ // generate stub methods ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ string function_name = (*f_iter)->get_name(); ++ f_service_ << ++ endl << ++ "::grpc::Status " << service_name_ << "::Stub::" << function_name << ++ "(::grpc::ClientContext* context, const " << service_name_ << "::" << ++ function_name << "Req& request, " << service_name_ << "::" << ++ function_name << "Resp* response) {" << endl; ++ ++ indent_up(); ++ f_service_ << ++ indent() << "return ::grpc::BlockingUnaryCall(channel_.get(), rpcmethod_" << ++ function_name << "_, context, request, response);" << endl; ++ indent_down(); ++ ++ f_service_ << ++ "}" << endl; ++ ++ } ++ ++ if (extends_service != nullptr) { ++ vector functions = extends_service->get_functions(); ++ vector::iterator f_iter; ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ string function_name = (*f_iter)->get_name(); ++ f_service_ << ++ endl << ++ "::grpc::Status " << service_name_ << "::Stub::" << function_name << ++ "(::grpc::ClientContext* context, const " << service_name_ << "::" << ++ function_name << "Req& request, " << service_name_ << "::" << ++ function_name << "Resp* response) {" << endl; ++ ++ indent_up(); ++ f_service_ << ++ indent() << "return ::grpc::BlockingUnaryCall(channel_.get(), rpcmethod_" << ++ function_name << "_, context, request, response);" << endl; ++ indent_down(); ++ ++ f_service_ << ++ "}" << endl; ++ ++ } ++ } ++ ++} ++ ++ ++/** + * Generates a service interface definition. + * + * @param tservice The service to generate a header definition for + */ + void t_cpp_generator::generate_service_interface(t_service* tservice, string style) { + +- string service_if_name = service_name_ + style + "If"; ++ string service_if_name = "Service"; + if (style == "CobCl") { + // Forward declare the client. + string client_name = service_name_ + "CobClient"; +@@ -1765,12 +2050,14 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty + + string extends = ""; + if (tservice->get_extends() != NULL) { +- extends = " : virtual public " + type_name(tservice->get_extends()) + style + "If"; ++ extends = " : virtual public " + type_name(tservice->get_extends()) + style + "::Service"; + if (style == "CobCl" && gen_templates_) { + // TODO(simpkins): If gen_templates_ is enabled, we currently assume all + // parent services were also generated with templates enabled. + extends += "T"; + } ++ } else { ++ extends = " : public ::grpc::Service"; + } + + if (style == "CobCl" && gen_templates_) { +@@ -1778,7 +2065,9 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty + } + f_header_ << "class " << service_if_name << extends << " {" << endl << " public:" << endl; + indent_up(); +- f_header_ << indent() << "virtual ~" << service_if_name << "() {}" << endl; ++ ++ f_header_ << indent() << "Service();" << endl; ++ f_header_ << indent() << "virtual ~Service();" << endl; + + vector functions = tservice->get_functions(); + vector::iterator f_iter; +@@ -1786,7 +2075,12 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty + if ((*f_iter)->has_doc()) + f_header_ << endl; + generate_java_doc(f_header_, *f_iter); +- f_header_ << indent() << "virtual " << function_signature(*f_iter, style) << " = 0;" << endl; ++ ++ string function_name = (*f_iter)->get_name(); ++ f_header_ << ++ indent() << "virtual ::grpc::Status " << function_name << ++ "(::grpc::ServerContext* context, const "<< function_name << ++ "Req* request, "<< function_name << "Resp* response);" << endl; + } + indent_down(); + f_header_ << "};" << endl << endl; +@@ -1797,6 +2091,66 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty + f_header_ << "typedef " << service_if_name << "< ::apache::thrift::protocol::TProtocol> " + << service_name_ << style << "If;" << endl << endl; + } ++ ++ // generate the service interface implementations ++ ++ f_service_ << ++ endl << ++ service_name_ << "::Service::Service() {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "(void)" << service_name_ << "_method_names;" << endl; ++ uint32_t i=0; ++ for(i=0;iget_name(); ++ f_service_ << ++ endl << ++ indent() << "AddMethod(new ::grpc::RpcServiceMethod(" << endl; ++ indent_up(); ++ ++ f_service_ << ++ indent() << service_name_ << "_method_names[" << i << "]," << endl << ++ indent() << "::grpc::RpcMethod::NORMAL_RPC," << endl << ++ indent() << "new ::grpc::RpcMethodHandler< " << service_name_ << "::Service, " << ++ service_name_ << "::" << function_name << "Req, " << service_name_ << "::" << ++ function_name << "Resp>(" << endl; ++ ++ indent_up(); ++ f_service_ << ++ indent() << "std::mem_fn(&" << service_name_ << "::Service::" << function_name << "), this)));" << endl; ++ ++ indent_down(); ++ indent_down(); ++ } ++ ++ indent_down(); ++ f_service_ << ++ "}" << endl; ++ ++ f_service_ << ++ endl << ++ service_name_ << "::Service::~Service() {" << endl << ++ "}" << endl; ++ ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ string function_name = (*f_iter)->get_name(); ++ f_service_ << ++ endl << ++ "::grpc::Status " << service_name_ << "::Service::" << function_name << ++ "(::grpc::ServerContext* context, const " << service_name_ << "::" << function_name << ++ "Req* request, " << service_name_ << "::" << function_name << "Resp* response) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "(void) context;" << endl << ++ indent() << "(void) request;" << endl << ++ indent() << "(void) response;" << endl << ++ indent() << "return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED,\"\");" << endl; ++ indent_down(); ++ ++ f_service_ << ++ "}" << endl; ++ } ++ + } + + /** +@@ -3095,7 +3449,7 @@ void t_cpp_generator::generate_function_helpers(t_service* tservice, t_function* + + std::ofstream& out = (gen_templates_ ? f_service_tcc_ : f_service_); + +- t_struct result(program_, tservice->get_name() + "_" + tfunction->get_name() + "_result"); ++ t_struct result(program_, tfunction->get_name() + "Resp"); + t_field success(tfunction->get_returntype(), "success", 0); + if (!tfunction->get_returntype()->is_void()) { + result.append(&success); +@@ -3109,17 +3463,9 @@ void t_cpp_generator::generate_function_helpers(t_service* tservice, t_function* + } + + generate_struct_declaration(f_header_, &result, false); +- generate_struct_definition(out, f_service_, &result, false); ++ generate_struct_definition(out, f_service_, &result, true); + generate_struct_reader(out, &result); + generate_struct_result_writer(out, &result); +- +- result.set_name(tservice->get_name() + "_" + tfunction->get_name() + "_presult"); +- generate_struct_declaration(f_header_, &result, false, true, true, gen_cob_style_); +- generate_struct_definition(out, f_service_, &result, false); +- generate_struct_reader(out, &result, true); +- if (gen_cob_style_) { +- generate_struct_writer(out, &result, true); +- } + } + + /** +@@ -3162,8 +3508,8 @@ void t_cpp_generator::generate_process_function(t_service* tservice, + << endl; + scope_up(out); + +- string argsname = tservice->get_name() + "_" + tfunction->get_name() + "_args"; +- string resultname = tservice->get_name() + "_" + tfunction->get_name() + "_result"; ++ string argsname = tfunction->get_name() + "Req"; ++ string resultname = tfunction->get_name() + "Resp"; + + if (tfunction->is_oneway() && !unnamed_oprot_seqid) { + out << indent() << "(void) seqid;" << endl << indent() << "(void) oprot;" << endl; +@@ -3320,7 +3666,7 @@ void t_cpp_generator::generate_process_function(t_service* tservice, + out << indent() << "(void) seqid;" << endl << indent() << "(void) oprot;" << endl; + } + +- out << indent() << tservice->get_name() + "_" + tfunction->get_name() << "_args args;" << endl ++ out << indent() << tfunction->get_name() << "Req args;" << endl + << indent() << "void* ctx = NULL;" << endl << indent() + << "if (this->eventHandler_.get() != NULL) {" << endl << indent() + << " ctx = this->eventHandler_->getContext(" << service_func_name << ", NULL);" << endl +@@ -3487,7 +3833,7 @@ void t_cpp_generator::generate_process_function(t_service* tservice, + << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << endl << endl; + + // Throw the TDelayedException, and catch the result +- out << indent() << tservice->get_name() << "_" << tfunction->get_name() << "_result result;" ++ out << indent() << tfunction->get_name() << "Resp result;" + << endl << endl << indent() << "try {" << endl; + indent_up(); + out << indent() << "_throw->throw_it();" << endl << indent() << "return cob(false);" +diff --git a/tutorial/cpp/CMakeLists.txt b/tutorial/cpp/CMakeLists.txt +deleted file mode 100644 +index 8a3d085..0000000 +--- a/tutorial/cpp/CMakeLists.txt ++++ /dev/null +@@ -1,53 +0,0 @@ +-# +-# Licensed to the Apache Software Foundation (ASF) under one +-# or more contributor license agreements. See the NOTICE file +-# distributed with this work for additional information +-# regarding copyright ownership. The ASF licenses this file +-# to you 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. +-# +- +-find_package(Boost 1.53.0 REQUIRED) +-include_directories(SYSTEM "${Boost_INCLUDE_DIRS}") +- +-#Make sure gen-cpp files can be included +-include_directories("${CMAKE_CURRENT_BINARY_DIR}") +-include_directories("${CMAKE_CURRENT_BINARY_DIR}/gen-cpp") +-include_directories("${PROJECT_SOURCE_DIR}/lib/cpp/src") +- +-include(ThriftMacros) +- +-set(tutorialgencpp_SOURCES +- gen-cpp/Calculator.cpp +- gen-cpp/SharedService.cpp +- gen-cpp/shared_constants.cpp +- gen-cpp/shared_types.cpp +- gen-cpp/tutorial_constants.cpp +- gen-cpp/tutorial_types.cpp +-) +-add_library(tutorialgencpp STATIC ${tutorialgencpp_SOURCES}) +-LINK_AGAINST_THRIFT_LIBRARY(tutorialgencpp thrift) +- +-add_custom_command(OUTPUT gen-cpp/Calculator.cpp gen-cpp/SharedService.cpp gen-cpp/shared_constants.cpp gen-cpp/shared_types.cpp gen-cpp/tutorial_constants.cpp gen-cpp/tutorial_types.cpp +- COMMAND ${THRIFT_COMPILER} --gen cpp -r ${PROJECT_SOURCE_DIR}/tutorial/tutorial.thrift +-) +- +-add_executable(TutorialServer CppServer.cpp) +-target_link_libraries(TutorialServer tutorialgencpp) +-LINK_AGAINST_THRIFT_LIBRARY(TutorialServer thrift) +-target_link_libraries(TutorialServer ${ZLIB_LIBRARIES}) +- +-add_executable(TutorialClient CppClient.cpp) +-target_link_libraries(TutorialClient tutorialgencpp) +-LINK_AGAINST_THRIFT_LIBRARY(TutorialClient thrift) +-target_link_libraries(TutorialClient ${ZLIB_LIBRARIES}) +diff --git a/tutorial/cpp/CppClient.cpp b/tutorial/cpp/CppClient.cpp +index 2763fee..c41604e 100644 +--- a/tutorial/cpp/CppClient.cpp ++++ b/tutorial/cpp/CppClient.cpp +@@ -1,80 +1,94 @@ + /* +- * Licensed to the Apache Software Foundation (ASF) under one +- * or more contributor license agreements. See the NOTICE file +- * distributed with this work for additional information +- * regarding copyright ownership. The ASF licenses this file +- * to you 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 ++ * Copyright 2015, Google Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are ++ * met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above ++ * copyright notice, this list of conditions and the following disclaimer ++ * in the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Google Inc. nor the names of its ++ * contributors may be used to endorse or promote products derived from ++ * this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +- * 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 ++#include ++#include + +-#include +-#include +-#include +- +-#include "../gen-cpp/Calculator.h" ++#include + +-using namespace std; +-using namespace apache::thrift; +-using namespace apache::thrift::protocol; +-using namespace apache::thrift::transport; ++#include "gen-cpp/Greeter.grpc.thrift.h" + +-using namespace tutorial; +-using namespace shared; ++using grpc::Channel; ++using grpc::ClientContext; ++using grpc::Status; ++using test::Greeter; ++using namespace test; + +-int main() { +- boost::shared_ptr socket(new TSocket("localhost", 9090)); +- boost::shared_ptr transport(new TBufferedTransport(socket)); +- boost::shared_ptr protocol(new TBinaryProtocol(transport)); +- CalculatorClient client(protocol); ++class GreeterClient { ++ public: ++ GreeterClient(std::shared_ptr channel) ++ : stub_(Greeter::NewStub(channel)) {} + +- try { +- transport->open(); ++ // Assambles the client's payload, sends it and presents the response back ++ // from the server. ++ std::string SayHello(const std::string& user) { ++ // Data we are sending to the server. ++ Greeter::SayHelloReq req; ++ req.request.name = user; + +- client.ping(); +- cout << "ping()" << endl; ++ // Container for the data we expect from the server. ++ Greeter::SayHelloResp reply; + +- cout << "1 + 1 = " << client.add(1, 1) << endl; ++ // Context for the client. It could be used to convey extra information to ++ // the server and/or tweak certain RPC behaviors. ++ ClientContext context; + +- Work work; +- work.op = Operation::DIVIDE; +- work.num1 = 1; +- work.num2 = 0; ++ // The actual RPC. ++ Status status = stub_->SayHello(&context, req, &reply); + +- try { +- client.calculate(1, work); +- cout << "Whoa? We can divide by zero!" << endl; +- } catch (InvalidOperation& io) { +- cout << "InvalidOperation: " << io.why << endl; +- // or using generated operator<<: cout << io << endl; +- // or by using std::exception native method what(): cout << io.what() << endl; ++ // Act upon its status. ++ if (status.ok()) { ++ return reply.success.message; ++ } else { ++ return "RPC failed"; + } ++ } + +- work.op = Operation::SUBTRACT; +- work.num1 = 15; +- work.num2 = 10; +- int32_t diff = client.calculate(1, work); +- cout << "15 - 10 = " << diff << endl; ++ private: ++ std::unique_ptr stub_; ++}; + +- // Note that C++ uses return by reference for complex types to avoid +- // costly copy construction +- SharedStruct ss; +- client.getStruct(ss, 1); +- cout << "Received log: " << ss << endl; ++int main() { ++ // Instantiate the client. It requires a channel, out of which the actual RPCs ++ // are created. This channel models a connection to an endpoint (in this case, ++ // localhost at port 50051). We indicate that the channel isn't authenticated ++ // (use of InsecureChannelCredentials()). ++ GreeterClient greeter(grpc::CreateChannel( ++ "localhost:50051", grpc::InsecureChannelCredentials())); ++ std::string user("world"); ++ std::string reply = greeter.SayHello(user); ++ std::cout << "Greeter received: " << reply << std::endl; + +- transport->close(); +- } catch (TException& tx) { +- cout << "ERROR: " << tx.what() << endl; +- } ++ return 0; + } +diff --git a/tutorial/cpp/CppServer.cpp b/tutorial/cpp/CppServer.cpp +index eafffa9..c838b61 100644 +--- a/tutorial/cpp/CppServer.cpp ++++ b/tutorial/cpp/CppServer.cpp +@@ -1,181 +1,87 @@ + /* +- * Licensed to the Apache Software Foundation (ASF) under one +- * or more contributor license agreements. See the NOTICE file +- * distributed with this work for additional information +- * regarding copyright ownership. The ASF licenses this file +- * to you 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 ++ * Copyright 2015, Google Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are ++ * met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above ++ * copyright notice, this list of conditions and the following disclaimer ++ * in the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Google Inc. nor the names of its ++ * contributors may be used to endorse or promote products derived from ++ * this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +- * 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 +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +- + #include +-#include +-#include +- +-#include "../gen-cpp/Calculator.h" ++#include ++#include + +-using namespace std; +-using namespace apache::thrift; +-using namespace apache::thrift::concurrency; +-using namespace apache::thrift::protocol; +-using namespace apache::thrift::transport; +-using namespace apache::thrift::server; ++#include + +-using namespace tutorial; +-using namespace shared; ++#include "gen-cpp/Greeter.grpc.thrift.h" ++#include + +-class CalculatorHandler : public CalculatorIf { +-public: +- CalculatorHandler() {} ++using grpc::Server; ++using grpc::ServerBuilder; ++using grpc::ServerContext; ++using grpc::Status; ++using test::Greeter; + +- void ping() { cout << "ping()" << endl; } ++using namespace grpc; ++using namespace test; + +- int32_t add(const int32_t n1, const int32_t n2) { +- cout << "add(" << n1 << ", " << n2 << ")" << endl; +- return n1 + n2; +- } ++// Logic and data behind the server's behavior. ++class GreeterServiceImpl final : public Greeter::Service { ++ Status SayHello(ServerContext* context,const Greeter::SayHelloReq* request, ++ Greeter::SayHelloResp* reply) override { ++ std::string prefix("Hello "); + +- int32_t calculate(const int32_t logid, const Work& work) { +- cout << "calculate(" << logid << ", " << work << ")" << endl; +- int32_t val; ++ reply->success.message = prefix + request->request.name; + +- switch (work.op) { +- case Operation::ADD: +- val = work.num1 + work.num2; +- break; +- case Operation::SUBTRACT: +- val = work.num1 - work.num2; +- break; +- case Operation::MULTIPLY: +- val = work.num1 * work.num2; +- break; +- case Operation::DIVIDE: +- if (work.num2 == 0) { +- InvalidOperation io; +- io.whatOp = work.op; +- io.why = "Cannot divide by 0"; +- throw io; +- } +- val = work.num1 / work.num2; +- break; +- default: +- InvalidOperation io; +- io.whatOp = work.op; +- io.why = "Invalid Operation"; +- throw io; +- } +- +- SharedStruct ss; +- ss.key = logid; +- ss.value = to_string(val); +- +- log[logid] = ss; +- +- return val; ++ return Status::OK; + } +- +- void getStruct(SharedStruct& ret, const int32_t logid) { +- cout << "getStruct(" << logid << ")" << endl; +- ret = log[logid]; +- } +- +- void zip() { cout << "zip()" << endl; } +- +-protected: +- map log; + }; + +-/* +- CalculatorIfFactory is code generated. +- CalculatorCloneFactory is useful for getting access to the server side of the +- transport. It is also useful for making per-connection state. Without this +- CloneFactory, all connections will end up sharing the same handler instance. +-*/ +-class CalculatorCloneFactory : virtual public CalculatorIfFactory { +- public: +- virtual ~CalculatorCloneFactory() {} +- virtual CalculatorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) +- { +- boost::shared_ptr sock = boost::dynamic_pointer_cast(connInfo.transport); +- cout << "Incoming connection\n"; +- cout << "\tSocketInfo: " << sock->getSocketInfo() << "\n"; +- cout << "\tPeerHost: " << sock->getPeerHost() << "\n"; +- cout << "\tPeerAddress: " << sock->getPeerAddress() << "\n"; +- cout << "\tPeerPort: " << sock->getPeerPort() << "\n"; +- return new CalculatorHandler; +- } +- virtual void releaseHandler( ::shared::SharedServiceIf* handler) { +- delete handler; +- } +-}; ++void RunServer() { ++ std::string server_address("0.0.0.0:50051"); ++ GreeterServiceImpl service; ++ ++ ServerBuilder builder; ++ // Listen on the given address without any authentication mechanism. ++ builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); ++ // Register "service" as the instance through which we'll communicate with ++ // clients. In this case it corresponds to an *synchronous* service. ++ builder.RegisterService(&service); ++ // Finally assemble the server. ++ std::unique_ptr server(builder.BuildAndStart()); ++ std::cout << "Server listening on " << server_address << std::endl; ++ ++ // Wait for the server to shutdown. Note that some other thread must be ++ // responsible for shutting down the server for this call to ever return. ++ server->Wait(); ++} + + int main() { +- TThreadedServer server( +- boost::make_shared(boost::make_shared()), +- boost::make_shared(9090), //port +- boost::make_shared(), +- boost::make_shared()); +- +- /* +- // if you don't need per-connection state, do the following instead +- TThreadedServer server( +- boost::make_shared(boost::make_shared()), +- boost::make_shared(9090), //port +- boost::make_shared(), +- boost::make_shared()); +- */ +- +- /** +- * Here are some alternate server types... +- +- // This server only allows one connection at a time, but spawns no threads +- TSimpleServer server( +- boost::make_shared(boost::make_shared()), +- boost::make_shared(9090), +- boost::make_shared(), +- boost::make_shared()); +- +- const int workerCount = 4; +- +- boost::shared_ptr threadManager = +- ThreadManager::newSimpleThreadManager(workerCount); +- threadManager->threadFactory( +- boost::make_shared()); +- threadManager->start(); +- +- // This server allows "workerCount" connection at a time, and reuses threads +- TThreadPoolServer server( +- boost::make_shared(boost::make_shared()), +- boost::make_shared(9090), +- boost::make_shared(), +- boost::make_shared(), +- threadManager); +- */ ++ RunServer(); + +- cout << "Starting the server..." << endl; +- server.serve(); +- cout << "Done." << endl; + return 0; + } +diff --git a/tutorial/cpp/Makefile.am b/tutorial/cpp/Makefile.am +index 184a69d..581f75e 100755 +--- a/tutorial/cpp/Makefile.am ++++ b/tutorial/cpp/Makefile.am +@@ -18,44 +18,38 @@ + # + AUTOMAKE_OPTIONS = subdir-objects serial-tests + +-BUILT_SOURCES = gen-cpp/shared_types.cpp \ +- gen-cpp/tutorial_types.cpp ++BUILT_SOURCES = gen-cpp/test_types.cpp + +-noinst_LTLIBRARIES = libtutorialgencpp.la +-nodist_libtutorialgencpp_la_SOURCES = \ +- gen-cpp/Calculator.cpp \ +- gen-cpp/Calculator.h \ +- gen-cpp/SharedService.cpp \ +- gen-cpp/SharedService.h \ +- gen-cpp/shared_constants.cpp \ +- gen-cpp/shared_constants.h \ +- gen-cpp/shared_types.cpp \ +- gen-cpp/shared_types.h \ +- gen-cpp/tutorial_constants.cpp \ +- gen-cpp/tutorial_constants.h \ +- gen-cpp/tutorial_types.cpp \ +- gen-cpp/tutorial_types.h ++#noinst_LTLIBRARIES = libtutorialgencpp.la ++noinst_LTLIBRARIES = libtestgencpp.la ++nodist_libtestgencpp_la_SOURCES = \ ++ gen-cpp/Greeter.grpc.thrift.cpp \ ++ gen-cpp/Greeter.grpc.thrift.h \ ++ gen-cpp/test_constants.cpp \ ++ gen-cpp/test_constants.h \ ++ gen-cpp/test_types.cpp \ ++ gen-cpp/test_types.h + + + +-libtutorialgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la ++libtestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la + + noinst_PROGRAMS = \ +- TutorialServer \ +- TutorialClient ++ TestServer \ ++ TestClient + +-TutorialServer_SOURCES = \ ++TestServer_SOURCES = \ + CppServer.cpp + +-TutorialServer_LDADD = \ +- libtutorialgencpp.la \ ++TestServer_LDADD = \ ++ libtestgencpp.la \ + $(top_builddir)/lib/cpp/libthrift.la + +-TutorialClient_SOURCES = \ ++TestClient_SOURCES = \ + CppClient.cpp + +-TutorialClient_LDADD = \ +- libtutorialgencpp.la \ ++TestClient_LDADD = \ ++ libtestgencpp.la \ + $(top_builddir)/lib/cpp/libthrift.la + + # +@@ -63,21 +57,21 @@ TutorialClient_LDADD = \ + # + THRIFT = $(top_builddir)/compiler/cpp/thrift + +-gen-cpp/Calculator.cpp gen-cpp/SharedService.cpp gen-cpp/shared_constants.cpp gen-cpp/shared_types.cpp gen-cpp/tutorial_constants.cpp gen-cpp/tutorial_types.cpp: $(top_srcdir)/tutorial/tutorial.thrift ++gen-cpp/Greeter.grpc.thrift.cpp gen-cpp/test_constants.cpp gen-cpp/test_types.cpp: $(top_srcdir)/tutorial/cpp/test.thrift + $(THRIFT) --gen cpp -r $< + + AM_CPPFLAGS = $(BOOST_CPPFLAGS) $(LIBEVENT_CPPFLAGS) -I$(top_srcdir)/lib/cpp/src -Igen-cpp + AM_CXXFLAGS = -Wall -Wextra -pedantic +-AM_LDFLAGS = $(BOOST_LDFLAGS) $(LIBEVENT_LDFLAGS) ++AM_LDFLAGS = $(BOOST_LDFLAGS) $(LIBEVENT_LDFLAGS) `pkg-config --libs grpc++ grpc` -lpthread -ldl -lgrpc + + clean-local: +- $(RM) gen-cpp/* ++ $(RM) -r gen-cpp + +-tutorialserver: all +- ./TutorialServer ++testserver: all ++ ./TestServer + +-tutorialclient: all +- ./TutorialClient ++testclient: all ++ ./TestClient + + style-local: + $(CPPSTYLE_CMD) +diff --git a/tutorial/cpp/test.thrift b/tutorial/cpp/test.thrift +new file mode 100644 +index 0000000..de3c9a4 +--- /dev/null ++++ b/tutorial/cpp/test.thrift +@@ -0,0 +1,13 @@ ++namespace cpp test ++ ++struct HelloRequest { ++ 1:string name ++} ++ ++struct HelloResponse { ++ 1:string message ++} ++ ++service Greeter { ++ HelloResponse SayHello(1:HelloRequest request); ++} +\ No newline at end of file +-- +2.8.0.rc3.226.g39d4020 + + +From 1d47ed062e62d136c3db9f6fc1dde9e2f794cf22 Mon Sep 17 00:00:00 2001 +From: chedeti +Date: Sun, 31 Jul 2016 16:23:53 -0700 +Subject: [PATCH 3/3] grpc java plugins generator + +for examples refer to https://github.com/grpc/grpc-java/tree/master/examples/thrift +--- + compiler/cpp/src/generate/t_java_generator.cc | 906 +++++++++++++++++++++++++- + tutorial/Makefile.am | 8 +- + 2 files changed, 887 insertions(+), 27 deletions(-) + +diff --git a/compiler/cpp/src/generate/t_java_generator.cc b/compiler/cpp/src/generate/t_java_generator.cc +index 2db8cb8..95e1ca8 100644 +--- a/compiler/cpp/src/generate/t_java_generator.cc ++++ b/compiler/cpp/src/generate/t_java_generator.cc +@@ -97,10 +97,10 @@ public: + } else if(iter->second.compare("suppress") == 0) { + suppress_generated_annotations_ = true; + } else { +- throw "unknown option java:" + iter->first + "=" + iter->second; ++ throw "unknown option java:" + iter->first + "=" + iter->second; + } + } else { +- throw "unknown option java:" + iter->first; ++ throw "unknown option java:" + iter->first; + } + } + +@@ -195,6 +195,17 @@ public: + void generate_service_async_server(t_service* tservice); + void generate_process_function(t_service* tservice, t_function* tfunction); + void generate_process_async_function(t_service* tservice, t_function* tfunction); ++ void generate_service_impl_base(t_service* tservice); ++ void generate_method_descriptors(t_service* tservice); ++ void generate_stub(t_service* tservice); ++ void generate_blocking_stub(t_service* tservice); ++ void generate_future_stub(t_service* tservice); ++ void generate_method_ids(t_service* tservice); ++ void generate_method_handlers(t_service* tservice); ++ void generate_service_descriptors(t_service* tservice); ++ void generate_service_builder(t_service* tservice); ++ void generate_arg_ids(t_service* tservice); ++ void generate_message_factory(t_service* tservice); + + void generate_java_union(t_struct* tstruct); + void generate_union_constructor(ofstream& out, t_struct* tstruct); +@@ -307,6 +318,8 @@ public: + std::string java_package(); + std::string java_type_imports(); + std::string java_suppressions(); ++ std::string grpc_imports(); ++ std::string import_extended_service(t_service* tservice); + std::string type_name(t_type* ttype, + bool in_container = false, + bool in_init = false, +@@ -368,7 +381,7 @@ private: + bool use_option_type_; + bool undated_generated_annotations_; + bool suppress_generated_annotations_; +- ++ + }; + + /** +@@ -456,6 +469,35 @@ string t_java_generator::java_suppressions() { + return "@SuppressWarnings({\"cast\", \"rawtypes\", \"serial\", \"unchecked\", \"unused\"})\n"; + } + ++string t_java_generator::grpc_imports() { ++ return ++ string() + ++ "import static io.grpc.stub.ClientCalls.asyncUnaryCall;\n" + ++ "import static io.grpc.stub.ClientCalls.asyncServerStreamingCall;\n" + ++ "import static io.grpc.stub.ClientCalls.asyncClientStreamingCall;\n" + ++ "import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall;\n" + ++ "import static io.grpc.stub.ClientCalls.blockingUnaryCall;\n" + ++ "import static io.grpc.stub.ClientCalls.blockingServerStreamingCall;\n" + ++ "import static io.grpc.stub.ClientCalls.futureUnaryCall;\n" + ++ "import static io.grpc.MethodDescriptor.generateFullMethodName;\n" + ++ "import static io.grpc.stub.ServerCalls.asyncUnaryCall;\n" + ++ "import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;\n" + ++ "import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;\n" + ++ "import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;\n" + ++ "import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;\n" + ++ "import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;\n" + ++ "import io.grpc.thrift.ThriftUtils;\n\n"; ++} ++ ++string t_java_generator::import_extended_service(t_service* tservice) { ++ if (tservice == nullptr) { ++ return string() + "\n"; ++ } ++ string ns = tservice->get_program()->get_namespace("java"); ++ string extend_service_name = tservice->get_name() + "Grpc"; ++ return string() + "import " + ns + "." + extend_service_name + ";\n\n"; ++} ++ + /** + * Nothing in Java + */ +@@ -2772,25 +2814,51 @@ void t_java_generator::generate_field_value_meta_data(std::ofstream& out, t_type + */ + void t_java_generator::generate_service(t_service* tservice) { + // Make output file +- string f_service_name = package_dir_ + "/" + make_valid_java_filename(service_name_) + ".java"; ++ string f_service_name = package_dir_ + "/" + make_valid_java_filename(service_name_) + "Grpc.java"; + f_service_.open(f_service_name.c_str()); + +- f_service_ << autogen_comment() << java_package() << java_type_imports() << java_suppressions(); ++ f_service_ << ++ autogen_comment() << ++ java_package() << ++ java_type_imports() << ++ grpc_imports() << ++ import_extended_service(tservice->get_extends()); ++ java_suppressions(); ++ ++ f_service_ << ++ "public class " << service_name_ << "Grpc {" << endl << ++ endl; + +- if (!suppress_generated_annotations_) { +- generate_javax_generated_annotation(f_service_); +- } +- f_service_ << "public class " << service_name_ << " {" << endl << endl; + indent_up(); + ++ // generate constructor ++ f_service_ << ++ indent() << "private " << service_name_ << ++ "Grpc() {}" << endl << endl; ++ ++ f_service_ << ++ indent() << "public static final String SERVICE_NAME = " << ++ "\"" << package_name_ << "." << service_name_ << "\";" << endl << endl; ++ + // Generate the three main parts of the service + generate_service_interface(tservice); +- generate_service_async_interface(tservice); +- generate_service_client(tservice); +- generate_service_async_client(tservice); +- generate_service_server(tservice); +- generate_service_async_server(tservice); ++ generate_arg_ids(tservice); ++ generate_message_factory(tservice); ++ generate_service_impl_base(tservice); ++ //generate_service_async_interface(tservice); ++ //generate_service_client(tservice); ++ //generate_service_async_client(tservice); ++ //generate_service_server(tservice); ++ //generate_service_async_server(tservice); + generate_service_helpers(tservice); ++ generate_method_descriptors(tservice); ++ generate_stub(tservice); ++ generate_blocking_stub(tservice); ++ generate_future_stub(tservice); ++ generate_method_ids(tservice); ++ generate_method_handlers(tservice); ++ generate_service_descriptors(tservice); ++ generate_service_builder(tservice); + + indent_down(); + f_service_ << "}" << endl; +@@ -2805,24 +2873,820 @@ void t_java_generator::generate_service(t_service* tservice) { + void t_java_generator::generate_service_interface(t_service* tservice) { + string extends = ""; + string extends_iface = ""; +- if (tservice->get_extends() != NULL) { +- extends = type_name(tservice->get_extends()); +- extends_iface = " extends " + extends + ".Iface"; +- } + + generate_java_doc(f_service_, tservice); +- f_service_ << indent() << "public interface Iface" << extends_iface << " {" << endl << endl; ++ f_service_ << indent() << ++ "@java.lang.Deprecated public static interface " << service_name_; ++ ++ if (tservice->get_extends() != nullptr) { ++ f_service_ << " extends " << tservice->get_extends()->get_name() + "Grpc." << ++ tservice->get_extends()->get_name() << endl; ++ } ++ f_service_ << " {" << endl; ++ ++ indent_up(); ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ //generate_java_doc(f_service_, *f_iter); ++ f_service_ << ++ indent() << "public void " << (*f_iter)->get_name() << "(" << (*f_iter)->get_name() << ++ "_args request," << endl << ++ indent() << " io.grpc.stub.StreamObserver<" << (*f_iter)->get_name() << ++ "_result> responseObserver);" << endl << endl; ++ } ++ indent_down(); ++ f_service_ << indent() << "}" << endl << endl; ++} ++ ++void t_java_generator::generate_arg_ids(t_service* tservice) { ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ int i=0; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << indent() << ++ "private static final int ARG_IN_METHOD_" << ++ (*f_iter)->get_name() << " = " << ++i << ";" << endl; ++ f_service_ << indent() << ++ "private static final int ARG_OUT_METHOD_" << ++ (*f_iter)->get_name() << " = " << ++i << ";" << endl; ++ } ++ f_service_ << endl; ++ ++ if (tservice->get_extends() != nullptr) { ++ f_service_ << indent() << "// ARG IDs for extended service" << endl; ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << indent() << ++ "private static final int ARG_IN_METHOD_" << ++ (*f_iter)->get_name() << " = " << ++i << ";" << endl; ++ f_service_ << indent() << ++ "private static final int ARG_OUT_METHOD_" << ++ (*f_iter)->get_name() << " = " << ++i << ";" << endl; ++ } ++ f_service_ << endl; ++ } ++} ++ ++void t_java_generator::generate_message_factory(t_service* tservice) { ++ f_service_ << indent() << ++ "private static final class ThriftMessageFactory>" << endl << indent() << ++ " implements io.grpc.thrift.MessageFactory {" << endl; ++ indent_up(); ++ f_service_ << indent() << ++ "private final int id;" << endl << endl; ++ f_service_ << endl; ++ ++ f_service_ << indent() << ++ "ThriftMessageFactory(int id) {" << endl << ++ indent() << " this.id = id;" << endl << ++ indent() << "}" << endl; ++ ++ f_service_ << indent() << ++ "@java.lang.Override" << endl << ++ indent() << "public T newInstance() {" << endl; ++ indent_up(); ++ ++ f_service_ << indent() << ++ "Object o;" << endl << ++ indent() << "switch (id) {" << endl; ++ ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << indent() << ++ "case ARG_IN_METHOD_" << (*f_iter)->get_name() << ":" << endl << ++ indent() << " o = new " << (*f_iter)->get_name() << "_args();" << ++ endl << indent() << " break;" << endl; ++ f_service_ << indent() << ++ "case ARG_OUT_METHOD_" << (*f_iter)->get_name() << ":" << endl << ++ indent() << " o = new " << (*f_iter)->get_name() << "_result();" << ++ endl << indent() << " break;" << endl; ++ } ++ ++ if (tservice->get_extends() != nullptr) { ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ string extend_service_name = extend_service->get_name() + "Grpc"; ++ for (f_iter = functions.begin(); f_iter!= functions.end(); ++f_iter) { ++ f_service_ << indent() << ++ "case ARG_IN_METHOD_" << (*f_iter)->get_name() << ":" << endl << ++ indent() << " o = new " << extend_service_name << "." << (*f_iter)->get_name() << "_args();" << ++ endl << indent() << " break;" << endl; ++ f_service_ << indent() << ++ "case ARG_OUT_METHOD_" << (*f_iter)->get_name() << ":" << endl << ++ indent() << " o = new " << extend_service_name << "." << (*f_iter)->get_name() << "_result();" << ++ endl << indent() << " break;" << endl; ++ } ++ } ++ ++ f_service_ << indent() << ++ "default:" << endl << indent() << ++ " throw new AssertionError();" << endl << indent() << ++ "}" << endl; ++ ++ f_service_ << indent() << ++ "@java.lang.SuppressWarnings(\"unchecked\")" << endl << ++ indent() << "T t = (T) o;" << endl << indent() << ++ "return t;" << endl; ++ ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl; ++ ++ indent_down(); ++ f_service_ << indent() << "}" << endl; ++} ++ ++void t_java_generator::generate_service_impl_base(t_service* tservice) { ++ f_service_ << ++ indent() << "public static abstract class " << service_name_ << ++ "ImplBase implements " << service_name_ << ", io.grpc.BindableService {" << endl; ++ indent_up(); ++ ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "public void " << (*f_iter)->get_name() << "(" << (*f_iter)->get_name() << ++ "_args request, " << endl << ++ indent() << " io.grpc.stub.StreamObserver<" << (*f_iter)->get_name() << ++ "_result> responseObserver) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "asyncUnimplementedUnaryCall(METHOD_" << (*f_iter)->get_name() << ++ ", responseObserver);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ } ++ ++ if (tservice->get_extends() != nullptr) { ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ string extend_service_name = extend_service->get_name() + "Grpc" ; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "public void " << (*f_iter)->get_name() << "(" << ++ extend_service_name << "." << (*f_iter)->get_name() << ++ "_args request, " << endl << ++ indent() << " io.grpc.stub.StreamObserver<" << extend_service_name ++ << "." << (*f_iter)->get_name() << "_result> responseObserver) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "asyncUnimplementedUnaryCall(METHOD_" << (*f_iter)->get_name() << ++ ", responseObserver);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ } ++ } ++ ++ f_service_ << ++ indent() << "@java.lang.Override" << ++ " public io.grpc.ServerServiceDefinition bindService() {" << endl; + indent_up(); ++ f_service_ << ++ indent() << "return " << service_name_ << "Grpc.bindService(this);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ // generate Abstract Service ++ f_service_ << ++ indent() << "@java.lang.Deprecated public static abstract class Abstract" << service_name_ << ++ " extends " << service_name_ << "ImplBase {}" << endl << endl; ++} ++ ++void t_java_generator::generate_method_descriptors(t_service* tservice) { ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ for( f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "public static final io.grpc.MethodDescriptor<" << ++ (*f_iter)->get_name() << "_args," << endl << ++ indent() << " " << (*f_iter)->get_name() << "_result> METHOD_" << (*f_iter)->get_name() << ++ " = " << endl << indent() << " io.grpc.MethodDescriptor.create(" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << " io.grpc.MethodDescriptor.MethodType.UNARY," << endl << ++ indent() << " generateFullMethodName(" << "\"" << package_name_ << "." << ++ service_name_ << "\" , \"" << (*f_iter)->get_name() << "\")," << endl << ++ indent() << " io.grpc.thrift.ThriftUtils.marshaller(" << endl << ++ indent() << " new ThriftMessageFactory<" << (*f_iter)->get_name() << ++ "_args>( ARG_IN_METHOD_" << (*f_iter)->get_name() << "))," << endl << ++ indent() << " io.grpc.thrift.ThriftUtils.marshaller(" << endl << ++ indent() << " new ThriftMessageFactory<" << (*f_iter)->get_name() << ++ "_result>( ARG_OUT_METHOD_" << (*f_iter)->get_name() << ")));" << endl << endl; ++ indent_down(); ++ } ++ ++ if(tservice->get_extends() != nullptr) { ++ t_service* extends_service = tservice->get_extends(); ++ functions = extends_service->get_functions(); ++ string extend_service_name = extends_service->get_name() + "Grpc"; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "public static final io.grpc.MethodDescriptor<" << extend_service_name << "." << ++ (*f_iter)->get_name() << "_args," << endl << ++ indent() << " " << extend_service_name << "." << (*f_iter)->get_name() << "_result> METHOD_" ++ << (*f_iter)->get_name() << " = " << endl << indent() << ++ " io.grpc.MethodDescriptor.create(" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << " io.grpc.MethodDescriptor.MethodType.UNARY," << endl << ++ indent() << " generateFullMethodName(" << "\"" << package_name_ << "." << ++ service_name_ << "\" , \"" << (*f_iter)->get_name() << "\")," << endl << ++ indent() << " io.grpc.thrift.ThriftUtils.marshaller(" << endl << ++ indent() << " new ThriftMessageFactory<" << extend_service_name << "." << ++ (*f_iter)->get_name() << "_args>( ARG_IN_METHOD_" << (*f_iter)->get_name() << "))," << endl << ++ indent() << " io.grpc.thrift.ThriftUtils.marshaller(" << endl << ++ indent() << " new ThriftMessageFactory<" << extend_service_name << "." << (*f_iter)->get_name() << ++ "_result>( ARG_OUT_METHOD_" << (*f_iter)->get_name() << ")));" << endl << endl; ++ indent_down(); ++ } ++ } ++} ++ ++void t_java_generator::generate_stub(t_service* tservice) { ++ f_service_ << ++ indent() << ++ "public static " << service_name_ << ++ "Stub newStub(io.grpc.Channel channel) {" << ++ endl; ++ ++ indent_up(); ++ f_service_ << ++ indent() << ++ "return new " << service_name_ << "Stub(channel);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ // generate Stub impl ++ ++ f_service_ << ++ indent() << "public static class " << ++ service_name_ << "Stub extends io.grpc.stub.AbstractStub<" << ++ service_name_ << "Stub>" << endl << ++ indent() << " implements " << service_name_ << "{" << endl; ++ indent_up(); ++ ++ f_service_ << ++ indent() << "private " << service_name_ << "Stub(io.grpc.Channel channel) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "super(channel);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ f_service_ << ++ indent() << "private " << service_name_ << "Stub(io.grpc.Channel channel, " << endl << ++ indent() << " io.grpc.CallOptions callOptions) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "super(channel, callOptions);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "protected " << service_name_ << "Stub build(io.grpc.Channel channel, " << ++ endl << indent() << " io.grpc.CallOptions callOptions) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return new " << service_name_ << "Stub(channel, callOptions);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "public void " << (*f_iter)->get_name() << "(" << ++ (*f_iter)->get_name() << "_args request," << endl << indent() << ++ " io.grpc.stub.StreamObserver<" << (*f_iter)->get_name() << ++ "_result> responseObserver) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "asyncUnaryCall(" << endl << ++ indent() << " getChannel().newCall(METHOD_" << (*f_iter)->get_name() << ++ ", getCallOptions()), request, responseObserver);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ } ++ ++ if (tservice->get_extends() != nullptr) { ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ string extend_service_name = extend_service->get_name() + "Grpc"; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "public void " << (*f_iter)->get_name() << "(" << ++ extend_service_name << "." << (*f_iter)->get_name() << "_args request," ++ << endl << indent() << " io.grpc.stub.StreamObserver<" << ++ extend_service_name << "." << (*f_iter)->get_name() << ++ "_result> responseObserver) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "asyncUnaryCall(" << endl << ++ indent() << " getChannel().newCall(METHOD_" << (*f_iter)->get_name() << ++ ", getCallOptions()), request, responseObserver);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ } ++ } ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++} ++ ++void t_java_generator::generate_blocking_stub(t_service* tservice) { ++ f_service_ << ++ indent() << "public static " << service_name_ << ++ "BlockingStub newBlockingStub(" << endl << ++ indent() << " io.grpc.Channel channel) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return new " << service_name_ << "BlockingStub(channel);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ // generate Blocking Client ++ f_service_ << ++ indent() << "@java.lang.Deprecated public static interface " << service_name_ << ++ "BlockingClient " ; ++ ++ if (tservice->get_extends() != nullptr) { ++ string extend_service_name = tservice->get_extends()->get_name(); ++ f_service_ << endl << indent() << " extends " << extend_service_name << "Grpc." << ++ extend_service_name << "BlockingClient " ; ++ } ++ ++ f_service_ << "{" << endl; ++ ++ indent_up(); ++ + vector functions = tservice->get_functions(); + vector::iterator f_iter; + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { +- generate_java_doc(f_service_, *f_iter); +- indent(f_service_) << "public " << function_signature(*f_iter) << ";" << endl << endl; ++ f_service_ << ++ indent() << "public " << (*f_iter)->get_name() << "_result " << ++ (*f_iter)->get_name() << "(" << (*f_iter)->get_name() << "_args request);" << endl << endl; ++ } ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ // generate Blocking Stub impl ++ ++ f_service_ << ++ indent() << "public static class " << ++ service_name_ << "BlockingStub extends io.grpc.stub.AbstractStub<" << ++ service_name_ << "BlockingStub>" << endl << ++ indent() << " implements " << service_name_ << "BlockingClient {"; ++ ++ indent_up(); ++ ++ f_service_ << ++ indent() << "private " << service_name_ << "BlockingStub(io.grpc.Channel channel) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "super(channel);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ f_service_ << ++ indent() << "private " << service_name_ << "BlockingStub(io.grpc.Channel channel, " << endl << ++ indent() << " io.grpc.CallOptions callOptions) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "super(channel, callOptions);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "protected " << service_name_ << "BlockingStub build(io.grpc.Channel channel, " << ++ endl << indent() << " io.grpc.CallOptions callOptions) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return new " << service_name_ << "BlockingStub(channel, callOptions);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "public " << (*f_iter)->get_name() << "_result " << (*f_iter)->get_name() << "(" << ++ (*f_iter)->get_name() << "_args request) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return blockingUnaryCall(" << endl << ++ indent() << " getChannel(), METHOD_" << (*f_iter)->get_name() << ++ ", getCallOptions(), request);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ } ++ ++ if (tservice->get_extends() != nullptr) { ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ string extend_service_name = extend_service->get_name() + "Grpc"; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "public " << extend_service_name << "." << (*f_iter)->get_name() << ++ "_result " << (*f_iter)->get_name() << "(" << extend_service_name << "." << ++ (*f_iter)->get_name() << "_args request) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return blockingUnaryCall(" << endl << ++ indent() << " getChannel(), METHOD_" << (*f_iter)->get_name() << ++ ", getCallOptions(), request);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ } ++ } ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++} ++ ++void t_java_generator::generate_future_stub(t_service* tservice) { ++ f_service_ << ++ indent() << "public static " << service_name_ << ++ "FutureStub newFutureStub(" << endl << ++ indent() << " io.grpc.Channel channel) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return new " << service_name_ << "FutureStub(channel);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ // generate Future Client ++ f_service_ << ++ indent() << "@java.lang.Deprecated public static interface " << service_name_ << ++ "FutureClient " ; ++ ++ if (tservice->get_extends() != nullptr) { ++ string extend_service_name = tservice->get_extends()->get_name(); ++ f_service_ << endl << indent() << " extends " << extend_service_name << "Grpc." << ++ extend_service_name << "FutureClient " ; ++ } ++ f_service_ << "{" << endl; ++ ++ indent_up(); ++ ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "public com.google.common.util.concurrent.ListenableFuture<" << ++ (*f_iter)->get_name() << "_result> " << (*f_iter)->get_name() << "(" << endl << ++ indent() << " " << (*f_iter)->get_name() << "_args request);" << endl << endl; ++ } ++ ++ if (tservice->get_extends() != nullptr) { ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ string extend_service_name = extend_service->get_name() + "Grpc"; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "public com.google.common.util.concurrent.ListenableFuture<" << ++ extend_service_name << "." << (*f_iter)->get_name() << "_result> " << ++ (*f_iter)->get_name() << "(" << endl << ++ indent() << " " << extend_service_name << "." << (*f_iter)->get_name() << ++ "_args request);" << endl << endl; ++ } ++ } ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ // generate Stub impl ++ ++ f_service_ << ++ indent() << "public static class " << ++ service_name_ << "FutureStub extends io.grpc.stub.AbstractStub<" << ++ service_name_ << "FutureStub>" << endl << ++ indent() << " implements " << service_name_ << "FutureClient {" << endl; ++ indent_up(); ++ ++ f_service_ << ++ indent() << "private " << service_name_ << "FutureStub(io.grpc.Channel channel) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "super(channel);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ f_service_ << ++ indent() << "private " << service_name_ << "FutureStub(io.grpc.Channel channel, " << endl << ++ indent() << " io.grpc.CallOptions callOptions) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "super(channel, callOptions);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "protected " << service_name_ << "FutureStub build(io.grpc.Channel channel, " << ++ endl << indent() << " io.grpc.CallOptions callOptions) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return new " << service_name_ << "FutureStub(channel, callOptions);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ functions = tservice->get_functions(); ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "public com.google.common.util.concurrent.ListenableFuture<" << ++ (*f_iter)->get_name() << "_result> " << (*f_iter)->get_name() << "(" << ++ endl << indent() << " " << (*f_iter)->get_name() << "_args request) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return futureUnaryCall(" << endl << ++ indent() << " getChannel().newCall(METHOD_" << (*f_iter)->get_name() << ++ ", getCallOptions()), request);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ } ++ ++ if (tservice->get_extends() != nullptr) { ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ string extend_service_name = extend_service->get_name() + "Grpc"; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "public com.google.common.util.concurrent.ListenableFuture<" << ++ extend_service_name << "." << (*f_iter)->get_name() << "_result> " << ++ (*f_iter)->get_name() << "(" << endl << indent() << " " << ++ extend_service_name << "." << (*f_iter)->get_name() << "_args request) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return futureUnaryCall(" << endl << ++ indent() << " getChannel().newCall(METHOD_" << (*f_iter)->get_name() << ++ ", getCallOptions()), request);" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ } ++ } ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++} ++ ++void t_java_generator::generate_method_ids(t_service* tservice) { ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ int i=0; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter, ++i) { ++ f_service_ << ++ indent() << "private static final int METHODID_" << ++ (*f_iter)->get_name() << " = " << i << ";" << endl; ++ } ++ if (tservice->get_extends() != nullptr) { ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ string extend_service_name = extend_service->get_name() + "Grpc"; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter, ++i) { ++ f_service_ << ++ indent() << "private static final int METHODID_" << ++ (*f_iter)->get_name() << " = " << i << ";" << endl; ++ } ++ } ++ f_service_ << endl; ++} ++ ++void t_java_generator::generate_method_handlers(t_service* tservice) { ++ f_service_ << ++ indent() << "private static class MethodHandlers implements" << ++ endl << indent() << " io.grpc.stub.ServerCalls.UnaryMethod," << ++ endl << indent() << " io.grpc.stub.ServerCalls.ServerStreamingMethod," << ++ endl << indent() << " io.grpc.stub.ServerCalls.ClientStreamingMethod," << ++ endl << indent() << " io.grpc.stub.ServerCalls.BidiStreamingMethod {" << ++ endl; ++ indent_up(); ++ f_service_ << ++ indent() << "private final " << service_name_ << " serviceImpl;" << endl << ++ indent() << "private final int methodId;" << endl << endl; ++ ++ f_service_ << ++ indent() << "public MethodHandlers(" << service_name_ << " serviceImpl, int " << ++ "methodId) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "this.serviceImpl = serviceImpl;" << endl << ++ indent() << "this.methodId = methodId;" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ // invoke ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "@java.lang.SuppressWarnings(\"unchecked\")" << endl << ++ indent() << "public void invoke(Req request, io.grpc.stub.StreamObserver responseObserver) {" << ++ endl; ++ indent_up(); ++ f_service_ << ++ indent() << "switch (methodId) {" << endl; ++ indent_up(); ++ ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "case METHODID_" << (*f_iter)->get_name() << ":" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "serviceImpl." << (*f_iter)->get_name() << "((" << (*f_iter)->get_name() << ++ "_args) request," << endl << ++ indent() << " (io.grpc.stub.StreamObserver<" << (*f_iter)->get_name() << "_result>)" << ++ " responseObserver);" << endl << ++ indent() << "break;" << endl << endl; ++ indent_down(); ++ } ++ if (tservice->get_extends() != nullptr) { ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ string extend_service_name = extend_service->get_name() + "Grpc"; ++ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "case METHODID_" << (*f_iter)->get_name() << ":" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "serviceImpl." << (*f_iter)->get_name() << "((" << extend_service_name << ++ "." << (*f_iter)->get_name() << "_args) request," << endl << ++ indent() << " (io.grpc.stub.StreamObserver<" << extend_service_name << "." << ++ (*f_iter)->get_name() << "_result>)" << " responseObserver);" << endl << ++ indent() << "break;" << endl << endl; ++ indent_down(); ++ } + } ++ f_service_ << ++ indent() << "default:" << endl << ++ indent() << " throw new AssertionError();" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl; ++ indent_down(); ++ f_service_ << ++ indent() << "}" << endl << endl; ++ ++ // invoke ++ f_service_ << ++ indent() << "@java.lang.Override" << endl << ++ indent() << "@java.lang.SuppressWarnings(\"unchecked\")" << endl << ++ indent() << "public io.grpc.stub.StreamObserver invoke(" << endl << ++ indent() << " io.grpc.stub.StreamObserver responseObserver) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "switch (methodId) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "default:" << endl; ++ f_service_ << ++ indent() << " throw new AssertionError();" << endl; ++ indent_down(); ++ f_service_ << indent() << "}" << endl; + indent_down(); + f_service_ << indent() << "}" << endl << endl; ++ indent_down(); ++ f_service_ << indent() << "}" << endl << endl; ++ + } + ++void t_java_generator::generate_service_descriptors(t_service* tservice) { ++ // generate service descriptor ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ f_service_ << ++ indent() << "public static io.grpc.ServiceDescriptor getServiceDescriptor() {" << ++ endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return new io.grpc.ServiceDescriptor(SERVICE_NAME"; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "," << endl << ++ indent() << " METHOD_" << (*f_iter)->get_name(); ++ } ++ if (tservice->get_extends() != nullptr) { ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << "," << endl << ++ indent() << " METHOD_" << (*f_iter)->get_name(); ++ } ++ } ++ f_service_ << ");" << endl; ++ indent_down(); ++ f_service_ << indent() << "}" << endl << endl; ++} ++ ++void t_java_generator::generate_service_builder(t_service* tservice) { ++ // bind Service ++ vector functions = tservice->get_functions(); ++ vector::iterator f_iter; ++ f_service_ << ++ indent() << "@java.lang.Deprecated public static io.grpc.ServerServiceDefinition" << ++ " bindService(" << endl << ++ indent() << " final " << service_name_ << " serviceImpl) {" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << "return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())" << ++ endl; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << " .addMethod(" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << " METHOD_" << (*f_iter)->get_name() << "," << endl << ++ indent() << " asyncUnaryCall(" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << " new MethodHandlers<" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << " " << (*f_iter)->get_name() << "_args," << endl << ++ indent() << " " << (*f_iter)->get_name() << "_result>(" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << " serviceImpl, METHODID_" << (*f_iter)->get_name() << ")))" << endl; ++ indent_down(); ++ indent_down(); ++ indent_down(); ++ indent_down(); ++ } ++ ++ if (tservice->get_extends() != nullptr) { ++ t_service* extend_service = tservice->get_extends(); ++ functions = extend_service->get_functions(); ++ string extend_service_name = extend_service->get_name() + "Grpc"; ++ for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { ++ f_service_ << ++ indent() << " .addMethod(" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << " METHOD_" << (*f_iter)->get_name() << "," << endl << ++ indent() << " asyncUnaryCall(" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << " new MethodHandlers<" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << " " << extend_service_name << "." << (*f_iter)->get_name() << "_args," << endl << ++ indent() << " " << extend_service_name << "." << (*f_iter)->get_name() << "_result>(" << endl; ++ indent_up(); ++ f_service_ << ++ indent() << " serviceImpl, METHODID_" << (*f_iter)->get_name() << ")))" << endl; ++ indent_down(); ++ indent_down(); ++ indent_down(); ++ indent_down(); ++ } ++ } ++ f_service_ << ++ indent() << " .build();" << endl; ++ indent_down(); ++ f_service_ << indent() << "}" << endl << endl; ++} ++ ++ + void t_java_generator::generate_service_async_interface(t_service* tservice) { + string extends = ""; + string extends_iface = ""; +diff --git a/tutorial/Makefile.am b/tutorial/Makefile.am +index 5865c54..1cffbe6 100755 +--- a/tutorial/Makefile.am ++++ b/tutorial/Makefile.am +@@ -35,11 +35,6 @@ if WITH_D + SUBDIRS += d + endif + +-if WITH_JAVA +-SUBDIRS += java +-SUBDIRS += js +-endif +- + if WITH_PYTHON + SUBDIRS += py + SUBDIRS += py.twisted +@@ -95,4 +90,5 @@ EXTRA_DIST = \ + php \ + shared.thrift \ + tutorial.thrift \ +- README.md ++ README.md \ ++ java +-- +2.8.0.rc3.226.g39d4020 + From 96b7b521902a7e1c8b50abdb04752a84451f9a1c Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 1 Aug 2016 09:33:38 -0700 Subject: [PATCH 105/279] Fix exit condition --- test/cpp/interop/interop_server.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc index 384d8da720e..e5878bb248c 100644 --- a/test/cpp/interop/interop_server.cc +++ b/test/cpp/interop/interop_server.cc @@ -77,8 +77,6 @@ using grpc::testing::StreamingOutputCallResponse; using grpc::testing::TestService; using grpc::Status; -static bool got_sigint = false; - const char kEchoInitialMetadataKey[] = "x-grpc-test-echo-initial"; const char kEchoTrailingBinMetadataKey[] = "x-grpc-test-echo-trailing-bin"; const char kEchoUserAgentKey[] = "x-grpc-test-echo-useragent"; @@ -325,7 +323,7 @@ void grpc::testing::interop::RunServer( builder.AddListeningPort(server_address.str(), creds); std::unique_ptr server(builder.BuildAndStart()); gpr_log(GPR_INFO, "Server listening on %s", server_address.str().c_str()); - while (!got_sigint) { + while (!g_got_sigint) { sleep(5); } } From b9be58ee5ac301788a35c26c37fea6f69a0e61fc Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 1 Aug 2016 11:25:59 -0700 Subject: [PATCH 106/279] Use dedicated build configuration 'Cronet' for the new target --- src/objective-c/tests/Podfile | 9 +- .../tests/Tests.xcodeproj/project.pbxproj | 193 +++++++++++++++++- .../InteropTestsRemoteWithCronet.xcscheme | 10 +- 3 files changed, 204 insertions(+), 8 deletions(-) diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 067d37eccc1..51dd1b8358f 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -31,8 +31,8 @@ GRPC_LOCAL_SRC = '../../..' pod 'RemoteTest', :path => "RemoteTestClient" if target_name == 'InteropTestsRemoteWithCronet' - pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" pod 'gRPC-Core/Cronet-Implementation', :path => GRPC_LOCAL_SRC + pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" end end end @@ -90,9 +90,14 @@ post_install do |installer| config.build_settings['GCC_WARN_ABOUT_RETURN_TYPE'] = 'NO' end end + + # Activate Cronet for the dedicated build configuration 'Cronet', which will be used solely by + # the test target 'InteropTestsRemoteWithCronet' if target.name == 'gRPC' target.build_configurations.each do |config| - config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_COMPILE_WITH_CRONET=1' + if config.name == 'Cronet' + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_COMPILE_WITH_CRONET=1' + end end end end diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 1d903478fdb..c4a6567ae0e 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -113,13 +113,17 @@ 07D10A965323BEA7FE59A74B /* Pods-RxLibraryUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.debug.xcconfig"; sourceTree = ""; }; 0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; 0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.debug.xcconfig"; sourceTree = ""; }; + 14B09A58FEE53A7A6B838920 /* Pods-InteropTestsLocalSSL.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.cronet.xcconfig"; sourceTree = ""; }; 17F60BF2871F6AF85FB3FA12 /* Pods-InteropTestsRemoteWithCronet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; sourceTree = ""; }; 20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 3B0861FC805389C52DB260D4 /* Pods-RxLibraryUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.release.xcconfig"; sourceTree = ""; }; + 3F27B2E744482771EB93C394 /* Pods-InteropTestsRemoteWithCronet.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.cronet.xcconfig"; sourceTree = ""; }; 4AD97096D13D7416DC91A72A /* Pods-CoreCronetEnd2EndTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.release.xcconfig"; sourceTree = ""; }; + 4ADEA1C8BBE10D90940AC68E /* Pods-InteropTestsRemote.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.cronet.xcconfig"; sourceTree = ""; }; 51A275E86C141416ED63FF76 /* Pods-InteropTestsLocalCleartext.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.release.xcconfig"; sourceTree = ""; }; 553BBBED24E4162D1F769D65 /* Pods-InteropTestsLocalSSL.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.debug.xcconfig"; sourceTree = ""; }; + 573450F334B331D0BED8B961 /* Pods-CoreCronetEnd2EndTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.cronet.xcconfig"; sourceTree = ""; }; 5761E98978DDDF136A58CB7E /* Pods-AllTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.release.xcconfig"; sourceTree = ""; }; 5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreCronetEnd2EndTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CoreCronetEnd2EndTests.m; sourceTree = ""; }; @@ -142,9 +146,11 @@ 63E240CC1B6C4D3A005F3B0E /* InteropTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InteropTests.h; sourceTree = ""; }; 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InteropTestsLocalSSL.m; sourceTree = ""; }; 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = TestCertificates.bundle; sourceTree = ""; }; + 79C68EFFCB5533475D810B79 /* Pods-RxLibraryUnitTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.cronet.xcconfig"; sourceTree = ""; }; 7A2E97E3F469CC2A758D77DE /* Pods-InteropTestsLocalSSL.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.release.xcconfig"; sourceTree = ""; }; 9E9444C764F0FFF64A7EB58E /* libPods-InteropTestsRemoteWithCronet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemoteWithCronet.a"; sourceTree = BUILT_PRODUCTS_DIR; }; A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RxLibraryUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + AA7CB64B4DD9915AE7C03163 /* Pods-InteropTestsLocalCleartext.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.cronet.xcconfig"; sourceTree = ""; }; AC414EF7A6BF76ED02B6E480 /* Pods-InteropTestsRemoteWithCronet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.release.xcconfig"; sourceTree = ""; }; B94C27C06733CF98CE1B2757 /* Pods-AllTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.debug.xcconfig"; sourceTree = ""; }; CAE086D5B470DA367D415AB0 /* libPods-AllTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AllTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -154,6 +160,8 @@ E1486220285AF123EB124008 /* Pods-InteropTestsLocalCleartext.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.debug.xcconfig"; sourceTree = ""; }; E4275A759BDBDF143B9B438F /* Pods-InteropTestsRemote.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.release.xcconfig"; sourceTree = ""; }; E6733B838B28453434B556E2 /* Pods-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.release.xcconfig"; sourceTree = ""; }; + E7E4D3FD76E3B745D992AF5F /* Pods-AllTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.cronet.xcconfig"; sourceTree = ""; }; + F671D4CAD2864FB203B920B4 /* Pods-Tests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.cronet.xcconfig"; sourceTree = ""; }; FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CoreCronetEnd2EndTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalCleartext.a"; sourceTree = BUILT_PRODUCTS_DIR; }; FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; @@ -271,6 +279,14 @@ 4AD97096D13D7416DC91A72A /* Pods-CoreCronetEnd2EndTests.release.xcconfig */, 17F60BF2871F6AF85FB3FA12 /* Pods-InteropTestsRemoteWithCronet.debug.xcconfig */, AC414EF7A6BF76ED02B6E480 /* Pods-InteropTestsRemoteWithCronet.release.xcconfig */, + E7E4D3FD76E3B745D992AF5F /* Pods-AllTests.cronet.xcconfig */, + 573450F334B331D0BED8B961 /* Pods-CoreCronetEnd2EndTests.cronet.xcconfig */, + AA7CB64B4DD9915AE7C03163 /* Pods-InteropTestsLocalCleartext.cronet.xcconfig */, + 14B09A58FEE53A7A6B838920 /* Pods-InteropTestsLocalSSL.cronet.xcconfig */, + 4ADEA1C8BBE10D90940AC68E /* Pods-InteropTestsRemote.cronet.xcconfig */, + 3F27B2E744482771EB93C394 /* Pods-InteropTestsRemoteWithCronet.cronet.xcconfig */, + 79C68EFFCB5533475D810B79 /* Pods-RxLibraryUnitTests.cronet.xcconfig */, + F671D4CAD2864FB203B920B4 /* Pods-Tests.cronet.xcconfig */, ); name = Pods; sourceTree = ""; @@ -1122,6 +1138,173 @@ }; name = Release; }; + 5EC3C7A01D4FC18C000330E2 /* Cronet */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Cronet; + }; + 5EC3C7A11D4FC18C000330E2 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F671D4CAD2864FB203B920B4 /* Pods-Tests.cronet.xcconfig */; + buildSettings = { + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Cronet; + }; + 5EC3C7A21D4FC18C000330E2 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E7E4D3FD76E3B745D992AF5F /* Pods-AllTests.cronet.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Cronet; + }; + 5EC3C7A31D4FC18C000330E2 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 79C68EFFCB5533475D810B79 /* Pods-RxLibraryUnitTests.cronet.xcconfig */; + buildSettings = { + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.RxLibraryUnitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Cronet; + }; + 5EC3C7A41D4FC18C000330E2 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4ADEA1C8BBE10D90940AC68E /* Pods-InteropTestsRemote.cronet.xcconfig */; + buildSettings = { + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Cronet; + }; + 5EC3C7A51D4FC18C000330E2 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 14B09A58FEE53A7A6B838920 /* Pods-InteropTestsLocalSSL.cronet.xcconfig */; + buildSettings = { + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalSSL; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Cronet; + }; + 5EC3C7A61D4FC18C000330E2 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AA7CB64B4DD9915AE7C03163 /* Pods-InteropTestsLocalCleartext.cronet.xcconfig */; + buildSettings = { + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalCleartext; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Cronet; + }; + 5EC3C7A71D4FC18C000330E2 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 573450F334B331D0BED8B961 /* Pods-CoreCronetEnd2EndTests.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + INFOPLIST_FILE = CoreCronetEnd2EndTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CoreCronetEnd2EndTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = "$(inherited) \"${PODS_ROOT}/../../../..\""; + }; + name = Cronet; + }; + 5EC3C7A81D4FC18C000330E2 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3F27B2E744482771EB93C394 /* Pods-InteropTestsRemoteWithCronet.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "COCOAPODS=1", + "$(inherited)", + "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1", + "GRPC_COMPILE_WITH_CRONET=1", + ); + INFOPLIST_FILE = InteropTestsRemoteWithCronet/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsRemoteWithCronet; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Cronet; + }; 5EE84BF91D4717E40050C6CC /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 17F60BF2871F6AF85FB3FA12 /* Pods-InteropTestsRemoteWithCronet.debug.xcconfig */; @@ -1135,7 +1318,6 @@ "COCOAPODS=1", "$(inherited)", "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1", - "GRPC_COMPILE_WITH_CRONET=1", ); INFOPLIST_FILE = InteropTestsRemoteWithCronet/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.3; @@ -1409,6 +1591,7 @@ isa = XCConfigurationList; buildConfigurations = ( 5E8A5DAC1D3840B4000F8BC4 /* Debug */, + 5EC3C7A71D4FC18C000330E2 /* Cronet */, 5E8A5DAD1D3840B4000F8BC4 /* Release */, ); defaultConfigurationIsVisible = 0; @@ -1418,6 +1601,7 @@ isa = XCConfigurationList; buildConfigurations = ( 5EE84BF91D4717E40050C6CC /* Debug */, + 5EC3C7A81D4FC18C000330E2 /* Cronet */, 5EE84BFA1D4717E40050C6CC /* Release */, ); defaultConfigurationIsVisible = 0; @@ -1427,6 +1611,7 @@ isa = XCConfigurationList; buildConfigurations = ( 63423F4E1B150A5F006CF63C /* Debug */, + 5EC3C7A21D4FC18C000330E2 /* Cronet */, 63423F4F1B150A5F006CF63C /* Release */, ); defaultConfigurationIsVisible = 0; @@ -1436,6 +1621,7 @@ isa = XCConfigurationList; buildConfigurations = ( 635697D91B14FC11007A7283 /* Debug */, + 5EC3C7A01D4FC18C000330E2 /* Cronet */, 635697DA1B14FC11007A7283 /* Release */, ); defaultConfigurationIsVisible = 0; @@ -1445,6 +1631,7 @@ isa = XCConfigurationList; buildConfigurations = ( 635697DC1B14FC11007A7283 /* Debug */, + 5EC3C7A11D4FC18C000330E2 /* Cronet */, 635697DD1B14FC11007A7283 /* Release */, ); defaultConfigurationIsVisible = 0; @@ -1454,6 +1641,7 @@ isa = XCConfigurationList; buildConfigurations = ( 63DC841C1BE15179000708E8 /* Debug */, + 5EC3C7A31D4FC18C000330E2 /* Cronet */, 63DC841D1BE15179000708E8 /* Release */, ); defaultConfigurationIsVisible = 0; @@ -1463,6 +1651,7 @@ isa = XCConfigurationList; buildConfigurations = ( 63DC842C1BE15267000708E8 /* Debug */, + 5EC3C7A41D4FC18C000330E2 /* Cronet */, 63DC842D1BE15267000708E8 /* Release */, ); defaultConfigurationIsVisible = 0; @@ -1472,6 +1661,7 @@ isa = XCConfigurationList; buildConfigurations = ( 63DC843D1BE15294000708E8 /* Debug */, + 5EC3C7A51D4FC18C000330E2 /* Cronet */, 63DC843E1BE15294000708E8 /* Release */, ); defaultConfigurationIsVisible = 0; @@ -1481,6 +1671,7 @@ isa = XCConfigurationList; buildConfigurations = ( 63DC844C1BE152B5000708E8 /* Debug */, + 5EC3C7A61D4FC18C000330E2 /* Cronet */, 63DC844D1BE152B5000708E8 /* Release */, ); defaultConfigurationIsVisible = 0; diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemoteWithCronet.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemoteWithCronet.xcscheme index 6d92be8b3de..1d211115f75 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemoteWithCronet.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemoteWithCronet.xcscheme @@ -23,7 +23,7 @@ @@ -57,7 +57,7 @@ + buildConfiguration = "Cronet"> From 9e83d7ef0f6bfb392d7b564e7edac8931cb3ad12 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Mon, 1 Aug 2016 12:51:31 -0700 Subject: [PATCH 107/279] Fix local server tests & exceptions tests --- src/objective-c/tests/GRPCClientTests.m | 9 --------- src/objective-c/tests/InteropTests.h | 7 +++++++ src/objective-c/tests/InteropTests.m | 8 ++++++-- src/objective-c/tests/InteropTestsLocalCleartext.m | 4 ++++ src/objective-c/tests/InteropTestsLocalSSL.m | 4 ++++ src/objective-c/tests/InteropTestsRemote.m | 4 ++++ .../xcshareddata/xcschemes/AllTests.xcscheme | 6 ------ 7 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 1167a715bb9..916a335802a 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -292,15 +292,6 @@ static GRPCProtoMethod *kUnaryCallMethod; // TODO(makarandd): Move to a different file that contains only unit tests - (void)testExceptions { - // Try to set userAgentPrefix for host that is nil. This should cause - // an exception. - @try { - [GRPCCall setUserAgentPrefix:@"Foo" forHost:nil]; - XCTFail(@"Did not receive an exception when host is nil"); - } @catch(NSException *theException) { - NSLog(@"Received exception as expected: %@", theException.name); - } - // Try to set parameters to nil for GRPCCall. This should cause an exception @try { (void)[[GRPCCall alloc] initWithHost:nil diff --git a/src/objective-c/tests/InteropTests.h b/src/objective-c/tests/InteropTests.h index 6d54343b135..ecab606a78b 100644 --- a/src/objective-c/tests/InteropTests.h +++ b/src/objective-c/tests/InteropTests.h @@ -46,4 +46,11 @@ * Override in a subclass to perform these tests against a specific address. */ + (NSString *)host; + +/** + * Bytes of overhead of test proto responses due to encoding. This is used to excercise the behavior + * when responses are just above or below the max response size. For some reason, the local and + * remote servers enconde responses with different overhead (?), so this is defined per-subclass. + */ +- (int32_t)encodingOverhead; @end diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 1ae0d7a848a..f04a7e6441f 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -88,6 +88,10 @@ return nil; } +- (int32_t)encodingOverhead { + return 0; +} + - (void)setUp { self.continueAfterFailure = NO; @@ -150,7 +154,7 @@ __weak XCTestExpectation *expectation = [self expectationWithDescription:@"MaxResponseSize"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; - const size_t kPayloadSize = 4 * 1024 * 1024 - 12; // 4MB - 12B of protobuf encoding overhead + const int32_t kPayloadSize = 4 * 1024 * 1024 - self.encodingOverhead; // 4MB - encoding overhead request.responseSize = kPayloadSize; [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) { @@ -167,7 +171,7 @@ __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ResponseOverMaxSize"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; - const size_t kPayloadSize = 4 * 1024 * 1024 - 11; // 1B over max size (see above test) + const int32_t kPayloadSize = 4 * 1024 * 1024 - self.encodingOverhead + 1; // 1B over max size request.responseSize = kPayloadSize; [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) { diff --git a/src/objective-c/tests/InteropTestsLocalCleartext.m b/src/objective-c/tests/InteropTestsLocalCleartext.m index c4ee0de7054..b41210f50f8 100644 --- a/src/objective-c/tests/InteropTestsLocalCleartext.m +++ b/src/objective-c/tests/InteropTestsLocalCleartext.m @@ -47,6 +47,10 @@ static NSString * const kLocalCleartextHost = @"localhost:5050"; return kLocalCleartextHost; } +- (int32_t)encodingOverhead { + return 10; // bytes +} + - (void)setUp { [super setUp]; diff --git a/src/objective-c/tests/InteropTestsLocalSSL.m b/src/objective-c/tests/InteropTestsLocalSSL.m index 27f025e6143..1479c5896c3 100644 --- a/src/objective-c/tests/InteropTestsLocalSSL.m +++ b/src/objective-c/tests/InteropTestsLocalSSL.m @@ -47,6 +47,10 @@ static NSString * const kLocalSSLHost = @"localhost:5051"; return kLocalSSLHost; } +- (int32_t)encodingOverhead { + return 10; // bytes +} + - (void)setUp { [super setUp]; diff --git a/src/objective-c/tests/InteropTestsRemote.m b/src/objective-c/tests/InteropTestsRemote.m index 758cc9346ad..70f84753bb6 100644 --- a/src/objective-c/tests/InteropTestsRemote.m +++ b/src/objective-c/tests/InteropTestsRemote.m @@ -47,4 +47,8 @@ static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.googleapis.com"; return kRemoteSSLHost; } +- (int32_t)encodingOverhead { + return 12; // bytes +} + @end diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme index e6a052a8ce1..d1d616c4cf2 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme @@ -38,12 +38,6 @@ ReferencedContainer = "container:Tests.xcodeproj"> - - - - From d915c6e28ae102739ba7c7f4032ff1a6a434ae0e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 1 Aug 2016 13:46:27 -0700 Subject: [PATCH 108/279] Suppress warning in all libraries whose names starting with gRPC-Core --- src/objective-c/tests/Podfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 51dd1b8358f..36f25e1bf55 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -82,7 +82,7 @@ post_install do |installer| target.build_configurations.each do |config| config.build_settings['GCC_TREAT_WARNINGS_AS_ERRORS'] = 'YES' end - if target.name == 'gRPC-Core' or target.name == 'gRPC-Core.default-Cronet-Implementation-Cronet-Interface-Tests' or target.name == 'gRPC-Core.default-Cronet-Implementation' + if target.name.start_with?('gRPC-Core') target.build_configurations.each do |config| # TODO(zyc): Remove this setting after the issue is resolved # GPR_UNREACHABLE_CODE causes "Control may reach end of non-void From b4280fa084ab57878fae069f59f1d834cceb1546 Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Thu, 28 Jul 2016 23:48:50 -0700 Subject: [PATCH 109/279] compare test config as objects instead of strings --- src/csharp/Grpc.Core.Tests/SanityTest.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/SanityTest.cs b/src/csharp/Grpc.Core.Tests/SanityTest.cs index 501992c5695..9d069fa432a 100644 --- a/src/csharp/Grpc.Core.Tests/SanityTest.cs +++ b/src/csharp/Grpc.Core.Tests/SanityTest.cs @@ -58,10 +58,11 @@ namespace Grpc.Core.Tests [Test] public void TestsJsonUpToDate() { - var discoveredTests = DiscoverAllTestClasses(); - string discoveredTestsJson = JsonConvert.SerializeObject(discoveredTests, Formatting.Indented); + Dictionary> discoveredTests = DiscoverAllTestClasses(); + Dictionary> testsFromFile + = JsonConvert.DeserializeObject>>(ReadTestsJson()); - Assert.AreEqual(discoveredTestsJson, ReadTestsJson()); + Assert.AreEqual(discoveredTests, testsFromFile); } /// From c44f6199841b1fd63d127dcd052312ee6c1899a0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 1 Aug 2016 14:57:20 -0700 Subject: [PATCH 110/279] Bug fix on error suppression and comment --- src/objective-c/tests/Podfile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 36f25e1bf55..17478fab12d 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -82,7 +82,11 @@ post_install do |installer| target.build_configurations.each do |config| config.build_settings['GCC_TREAT_WARNINGS_AS_ERRORS'] = 'YES' end - if target.name.start_with?('gRPC-Core') + + # CocoaPods creates duplicated library targets of gRPC-Core when the test targets include + # non-default subspecs of gRPC-Core. All of these library targets start with prefix 'gRPC-Core.' + # and require the same error suppresion. + if target.name == 'gRPC-Core' or target.name.start_with?('gRPC-Core.') target.build_configurations.each do |config| # TODO(zyc): Remove this setting after the issue is resolved # GPR_UNREACHABLE_CODE causes "Control may reach end of non-void From ffd207fe4c942e5de5e178d9b9eccb38fb787635 Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Mon, 1 Aug 2016 16:20:52 -0700 Subject: [PATCH 111/279] fixed include guard script and faulty .h --- include/grpc++/impl/codegen/core_codegen.h | 5 +++++ tools/distrib/check_include_guards.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/grpc++/impl/codegen/core_codegen.h b/include/grpc++/impl/codegen/core_codegen.h index 9699abfb438..2586b945048 100644 --- a/include/grpc++/impl/codegen/core_codegen.h +++ b/include/grpc++/impl/codegen/core_codegen.h @@ -31,6 +31,9 @@ * */ +#ifndef GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_H +#define GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_H + // This file should be compiled as part of grpc++. #include @@ -83,3 +86,5 @@ class CoreCodegen : public CoreCodegenInterface { }; } // namespace grpc + +#endif // GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_H diff --git a/tools/distrib/check_include_guards.py b/tools/distrib/check_include_guards.py index 56b2924a1ac..28312813f65 100755 --- a/tools/distrib/check_include_guards.py +++ b/tools/distrib/check_include_guards.py @@ -200,6 +200,6 @@ validator = GuardValidator() for filename in filename_list: if filename in KNOWN_BAD: continue - ok = validator.check(filename, args.fix) + ok = ok and validator.check(filename, args.fix) sys.exit(0 if ok else 1) From 8eec9ec6af48d739e5c9346da011e88ad947ab7e Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Mon, 1 Aug 2016 17:05:04 -0700 Subject: [PATCH 112/279] Changed census static metadata keys for tracing and tag propagation --- src/core/lib/transport/static_metadata.c | 22 ++++----- src/core/lib/transport/static_metadata.h | 56 +++++++++++----------- test/core/end2end/fuzzers/hpack.dictionary | 4 +- tools/codegen/core/gen_static_metadata.py | 4 +- 4 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/core/lib/transport/static_metadata.c b/src/core/lib/transport/static_metadata.c index c396c1e0b5a..8f3e5b5b401 100644 --- a/src/core/lib/transport/static_metadata.c +++ b/src/core/lib/transport/static_metadata.c @@ -51,15 +51,15 @@ uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; const uint8_t grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2] = - {11, 35, 10, 35, 12, 35, 12, 49, 13, 35, 14, 35, 15, 35, 16, 35, 17, 35, - 19, 35, 20, 35, 21, 35, 24, 35, 25, 35, 26, 35, 27, 35, 28, 35, 29, 35, - 30, 18, 30, 35, 31, 35, 32, 35, 36, 35, 37, 35, 38, 35, 39, 35, 42, 33, - 42, 34, 42, 48, 42, 53, 42, 54, 42, 55, 42, 56, 43, 33, 43, 48, 43, 53, - 46, 0, 46, 1, 46, 2, 50, 35, 57, 35, 58, 35, 59, 35, 60, 35, 61, 35, - 62, 35, 63, 35, 64, 35, 65, 35, 66, 35, 67, 35, 68, 40, 68, 70, 68, 73, - 69, 81, 69, 82, 71, 35, 72, 35, 74, 35, 75, 35, 76, 35, 77, 35, 78, 41, - 78, 51, 78, 52, 79, 35, 80, 35, 83, 3, 83, 4, 83, 5, 83, 6, 83, 7, - 83, 8, 83, 9, 84, 35, 85, 86, 87, 35, 88, 35, 89, 35, 90, 35, 91, 35}; + {11, 33, 10, 33, 12, 33, 12, 49, 13, 33, 14, 33, 15, 33, 16, 33, 17, 33, + 19, 33, 20, 33, 21, 33, 22, 33, 23, 33, 24, 33, 25, 33, 26, 33, 27, 33, + 28, 18, 28, 33, 29, 33, 30, 33, 34, 33, 35, 33, 36, 33, 37, 33, 40, 31, + 40, 32, 40, 48, 40, 53, 40, 54, 40, 55, 40, 56, 42, 31, 42, 48, 42, 53, + 45, 0, 45, 1, 45, 2, 50, 33, 57, 33, 58, 33, 59, 33, 60, 33, 61, 33, + 62, 33, 63, 33, 64, 33, 65, 33, 66, 33, 67, 33, 68, 38, 68, 70, 68, 73, + 69, 81, 69, 82, 71, 33, 72, 33, 74, 33, 75, 33, 76, 33, 77, 33, 78, 39, + 78, 51, 78, 52, 79, 33, 80, 33, 83, 3, 83, 4, 83, 5, 83, 6, 83, 7, + 83, 8, 83, 9, 84, 33, 85, 86, 87, 33, 88, 33, 89, 33, 90, 33, 91, 33}; const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = { "0", @@ -84,8 +84,6 @@ const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = { ":authority", "authorization", "cache-control", - "census-bin", - "census-binary-bin", "content-disposition", "content-encoding", "content-language", @@ -105,11 +103,13 @@ const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = { "GET", "grpc", "grpc-accept-encoding", + "grpc-census-bin", "grpc-encoding", "grpc-internal-encoding-request", "grpc-message", "grpc-status", "grpc-timeout", + "grpc-tracing-bin", "gzip", "gzip, deflate", "host", diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index 491c8cf125a..b51bacac50b 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -90,58 +90,58 @@ extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT]; #define GRPC_MDSTR_AUTHORIZATION (&grpc_static_mdstr_table[20]) /* "cache-control" */ #define GRPC_MDSTR_CACHE_CONTROL (&grpc_static_mdstr_table[21]) -/* "census-bin" */ -#define GRPC_MDSTR_CENSUS_BIN (&grpc_static_mdstr_table[22]) -/* "census-binary-bin" */ -#define GRPC_MDSTR_CENSUS_BINARY_BIN (&grpc_static_mdstr_table[23]) /* "content-disposition" */ -#define GRPC_MDSTR_CONTENT_DISPOSITION (&grpc_static_mdstr_table[24]) +#define GRPC_MDSTR_CONTENT_DISPOSITION (&grpc_static_mdstr_table[22]) /* "content-encoding" */ -#define GRPC_MDSTR_CONTENT_ENCODING (&grpc_static_mdstr_table[25]) +#define GRPC_MDSTR_CONTENT_ENCODING (&grpc_static_mdstr_table[23]) /* "content-language" */ -#define GRPC_MDSTR_CONTENT_LANGUAGE (&grpc_static_mdstr_table[26]) +#define GRPC_MDSTR_CONTENT_LANGUAGE (&grpc_static_mdstr_table[24]) /* "content-length" */ -#define GRPC_MDSTR_CONTENT_LENGTH (&grpc_static_mdstr_table[27]) +#define GRPC_MDSTR_CONTENT_LENGTH (&grpc_static_mdstr_table[25]) /* "content-location" */ -#define GRPC_MDSTR_CONTENT_LOCATION (&grpc_static_mdstr_table[28]) +#define GRPC_MDSTR_CONTENT_LOCATION (&grpc_static_mdstr_table[26]) /* "content-range" */ -#define GRPC_MDSTR_CONTENT_RANGE (&grpc_static_mdstr_table[29]) +#define GRPC_MDSTR_CONTENT_RANGE (&grpc_static_mdstr_table[27]) /* "content-type" */ -#define GRPC_MDSTR_CONTENT_TYPE (&grpc_static_mdstr_table[30]) +#define GRPC_MDSTR_CONTENT_TYPE (&grpc_static_mdstr_table[28]) /* "cookie" */ -#define GRPC_MDSTR_COOKIE (&grpc_static_mdstr_table[31]) +#define GRPC_MDSTR_COOKIE (&grpc_static_mdstr_table[29]) /* "date" */ -#define GRPC_MDSTR_DATE (&grpc_static_mdstr_table[32]) +#define GRPC_MDSTR_DATE (&grpc_static_mdstr_table[30]) /* "deflate" */ -#define GRPC_MDSTR_DEFLATE (&grpc_static_mdstr_table[33]) +#define GRPC_MDSTR_DEFLATE (&grpc_static_mdstr_table[31]) /* "deflate,gzip" */ -#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (&grpc_static_mdstr_table[34]) +#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (&grpc_static_mdstr_table[32]) /* "" */ -#define GRPC_MDSTR_EMPTY (&grpc_static_mdstr_table[35]) +#define GRPC_MDSTR_EMPTY (&grpc_static_mdstr_table[33]) /* "etag" */ -#define GRPC_MDSTR_ETAG (&grpc_static_mdstr_table[36]) +#define GRPC_MDSTR_ETAG (&grpc_static_mdstr_table[34]) /* "expect" */ -#define GRPC_MDSTR_EXPECT (&grpc_static_mdstr_table[37]) +#define GRPC_MDSTR_EXPECT (&grpc_static_mdstr_table[35]) /* "expires" */ -#define GRPC_MDSTR_EXPIRES (&grpc_static_mdstr_table[38]) +#define GRPC_MDSTR_EXPIRES (&grpc_static_mdstr_table[36]) /* "from" */ -#define GRPC_MDSTR_FROM (&grpc_static_mdstr_table[39]) +#define GRPC_MDSTR_FROM (&grpc_static_mdstr_table[37]) /* "GET" */ -#define GRPC_MDSTR_GET (&grpc_static_mdstr_table[40]) +#define GRPC_MDSTR_GET (&grpc_static_mdstr_table[38]) /* "grpc" */ -#define GRPC_MDSTR_GRPC (&grpc_static_mdstr_table[41]) +#define GRPC_MDSTR_GRPC (&grpc_static_mdstr_table[39]) /* "grpc-accept-encoding" */ -#define GRPC_MDSTR_GRPC_ACCEPT_ENCODING (&grpc_static_mdstr_table[42]) +#define GRPC_MDSTR_GRPC_ACCEPT_ENCODING (&grpc_static_mdstr_table[40]) +/* "grpc-census-bin" */ +#define GRPC_MDSTR_GRPC_CENSUS_BIN (&grpc_static_mdstr_table[41]) /* "grpc-encoding" */ -#define GRPC_MDSTR_GRPC_ENCODING (&grpc_static_mdstr_table[43]) +#define GRPC_MDSTR_GRPC_ENCODING (&grpc_static_mdstr_table[42]) /* "grpc-internal-encoding-request" */ -#define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (&grpc_static_mdstr_table[44]) +#define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (&grpc_static_mdstr_table[43]) /* "grpc-message" */ -#define GRPC_MDSTR_GRPC_MESSAGE (&grpc_static_mdstr_table[45]) +#define GRPC_MDSTR_GRPC_MESSAGE (&grpc_static_mdstr_table[44]) /* "grpc-status" */ -#define GRPC_MDSTR_GRPC_STATUS (&grpc_static_mdstr_table[46]) +#define GRPC_MDSTR_GRPC_STATUS (&grpc_static_mdstr_table[45]) /* "grpc-timeout" */ -#define GRPC_MDSTR_GRPC_TIMEOUT (&grpc_static_mdstr_table[47]) +#define GRPC_MDSTR_GRPC_TIMEOUT (&grpc_static_mdstr_table[46]) +/* "grpc-tracing-bin" */ +#define GRPC_MDSTR_GRPC_TRACING_BIN (&grpc_static_mdstr_table[47]) /* "gzip" */ #define GRPC_MDSTR_GZIP (&grpc_static_mdstr_table[48]) /* "gzip, deflate" */ diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary index af075c09ef1..3157dfca3fe 100644 --- a/test/core/end2end/fuzzers/hpack.dictionary +++ b/test/core/end2end/fuzzers/hpack.dictionary @@ -21,8 +21,6 @@ "\x0A:authority" "\x0Dauthorization" "\x0Dcache-control" -"\x0Acensus-bin" -"\x11census-binary-bin" "\x13content-disposition" "\x10content-encoding" "\x10content-language" @@ -42,11 +40,13 @@ "\x03GET" "\x04grpc" "\x14grpc-accept-encoding" +"\x0Fgrpc-census-bin" "\x0Dgrpc-encoding" "\x1Egrpc-internal-encoding-request" "\x0Cgrpc-message" "\x0Bgrpc-status" "\x0Cgrpc-timeout" +"\x10grpc-tracing-bin" "\x04gzip" "\x0Dgzip, deflate" "\x04host" diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index c3c04966dfd..859adcbeb14 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -50,8 +50,8 @@ CONFIG = [ 'host', 'grpc-message', 'grpc-status', - 'census-bin', - 'census-binary-bin', + 'grpc-tracing-bin', + 'grpc-census-bin', '', ('grpc-status', '0'), ('grpc-status', '1'), From a17039aaa443ac8b4f8d5bad51fd6e8c2777071f Mon Sep 17 00:00:00 2001 From: chedeti Date: Mon, 1 Aug 2016 17:32:06 -0700 Subject: [PATCH 113/279] refine code and add README --- Makefile | 1 - build.yaml | 1 - .../grpc++/impl/codegen/thrift_serializer.h | 207 ++++++++++++------ .../impl/codegen/thrift_serializer_inl.h | 169 -------------- include/grpc++/impl/codegen/thrift_utils.h | 10 +- tools/grift/README.md | 15 ++ tools/grift/grpc_plugins_generator.patch | 187 +++++++++++++++- tools/run_tests/sources_and_headers.json | 2 - .../grpc++_test_util/grpc++_test_util.vcxproj | 1 - .../grpc++_test_util.vcxproj.filters | 3 - 10 files changed, 341 insertions(+), 255 deletions(-) delete mode 100644 include/grpc++/impl/codegen/thrift_serializer_inl.h create mode 100644 tools/grift/README.md diff --git a/Makefile b/Makefile index 986c25780f2..31a8448fff6 100644 --- a/Makefile +++ b/Makefile @@ -3924,7 +3924,6 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/impl/codegen/proto_utils.h \ include/grpc++/impl/codegen/config_protobuf.h \ include/grpc++/impl/codegen/thrift_serializer.h \ - include/grpc++/impl/codegen/thrift_serializer_inl.h \ include/grpc++/impl/codegen/thrift_utils.h \ LIBGRPC++_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_UTIL_SRC)))) diff --git a/build.yaml b/build.yaml index 35af7a6c7a5..02ad6a8842b 100644 --- a/build.yaml +++ b/build.yaml @@ -784,7 +784,6 @@ filegroups: language: c++ public_headers: - include/grpc++/impl/codegen/thrift_serializer.h - - include/grpc++/impl/codegen/thrift_serializer_inl.h - include/grpc++/impl/codegen/thrift_utils.h uses: - grpc++_codegen_base diff --git a/include/grpc++/impl/codegen/thrift_serializer.h b/include/grpc++/impl/codegen/thrift_serializer.h index 315d76cf2a5..46112ee5b23 100644 --- a/include/grpc++/impl/codegen/thrift_serializer.h +++ b/include/grpc++/impl/codegen/thrift_serializer.h @@ -36,12 +36,16 @@ #include #include - +#include +#include +#include +#include +#include #include #include +#include #include #include -#include namespace apache { namespace thrift { @@ -49,100 +53,165 @@ namespace util { using apache::thrift::protocol::TBinaryProtocolT; using apache::thrift::protocol::TCompactProtocolT; +using apache::thrift::protocol::TMessageType; using apache::thrift::protocol::TNetworkBigEndian; using apache::thrift::transport::TMemoryBuffer; using apache::thrift::transport::TBufferBase; using apache::thrift::transport::TTransport; -using std::shared_ptr; - -template -class ThriftSerializer { +template class ThriftSerializer { public: ThriftSerializer() - : prepared_ (false) - , lastDeserialized_ (false) - , serializeVersion_ (false) {} - - /** - * Serialize the passed type into the internal buffer - * and returns a pointer to internal buffer and its size - * - */ - template - void serialize(const T& fields, const uint8_t** serializedBuffer, - size_t* serializedLen); - - /** - * Serialize the passed type into the byte buffer - */ - template - void serialize(const T& fields, grpc_byte_buffer** bp); - - /** - * Deserialize the passed char array into the passed type, returns the number - * of bytes that have been consumed from the passed string. - */ - template - uint32_t deserialize(const uint8_t* serializedBuffer, size_t length, - T* fields); - - /** - * Deserialize the passed byte buffer to passed type, returns the number - * of bytes consumed from byte buffer - */ - template - uint32_t deserialize(grpc_byte_buffer* buffer, T* msg); - - void setSerializeVersion(bool value); + : prepared_ (false) + , last_deserialized_ (false) + , serialize_version_ (false) {} virtual ~ThriftSerializer() {} + // Serialize the passed type into the internal buffer + // and returns a pointer to internal buffer and its size + template void Serialize(const T& fields, const uint8_t** serializedBuffer, + size_t* serializedLen) { + // prepare or reset buffer + if (!prepared_ || last_deserialized_) { + prepare(); + } else { + buffer_->resetBuffer(); + } + last_deserialized_ = false; + + // if required serialize protocol version + if (serialize_version_) { + protocol_->writeMessageBegin("", TMessageType(0), 0); + } + + // serilaize fields into buffer + fields.write(protocol_.get()); + + // write the end of message + if (serialize_version_) { + protocol_->writeMessageEnd(); + } + + uint8_t* byteBuffer; + uint32_t byteBufferSize; + buffer_->getBuffer(&byteBuffer, &byteBufferSize); + *serializedBuffer = byteBuffer; + *serializedLen = byteBufferSize; + } + + // Serialize the passed type into the byte buffer + template void Serialize(const T& fields, grpc_byte_buffer** bp) { + + const uint8_t* byteBuffer; + size_t byteBufferSize; + + Serialize(fields, &byteBuffer, &byteBufferSize); + + gpr_slice slice = gpr_slice_from_copied_buffer((char*)byteBuffer,byteBufferSize); + + *bp = grpc_raw_byte_buffer_create(&slice, 1); - /** - * Set the container size limit to deserialize - * This function should be called after buffer_ is initialized - */ - void setContainerSizeLimit(int32_t container_limit) { + gpr_slice_unref(slice); + } + + // Deserialize the passed char array into the passed type, returns the number + // of bytes that have been consumed from the passed string. + template uint32_t Deserialize(const uint8_t* serializedBuffer, size_t length, + T* fields) { + // prepare buffer if necessary + if (!prepared_) { + prepare(); + } + last_deserialized_ = true; + + //reset buffer transport + buffer_->resetBuffer((uint8_t*)serializedBuffer, length); + + // read the protocol version if necessary + if (serialize_version_) { + std::string name = ""; + TMessageType mt = (TMessageType) 0; + int32_t seq_id = 0; + protocol_->readMessageBegin(name, mt, seq_id); + } + + // deserialize buffer into fields + uint32_t len = fields->read(protocol_.get()); + + // read the end of message + if (serialize_version_) { + protocol_->readMessageEnd(); + } + + return len; + } + + + // Deserialize the passed byte buffer to passed type, returns the number + // of bytes consumed from byte buffer + template uint32_t Deserialize(grpc_byte_buffer* buffer, T* msg) { + + grpc_byte_buffer_reader reader; + grpc_byte_buffer_reader_init(&reader, buffer); + + gpr_slice slice = grpc_byte_buffer_reader_readall(&reader); + + uint32_t len = Deserialize(GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice), msg); + + gpr_slice_unref(slice); + + grpc_byte_buffer_reader_destroy(&reader); + + return len; + } + + // set serialization version flag + void SetSerializeVersion(bool value) { + serialize_version_ = value; + } + + // Set the container size limit to deserialize + // This function should be called after buffer_ is initialized + void SetContainerSizeLimit(int32_t container_limit) { if (!prepared_) { prepare(); } protocol_->setContainerSizeLimit(container_limit); } - /** - * Set the string size limit to deserialize - * This function should be called after buffer_ is initialized - */ - void setStringSizeLimit(int32_t string_limit) { + // Set the string size limit to deserialize + // This function should be called after buffer_ is initialized + void SetStringSizeLimit(int32_t string_limit) { if (!prepared_) { prepare(); } protocol_->setStringSizeLimit(string_limit); } +private: + bool prepared_; + bool last_deserialized_; + boost::shared_ptr buffer_; + std::shared_ptr protocol_; + bool serialize_version_; - private: - void prepare(); - - private: - typedef P Protocol; - bool prepared_; - bool lastDeserialized_; - boost::shared_ptr buffer_; - shared_ptr protocol_; - bool serializeVersion_; -}; // ThriftSerializer + void prepare() { + buffer_.reset(new TMemoryBuffer()); -template -struct ThriftSerializerBinary : public ThriftSerializer > {}; + // create a protocol for the memory buffer transport + protocol_.reset(new Protocol(buffer_)); + prepared_ = true; + } -template -struct ThriftSerializerCompact : public ThriftSerializer >{ }; +}; // ThriftSerializer -}}} // namespace apache::thrift::util +typedef ThriftSerializer> ThriftSerializerBinary; +typedef ThriftSerializer> ThriftSerializerCompact; -#include +} // namespace util +} // namespace thrift +} // namespace apache -#endif +#endif \ No newline at end of file diff --git a/include/grpc++/impl/codegen/thrift_serializer_inl.h b/include/grpc++/impl/codegen/thrift_serializer_inl.h deleted file mode 100644 index 866ecf6312d..00000000000 --- a/include/grpc++/impl/codegen/thrift_serializer_inl.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * - * Copyright 2016, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - - #ifndef GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_INL_H - #define GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_INL_H - -#include -#include -#include -#include -#include -#include -#include - -namespace apache { -namespace thrift { -namespace util { - -using apache::thrift::protocol::TMessageType; - -template -template -void ThriftSerializer::serialize(const T& fields, - const uint8_t** serializedBuffer, size_t* serializedLen) { - - // prepare or reset buffer - if (!prepared_ || lastDeserialized_) { - prepare(); - } else { - buffer_->resetBuffer(); - } - lastDeserialized_ = false; - - // if required serialize protocol version - if (serializeVersion_) { - protocol_->writeMessageBegin("", TMessageType(0), 0); - } - - // serilaize fields into buffer - fields.write(protocol_.get()); - - // write the end of message - if (serializeVersion_) { - protocol_->writeMessageEnd(); - } - - // assign buffer to string - uint8_t* byteBuffer; - uint32_t byteBufferSize; - buffer_->getBuffer(&byteBuffer, &byteBufferSize); - *serializedBuffer = byteBuffer; - *serializedLen = byteBufferSize; -} - -template -template -void ThriftSerializer::serialize(const T& fields, grpc_byte_buffer** bp) { - - const uint8_t* byteBuffer; - size_t byteBufferSize; - serialize(fields, &byteBuffer, &byteBufferSize); - - gpr_slice slice = gpr_slice_from_copied_buffer((char*)byteBuffer,byteBufferSize); - - *bp = grpc_raw_byte_buffer_create(&slice, 1); - - gpr_slice_unref(slice); -} - -template -template -uint32_t ThriftSerializer::deserialize(const uint8_t* serializedBuffer, - size_t length, T* fields) { - // prepare buffer if necessary - if (!prepared_) { - prepare(); - } - lastDeserialized_ = true; - - //reset buffer transport - buffer_->resetBuffer((uint8_t*)serializedBuffer, length); - - // read the protocol version if necessary - if (serializeVersion_) { - std::string name = ""; - TMessageType mt = (TMessageType) 0; - int32_t seq_id = 0; - protocol_->readMessageBegin(name, mt, seq_id); - } - - // deserialize buffer into fields - uint32_t len = fields->read(protocol_.get()); - - // read the end of message - if (serializeVersion_) { - protocol_->readMessageEnd(); - } - - return len; -} - -template -template -uint32_t ThriftSerializer::deserialize(grpc_byte_buffer* bp, T* fields) { - grpc_byte_buffer_reader reader; - grpc_byte_buffer_reader_init(&reader, bp); - - gpr_slice slice = grpc_byte_buffer_reader_readall(&reader); - - uint32_t len = deserialize(GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice), fields); - - gpr_slice_unref(slice); - - grpc_byte_buffer_reader_destroy(&reader); - - return len; -} - -template -void ThriftSerializer::setSerializeVersion(bool value) { - serializeVersion_ = value; -} - -template -void -ThriftSerializer::prepare() -{ - - buffer_.reset(new TMemoryBuffer()); - - // create a protocol for the memory buffer transport - protocol_.reset(new Protocol(buffer_)); - - prepared_ = true; -} - -}}} // namespace apache::thrift::util - -#endif diff --git a/include/grpc++/impl/codegen/thrift_utils.h b/include/grpc++/impl/codegen/thrift_utils.h index 629441149fd..14332c05219 100644 --- a/include/grpc++/impl/codegen/thrift_utils.h +++ b/include/grpc++/impl/codegen/thrift_utils.h @@ -44,9 +44,7 @@ #include #include #include -#include #include -#include #include namespace grpc { @@ -62,9 +60,9 @@ class SerializationTraits serializer; + ThriftSerializerCompact serializer; - serializer.serialize(msg, bp); + serializer.Serialize(msg, bp); return Status(StatusCode::OK, "ok"); } @@ -76,8 +74,8 @@ class SerializationTraits deserializer; - deserializer.deserialize(buffer, msg); + ThriftSerializerCompact deserializer; + deserializer.Deserialize(buffer, msg); grpc_byte_buffer_destroy(buffer); diff --git a/tools/grift/README.md b/tools/grift/README.md new file mode 100644 index 00000000000..a4cb87bff1a --- /dev/null +++ b/tools/grift/README.md @@ -0,0 +1,15 @@ +Copyright 2016 Google Inc. + +#Documentation + +grift is integration of [Apache Thrift](https://github.com/apache/thrift.git) Serializer with GRPC. + +This integration allows you to use grpc to send thrift messages in C++ and java. + +By default grift uses Compact Protocol to serialize thrift messages. + +#Installation + +Before Installing thrift make sure to apply this [patch](grpc_plugins_generate.patch) to third_party/thrift. +Go to third_party/thrift and follow the [INSTALLATION](https://github.com/apache/thrift.git) instructions to +install thrift. \ No newline at end of file diff --git a/tools/grift/grpc_plugins_generator.patch b/tools/grift/grpc_plugins_generator.patch index 2779dfb59eb..9c18db35995 100644 --- a/tools/grift/grpc_plugins_generator.patch +++ b/tools/grift/grpc_plugins_generator.patch @@ -1,7 +1,7 @@ From 0894590b5020c38106d4ebb2291994668c64f9dd Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 15:47:47 -0700 -Subject: [PATCH 1/3] don't build tests +Subject: [PATCH 1/5] don't build tests --- Makefile.am | 7 ++----- @@ -62,7 +62,7 @@ index 6fd15d2..7de1fad 100755 From 04244fa7805740761db757e4c44251f723d85839 Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 16:16:40 -0700 -Subject: [PATCH 2/3] grpc cpp plugins generator with example +Subject: [PATCH 2/5] grpc cpp plugins generator with example --- compiler/cpp/src/generate/t_cpp_generator.cc | 476 +++++++++++++++++++++++---- @@ -1401,7 +1401,7 @@ index 0000000..de3c9a4 From 1d47ed062e62d136c3db9f6fc1dde9e2f794cf22 Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 16:23:53 -0700 -Subject: [PATCH 3/3] grpc java plugins generator +Subject: [PATCH 3/5] grpc java plugins generator for examples refer to https://github.com/grpc/grpc-java/tree/master/examples/thrift --- @@ -2415,3 +2415,184 @@ index 5865c54..1cffbe6 100755 -- 2.8.0.rc3.226.g39d4020 + +From a9769a0fa08f553da76215ca59a8fd797b92a853 Mon Sep 17 00:00:00 2001 +From: chedeti +Date: Mon, 1 Aug 2016 16:56:36 -0700 +Subject: [PATCH 4/5] maintain consistency with grpc + +--- + compiler/cpp/src/generate/t_cpp_generator.cc | 20 ++++++++++---------- + tutorial/cpp/{CppClient.cpp => GrpcClient.cpp} | 0 + tutorial/cpp/{CppServer.cpp => GrpcServer.cpp} | 0 + tutorial/cpp/Makefile.am | 8 ++++---- + 4 files changed, 14 insertions(+), 14 deletions(-) + rename tutorial/cpp/{CppClient.cpp => GrpcClient.cpp} (100%) + rename tutorial/cpp/{CppServer.cpp => GrpcServer.cpp} (100%) + +diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc +index 9c3399b..4e00129 100644 +--- a/compiler/cpp/src/generate/t_cpp_generator.cc ++++ b/compiler/cpp/src/generate/t_cpp_generator.cc +@@ -1641,7 +1641,7 @@ void t_cpp_generator::generate_service(t_service* tservice) { + << endl; + + t_service* extends_service = tservice->get_extends(); +- if (extends_service != nullptr) { ++ if (extends_service) { + f_header_ << "#include \"" << get_include_prefix(*(extends_service->get_program())) + << extends_service->get_name() << ".grpc.thrift.h\"" << endl; + } +@@ -1733,7 +1733,7 @@ void t_cpp_generator::generate_service(t_service* tservice) { + indent() << "\"/" << ns << "." << service_name_ << "/" << (*f_iter)->get_name() << "\"," << endl; + } + +- if (extends_service != nullptr) { ++ if (extends_service) { + vector functions = extends_service->get_functions(); + vector::iterator f_iter; + +@@ -1749,9 +1749,9 @@ void t_cpp_generator::generate_service(t_service* tservice) { + "};" << endl; + + // Generate service class +- if ( extends_service != nullptr ) { ++ if ( extends_service) { + f_header_ << "class " << service_name_ << " : public " << +- extends_service->get_name() << " {" << endl << ++ type_name(extends_service) << " {" << endl << + "public:" << endl; + } + else { +@@ -1841,7 +1841,7 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) { + void t_cpp_generator::generate_service_stub_interface(t_service* tservice) { + + string extends = ""; +- if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + extends = " : virtual public " + type_name(tservice->get_extends()) + "::StubInterface"; + } + +@@ -1890,7 +1890,7 @@ void t_cpp_generator::generate_service_stub(t_service* tservice) { + } + + t_service* extends_service = tservice->get_extends(); +- if (extends_service != nullptr) { ++ if (extends_service) { + // generate inherited methods + vector functions = extends_service->get_functions(); + vector::iterator f_iter; +@@ -1914,7 +1914,7 @@ void t_cpp_generator::generate_service_stub(t_service* tservice) { + indent() << "const ::grpc::RpcMethod rpcmethod_" << (*f_iter)->get_name() << "_;" << endl; + } + +- if (extends_service != nullptr) { ++ if (extends_service) { + // generate inherited methods + vector functions = extends_service->get_functions(); + vector::iterator f_iter; +@@ -1944,7 +1944,7 @@ void t_cpp_generator::generate_service_stub(t_service* tservice) { + service_name_ << "_method_names[" << i << "], ::grpc::RpcMethod::NORMAL_RPC, channel)" << endl; + } + +- if (extends_service != nullptr) { ++ if (extends_service) { + // generate inherited methods + vector functions = extends_service->get_functions(); + vector::iterator f_iter; +@@ -2002,7 +2002,7 @@ void t_cpp_generator::generate_service_stub(t_service* tservice) { + + } + +- if (extends_service != nullptr) { ++ if (extends_service) { + vector functions = extends_service->get_functions(); + vector::iterator f_iter; + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { +@@ -2049,7 +2049,7 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty + } + + string extends = ""; +- if (tservice->get_extends() != NULL) { ++ if (tservice->get_extends()) { + extends = " : virtual public " + type_name(tservice->get_extends()) + style + "::Service"; + if (style == "CobCl" && gen_templates_) { + // TODO(simpkins): If gen_templates_ is enabled, we currently assume all +diff --git a/tutorial/cpp/CppClient.cpp b/tutorial/cpp/GrpcClient.cpp +similarity index 100% +rename from tutorial/cpp/CppClient.cpp +rename to tutorial/cpp/GrpcClient.cpp +diff --git a/tutorial/cpp/CppServer.cpp b/tutorial/cpp/GrpcServer.cpp +similarity index 100% +rename from tutorial/cpp/CppServer.cpp +rename to tutorial/cpp/GrpcServer.cpp +diff --git a/tutorial/cpp/Makefile.am b/tutorial/cpp/Makefile.am +index 581f75e..39d85e1 100755 +--- a/tutorial/cpp/Makefile.am ++++ b/tutorial/cpp/Makefile.am +@@ -39,14 +39,14 @@ noinst_PROGRAMS = \ + TestClient + + TestServer_SOURCES = \ +- CppServer.cpp ++ GrpcServer.cpp + + TestServer_LDADD = \ + libtestgencpp.la \ + $(top_builddir)/lib/cpp/libthrift.la + + TestClient_SOURCES = \ +- CppClient.cpp ++ GrpcClient.cpp + + TestClient_LDADD = \ + libtestgencpp.la \ +@@ -78,5 +78,5 @@ style-local: + + EXTRA_DIST = \ + CMakeLists.txt \ +- CppClient.cpp \ +- CppServer.cpp ++ GrpcClient.cpp \ ++ GrpcServer.cpp +-- +2.8.0.rc3.226.g39d4020 + + +From b4bc0c810f00a1b86516774306ff4017e3d2d252 Mon Sep 17 00:00:00 2001 +From: chedeti +Date: Mon, 1 Aug 2016 17:00:17 -0700 +Subject: [PATCH 5/5] fix typo + +--- + tutorial/cpp/GrpcClient.cpp | 2 +- + tutorial/cpp/GrpcServer.cpp | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tutorial/cpp/GrpcClient.cpp b/tutorial/cpp/GrpcClient.cpp +index c41604e..41a7acf 100644 +--- a/tutorial/cpp/GrpcClient.cpp ++++ b/tutorial/cpp/GrpcClient.cpp +@@ -1,6 +1,6 @@ + /* + * +- * Copyright 2015, Google Inc. ++ * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without +diff --git a/tutorial/cpp/GrpcServer.cpp b/tutorial/cpp/GrpcServer.cpp +index c838b61..f63db57 100644 +--- a/tutorial/cpp/GrpcServer.cpp ++++ b/tutorial/cpp/GrpcServer.cpp +@@ -1,6 +1,6 @@ + /* + * +- * Copyright 2015, Google Inc. ++ * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without +-- +2.8.0.rc3.226.g39d4020 + diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 06ac86fc9c4..82b443a4742 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -6792,14 +6792,12 @@ ], "headers": [ "include/grpc++/impl/codegen/thrift_serializer.h", - "include/grpc++/impl/codegen/thrift_serializer_inl.h", "include/grpc++/impl/codegen/thrift_utils.h" ], "language": "c++", "name": "thrift_util", "src": [ "include/grpc++/impl/codegen/thrift_serializer.h", - "include/grpc++/impl/codegen/thrift_serializer_inl.h", "include/grpc++/impl/codegen/thrift_utils.h" ], "third_party": false, diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj index 96ce3b89164..c2c7d00a6d9 100644 --- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj +++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj @@ -201,7 +201,6 @@ - diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters index 2105e672df9..9b8c8ddfada 100644 --- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters @@ -195,9 +195,6 @@ include\grpc++\impl\codegen - - include\grpc++\impl\codegen - include\grpc++\impl\codegen From f5dcc9b5b5d1ade84eb7bac07abbac56f5f86675 Mon Sep 17 00:00:00 2001 From: chedeti Date: Mon, 1 Aug 2016 17:57:24 -0700 Subject: [PATCH 114/279] fix typos --- tools/grift/README.md | 16 ++++++++++++++-- tools/grift/grpc_plugins_generator.patch | 17 +++++++++++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/tools/grift/README.md b/tools/grift/README.md index a4cb87bff1a..25c67451326 100644 --- a/tools/grift/README.md +++ b/tools/grift/README.md @@ -6,10 +6,22 @@ grift is integration of [Apache Thrift](https://github.com/apache/thrift.git) Se This integration allows you to use grpc to send thrift messages in C++ and java. -By default grift uses Compact Protocol to serialize thrift messages. +grift uses Compact Protocol to serialize thrift messages. + +##generating grpc plugins for thrift services + +###CPP +```sh + $ thrift --gen cpp +``` + +###JAVA +```sh + $ thrift --gen java +``` #Installation -Before Installing thrift make sure to apply this [patch](grpc_plugins_generate.patch) to third_party/thrift. +Before Installing thrift make sure to apply this [patch](grpc_plugins_generator.patch) to third_party/thrift. Go to third_party/thrift and follow the [INSTALLATION](https://github.com/apache/thrift.git) instructions to install thrift. \ No newline at end of file diff --git a/tools/grift/grpc_plugins_generator.patch b/tools/grift/grpc_plugins_generator.patch index 9c18db35995..eeee1612519 100644 --- a/tools/grift/grpc_plugins_generator.patch +++ b/tools/grift/grpc_plugins_generator.patch @@ -2559,18 +2559,18 @@ index 581f75e..39d85e1 100755 2.8.0.rc3.226.g39d4020 -From b4bc0c810f00a1b86516774306ff4017e3d2d252 Mon Sep 17 00:00:00 2001 +From bc74fca1ee73333819724f51d5aaff3546443ed0 Mon Sep 17 00:00:00 2001 From: chedeti Date: Mon, 1 Aug 2016 17:00:17 -0700 Subject: [PATCH 5/5] fix typo --- - tutorial/cpp/GrpcClient.cpp | 2 +- + tutorial/cpp/GrpcClient.cpp | 4 ++-- tutorial/cpp/GrpcServer.cpp | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tutorial/cpp/GrpcClient.cpp b/tutorial/cpp/GrpcClient.cpp -index c41604e..41a7acf 100644 +index c41604e..ab1fe77 100644 --- a/tutorial/cpp/GrpcClient.cpp +++ b/tutorial/cpp/GrpcClient.cpp @@ -1,6 +1,6 @@ @@ -2581,6 +2581,15 @@ index c41604e..41a7acf 100644 * All rights reserved. * * Redistribution and use in source and binary forms, with or without +@@ -50,7 +50,7 @@ class GreeterClient { + GreeterClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + +- // Assambles the client's payload, sends it and presents the response back ++ // Assembles the client's payload, sends it and presents the response back + // from the server. + std::string SayHello(const std::string& user) { + // Data we are sending to the server. diff --git a/tutorial/cpp/GrpcServer.cpp b/tutorial/cpp/GrpcServer.cpp index c838b61..f63db57 100644 --- a/tutorial/cpp/GrpcServer.cpp From 1b22cddc7dcd3abb6cb7654a9a2243099d096229 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Fri, 15 Jul 2016 11:05:24 -0700 Subject: [PATCH 115/279] Add clientSuccess and serverSuccess to BQ schema --- tools/run_tests/performance/bq_upload_result.py | 2 ++ .../run_tests/performance/scenario_result_schema.json | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/tools/run_tests/performance/bq_upload_result.py b/tools/run_tests/performance/bq_upload_result.py index fbccf3bdcab..2a99499843a 100755 --- a/tools/run_tests/performance/bq_upload_result.py +++ b/tools/run_tests/performance/bq_upload_result.py @@ -118,6 +118,8 @@ def _flatten_result_inplace(scenario_result): for stats in scenario_result['clientStats']: stats['latencies'] = json.dumps(stats['latencies']) scenario_result['serverCores'] = json.dumps(scenario_result['serverCores']) + scenario_result['clientSuccess'] = json.dumps(scenario_result['clientSuccess']) + scenario_result['serverSuccess'] = json.dumps(scenario_result['serverSuccess']) def _populate_metadata_inplace(scenario_result): diff --git a/tools/run_tests/performance/scenario_result_schema.json b/tools/run_tests/performance/scenario_result_schema.json index 03254147571..6bec21df397 100644 --- a/tools/run_tests/performance/scenario_result_schema.json +++ b/tools/run_tests/performance/scenario_result_schema.json @@ -198,5 +198,15 @@ "mode": "NULLABLE" } ] + }, + { + "name": "clientSuccess", + "type": "STRING", + "mode": "NULLABLE" + }, + { + "name": "serverSuccess", + "type": "STRING", + "mode": "NULLABLE" } ] From 0ff122e3e55a297643805735986deb7f336c7159 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 2 Aug 2016 10:07:19 -0700 Subject: [PATCH 116/279] Ran generate_projects.sh. --- tools/run_tests/tests.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index 5cd74ff7edd..99ca67da33d 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -10679,7 +10679,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_loadreporting_test", + "name": "h2_load_reporting_test", "platforms": [ "windows", "linux", @@ -23915,7 +23915,7 @@ "exclude_configs": [], "flaky": false, "language": "c", - "name": "h2_loadreporting_nosec_test", + "name": "h2_load_reporting_nosec_test", "platforms": [ "windows", "linux", From 4004ac222ab62ea251da225fc261d68767d7727b Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 2 Aug 2016 10:08:27 -0700 Subject: [PATCH 117/279] Ran generate_projects.sh. --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d2e276e94d..23c0032865d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -996,6 +996,7 @@ add_library(grpc++ src/cpp/client/generic_stub.cc src/cpp/client/insecure_credentials.cc src/cpp/common/channel_arguments.cc + src/cpp/common/channel_filter.cc src/cpp/common/completion_queue.cc src/cpp/common/core_codegen.cc src/cpp/common/rpc_method.cc @@ -1251,6 +1252,7 @@ add_library(grpc++_unsecure src/cpp/client/generic_stub.cc src/cpp/client/insecure_credentials.cc src/cpp/common/channel_arguments.cc + src/cpp/common/channel_filter.cc src/cpp/common/completion_queue.cc src/cpp/common/core_codegen.cc src/cpp/common/rpc_method.cc From 6f7489373558d932558db24369b205601556061f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 2 Aug 2016 10:10:28 -0700 Subject: [PATCH 118/279] Fix Jenkins test error --- tools/run_tests/build_python.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/run_tests/build_python.sh b/tools/run_tests/build_python.sh index c4b5d98a53b..cb3446fc565 100755 --- a/tools/run_tests/build_python.sh +++ b/tools/run_tests/build_python.sh @@ -111,6 +111,7 @@ TOOLCHAIN=${4:-$(toolchain)} ROOT=`pwd` export CFLAGS="-I$ROOT/include -std=gnu99 -fno-wrapv $CFLAGS" export GRPC_PYTHON_BUILD_WITH_CYTHON=1 +export LANG=en_US.UTF-8 # Default python on the host to fall back to when instantiating e.g. the # virtualenv. From cca4a199e7786b2cee1743cd069551433e141e54 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 2 Aug 2016 10:36:53 -0700 Subject: [PATCH 119/279] Fix destroy_call_elem API in test. --- test/core/end2end/tests/filter_call_init_fails.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/end2end/tests/filter_call_init_fails.c b/test/core/end2end/tests/filter_call_init_fails.c index 08c377a281c..a09183b7868 100644 --- a/test/core/end2end/tests/filter_call_init_fails.c +++ b/test/core/end2end/tests/filter_call_init_fails.c @@ -210,7 +210,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, } static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - const grpc_call_stats *stats, + const grpc_call_final_info *final_info, void *and_free_memory) {} static void init_channel_elem(grpc_exec_ctx *exec_ctx, From 00be9de95cf040e2705c137ea213140562f7571d Mon Sep 17 00:00:00 2001 From: chedeti Date: Tue, 2 Aug 2016 10:44:41 -0700 Subject: [PATCH 120/279] fix codegen patch --- tools/grift/grpc_plugins_generator.patch | 880 ++++++++++------------- 1 file changed, 381 insertions(+), 499 deletions(-) diff --git a/tools/grift/grpc_plugins_generator.patch b/tools/grift/grpc_plugins_generator.patch index eeee1612519..3a6710c224e 100644 --- a/tools/grift/grpc_plugins_generator.patch +++ b/tools/grift/grpc_plugins_generator.patch @@ -1,7 +1,7 @@ From 0894590b5020c38106d4ebb2291994668c64f9dd Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 15:47:47 -0700 -Subject: [PATCH 1/5] don't build tests +Subject: [PATCH 1/3] don't build tests --- Makefile.am | 7 ++----- @@ -59,24 +59,30 @@ index 6fd15d2..7de1fad 100755 2.8.0.rc3.226.g39d4020 -From 04244fa7805740761db757e4c44251f723d85839 Mon Sep 17 00:00:00 2001 +From c8577ad5513543c57a81ad1bf4927cc8a78baa03 Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 16:16:40 -0700 -Subject: [PATCH 2/5] grpc cpp plugins generator with example +Subject: [PATCH 2/3] grpc cpp plugins generator with example --- - compiler/cpp/src/generate/t_cpp_generator.cc | 476 +++++++++++++++++++++++---- + compiler/cpp/src/generate/t_cpp_generator.cc | 478 +++++++++++++++++++++++---- tutorial/cpp/CMakeLists.txt | 53 --- - tutorial/cpp/CppClient.cpp | 134 ++++---- - tutorial/cpp/CppServer.cpp | 226 ++++--------- - tutorial/cpp/Makefile.am | 58 ++-- + tutorial/cpp/CppClient.cpp | 80 ----- + tutorial/cpp/CppServer.cpp | 181 ---------- + tutorial/cpp/GrpcClient.cpp | 94 ++++++ + tutorial/cpp/GrpcServer.cpp | 87 +++++ + tutorial/cpp/Makefile.am | 66 ++-- tutorial/cpp/test.thrift | 13 + - 6 files changed, 590 insertions(+), 370 deletions(-) + 8 files changed, 636 insertions(+), 416 deletions(-) delete mode 100644 tutorial/cpp/CMakeLists.txt + delete mode 100644 tutorial/cpp/CppClient.cpp + delete mode 100644 tutorial/cpp/CppServer.cpp + create mode 100644 tutorial/cpp/GrpcClient.cpp + create mode 100644 tutorial/cpp/GrpcServer.cpp create mode 100644 tutorial/cpp/test.thrift diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc -index 6c04899..9c3399b 100644 +index 6c04899..4e00129 100644 --- a/compiler/cpp/src/generate/t_cpp_generator.cc +++ b/compiler/cpp/src/generate/t_cpp_generator.cc @@ -162,6 +162,8 @@ public: @@ -266,7 +272,7 @@ index 6c04899..9c3399b 100644 t_service* extends_service = tservice->get_extends(); - if (extends_service != NULL) { -+ if (extends_service != nullptr) { ++ if (extends_service) { f_header_ << "#include \"" << get_include_prefix(*(extends_service->get_program())) - << extends_service->get_name() << ".h\"" << endl; + << extends_service->get_name() << ".grpc.thrift.h\"" << endl; @@ -355,7 +361,7 @@ index 6c04899..9c3399b 100644 + indent() << "\"/" << ns << "." << service_name_ << "/" << (*f_iter)->get_name() << "\"," << endl; + } + -+ if (extends_service != nullptr) { ++ if (extends_service) { + vector functions = extends_service->get_functions(); + vector::iterator f_iter; + @@ -371,9 +377,9 @@ index 6c04899..9c3399b 100644 + "};" << endl; + + // Generate service class -+ if ( extends_service != nullptr ) { ++ if ( extends_service) { + f_header_ << "class " << service_name_ << " : public " << -+ extends_service->get_name() << " {" << endl << ++ type_name(extends_service) << " {" << endl << + "public:" << endl; + } + else { @@ -442,7 +448,7 @@ index 6c04899..9c3399b 100644 +void t_cpp_generator::generate_service_stub_interface(t_service* tservice) { + + string extends = ""; -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + extends = " : virtual public " + type_name(tservice->get_extends()) + "::StubInterface"; + } + @@ -491,7 +497,7 @@ index 6c04899..9c3399b 100644 + } + + t_service* extends_service = tservice->get_extends(); -+ if (extends_service != nullptr) { ++ if (extends_service) { + // generate inherited methods + vector functions = extends_service->get_functions(); + vector::iterator f_iter; @@ -515,7 +521,7 @@ index 6c04899..9c3399b 100644 + indent() << "const ::grpc::RpcMethod rpcmethod_" << (*f_iter)->get_name() << "_;" << endl; + } + -+ if (extends_service != nullptr) { ++ if (extends_service) { + // generate inherited methods + vector functions = extends_service->get_functions(); + vector::iterator f_iter; @@ -545,7 +551,7 @@ index 6c04899..9c3399b 100644 + service_name_ << "_method_names[" << i << "], ::grpc::RpcMethod::NORMAL_RPC, channel)" << endl; + } + -+ if (extends_service != nullptr) { ++ if (extends_service) { + // generate inherited methods + vector functions = extends_service->get_functions(); + vector::iterator f_iter; @@ -603,7 +609,7 @@ index 6c04899..9c3399b 100644 + + } + -+ if (extends_service != nullptr) { ++ if (extends_service) { + vector functions = extends_service->get_functions(); + vector::iterator f_iter; + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -642,11 +648,13 @@ index 6c04899..9c3399b 100644 if (style == "CobCl") { // Forward declare the client. string client_name = service_name_ + "CobClient"; -@@ -1765,12 +2050,14 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty +@@ -1764,13 +2049,15 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty + } string extends = ""; - if (tservice->get_extends() != NULL) { +- if (tservice->get_extends() != NULL) { - extends = " : virtual public " + type_name(tservice->get_extends()) + style + "If"; ++ if (tservice->get_extends()) { + extends = " : virtual public " + type_name(tservice->get_extends()) + style + "::Service"; if (style == "CobCl" && gen_templates_) { // TODO(simpkins): If gen_templates_ is enabled, we currently assume all @@ -867,11 +875,12 @@ index 8a3d085..0000000 -LINK_AGAINST_THRIFT_LIBRARY(TutorialClient thrift) -target_link_libraries(TutorialClient ${ZLIB_LIBRARIES}) diff --git a/tutorial/cpp/CppClient.cpp b/tutorial/cpp/CppClient.cpp -index 2763fee..c41604e 100644 +deleted file mode 100644 +index 2763fee..0000000 --- a/tutorial/cpp/CppClient.cpp -+++ b/tutorial/cpp/CppClient.cpp -@@ -1,80 +1,94 @@ - /* ++++ /dev/null +@@ -1,80 +0,0 @@ +-/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information @@ -879,9 +888,274 @@ index 2763fee..c41604e 100644 - * to you 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 -+ * Copyright 2015, Google Inc. +- * +- * 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 +- +-#include +-#include +-#include +- +-#include "../gen-cpp/Calculator.h" +- +-using namespace std; +-using namespace apache::thrift; +-using namespace apache::thrift::protocol; +-using namespace apache::thrift::transport; +- +-using namespace tutorial; +-using namespace shared; +- +-int main() { +- boost::shared_ptr socket(new TSocket("localhost", 9090)); +- boost::shared_ptr transport(new TBufferedTransport(socket)); +- boost::shared_ptr protocol(new TBinaryProtocol(transport)); +- CalculatorClient client(protocol); +- +- try { +- transport->open(); +- +- client.ping(); +- cout << "ping()" << endl; +- +- cout << "1 + 1 = " << client.add(1, 1) << endl; +- +- Work work; +- work.op = Operation::DIVIDE; +- work.num1 = 1; +- work.num2 = 0; +- +- try { +- client.calculate(1, work); +- cout << "Whoa? We can divide by zero!" << endl; +- } catch (InvalidOperation& io) { +- cout << "InvalidOperation: " << io.why << endl; +- // or using generated operator<<: cout << io << endl; +- // or by using std::exception native method what(): cout << io.what() << endl; +- } +- +- work.op = Operation::SUBTRACT; +- work.num1 = 15; +- work.num2 = 10; +- int32_t diff = client.calculate(1, work); +- cout << "15 - 10 = " << diff << endl; +- +- // Note that C++ uses return by reference for complex types to avoid +- // costly copy construction +- SharedStruct ss; +- client.getStruct(ss, 1); +- cout << "Received log: " << ss << endl; +- +- transport->close(); +- } catch (TException& tx) { +- cout << "ERROR: " << tx.what() << endl; +- } +-} +diff --git a/tutorial/cpp/CppServer.cpp b/tutorial/cpp/CppServer.cpp +deleted file mode 100644 +index eafffa9..0000000 +--- a/tutorial/cpp/CppServer.cpp ++++ /dev/null +@@ -1,181 +0,0 @@ +-/* +- * Licensed to the Apache Software Foundation (ASF) under one +- * or more contributor license agreements. See the NOTICE file +- * distributed with this work for additional information +- * regarding copyright ownership. The ASF licenses this file +- * to you 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 +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +- +-#include +-#include +-#include +- +-#include "../gen-cpp/Calculator.h" +- +-using namespace std; +-using namespace apache::thrift; +-using namespace apache::thrift::concurrency; +-using namespace apache::thrift::protocol; +-using namespace apache::thrift::transport; +-using namespace apache::thrift::server; +- +-using namespace tutorial; +-using namespace shared; +- +-class CalculatorHandler : public CalculatorIf { +-public: +- CalculatorHandler() {} +- +- void ping() { cout << "ping()" << endl; } +- +- int32_t add(const int32_t n1, const int32_t n2) { +- cout << "add(" << n1 << ", " << n2 << ")" << endl; +- return n1 + n2; +- } +- +- int32_t calculate(const int32_t logid, const Work& work) { +- cout << "calculate(" << logid << ", " << work << ")" << endl; +- int32_t val; +- +- switch (work.op) { +- case Operation::ADD: +- val = work.num1 + work.num2; +- break; +- case Operation::SUBTRACT: +- val = work.num1 - work.num2; +- break; +- case Operation::MULTIPLY: +- val = work.num1 * work.num2; +- break; +- case Operation::DIVIDE: +- if (work.num2 == 0) { +- InvalidOperation io; +- io.whatOp = work.op; +- io.why = "Cannot divide by 0"; +- throw io; +- } +- val = work.num1 / work.num2; +- break; +- default: +- InvalidOperation io; +- io.whatOp = work.op; +- io.why = "Invalid Operation"; +- throw io; +- } +- +- SharedStruct ss; +- ss.key = logid; +- ss.value = to_string(val); +- +- log[logid] = ss; +- +- return val; +- } +- +- void getStruct(SharedStruct& ret, const int32_t logid) { +- cout << "getStruct(" << logid << ")" << endl; +- ret = log[logid]; +- } +- +- void zip() { cout << "zip()" << endl; } +- +-protected: +- map log; +-}; +- +-/* +- CalculatorIfFactory is code generated. +- CalculatorCloneFactory is useful for getting access to the server side of the +- transport. It is also useful for making per-connection state. Without this +- CloneFactory, all connections will end up sharing the same handler instance. +-*/ +-class CalculatorCloneFactory : virtual public CalculatorIfFactory { +- public: +- virtual ~CalculatorCloneFactory() {} +- virtual CalculatorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) +- { +- boost::shared_ptr sock = boost::dynamic_pointer_cast(connInfo.transport); +- cout << "Incoming connection\n"; +- cout << "\tSocketInfo: " << sock->getSocketInfo() << "\n"; +- cout << "\tPeerHost: " << sock->getPeerHost() << "\n"; +- cout << "\tPeerAddress: " << sock->getPeerAddress() << "\n"; +- cout << "\tPeerPort: " << sock->getPeerPort() << "\n"; +- return new CalculatorHandler; +- } +- virtual void releaseHandler( ::shared::SharedServiceIf* handler) { +- delete handler; +- } +-}; +- +-int main() { +- TThreadedServer server( +- boost::make_shared(boost::make_shared()), +- boost::make_shared(9090), //port +- boost::make_shared(), +- boost::make_shared()); +- +- /* +- // if you don't need per-connection state, do the following instead +- TThreadedServer server( +- boost::make_shared(boost::make_shared()), +- boost::make_shared(9090), //port +- boost::make_shared(), +- boost::make_shared()); +- */ +- +- /** +- * Here are some alternate server types... +- +- // This server only allows one connection at a time, but spawns no threads +- TSimpleServer server( +- boost::make_shared(boost::make_shared()), +- boost::make_shared(9090), +- boost::make_shared(), +- boost::make_shared()); +- +- const int workerCount = 4; +- +- boost::shared_ptr threadManager = +- ThreadManager::newSimpleThreadManager(workerCount); +- threadManager->threadFactory( +- boost::make_shared()); +- threadManager->start(); +- +- // This server allows "workerCount" connection at a time, and reuses threads +- TThreadPoolServer server( +- boost::make_shared(boost::make_shared()), +- boost::make_shared(9090), +- boost::make_shared(), +- boost::make_shared(), +- threadManager); +- */ +- +- cout << "Starting the server..." << endl; +- server.serve(); +- cout << "Done." << endl; +- return 0; +-} +diff --git a/tutorial/cpp/GrpcClient.cpp b/tutorial/cpp/GrpcClient.cpp +new file mode 100644 +index 0000000..ab1fe77 +--- /dev/null ++++ b/tutorial/cpp/GrpcClient.cpp +@@ -0,0 +1,94 @@ ++/* ++ * ++ * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without @@ -909,105 +1183,57 @@ index 2763fee..c41604e 100644 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -- * 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 ++ * ++ */ ++ ++#include +#include +#include - --#include --#include --#include -- --#include "../gen-cpp/Calculator.h" ++ +#include - --using namespace std; --using namespace apache::thrift; --using namespace apache::thrift::protocol; --using namespace apache::thrift::transport; ++ +#include "gen-cpp/Greeter.grpc.thrift.h" - --using namespace tutorial; --using namespace shared; ++ +using grpc::Channel; +using grpc::ClientContext; +using grpc::Status; +using test::Greeter; +using namespace test; - --int main() { -- boost::shared_ptr socket(new TSocket("localhost", 9090)); -- boost::shared_ptr transport(new TBufferedTransport(socket)); -- boost::shared_ptr protocol(new TBinaryProtocol(transport)); -- CalculatorClient client(protocol); ++ +class GreeterClient { + public: + GreeterClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} - -- try { -- transport->open(); -+ // Assambles the client's payload, sends it and presents the response back ++ ++ // Assembles the client's payload, sends it and presents the response back + // from the server. + std::string SayHello(const std::string& user) { + // Data we are sending to the server. + Greeter::SayHelloReq req; + req.request.name = user; - -- client.ping(); -- cout << "ping()" << endl; ++ + // Container for the data we expect from the server. + Greeter::SayHelloResp reply; - -- cout << "1 + 1 = " << client.add(1, 1) << endl; ++ + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. + ClientContext context; - -- Work work; -- work.op = Operation::DIVIDE; -- work.num1 = 1; -- work.num2 = 0; ++ + // The actual RPC. + Status status = stub_->SayHello(&context, req, &reply); - -- try { -- client.calculate(1, work); -- cout << "Whoa? We can divide by zero!" << endl; -- } catch (InvalidOperation& io) { -- cout << "InvalidOperation: " << io.why << endl; -- // or using generated operator<<: cout << io << endl; -- // or by using std::exception native method what(): cout << io.what() << endl; ++ + // Act upon its status. + if (status.ok()) { + return reply.success.message; + } else { + return "RPC failed"; - } ++ } + } - -- work.op = Operation::SUBTRACT; -- work.num1 = 15; -- work.num2 = 10; -- int32_t diff = client.calculate(1, work); -- cout << "15 - 10 = " << diff << endl; ++ + private: + std::unique_ptr stub_; +}; - -- // Note that C++ uses return by reference for complex types to avoid -- // costly copy construction -- SharedStruct ss; -- client.getStruct(ss, 1); -- cout << "Received log: " << ss << endl; ++ +int main() { + // Instantiate the client. It requires a channel, out of which the actual RPCs + // are created. This channel models a connection to an endpoint (in this case, @@ -1018,29 +1244,18 @@ index 2763fee..c41604e 100644 + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Greeter received: " << reply << std::endl; - -- transport->close(); -- } catch (TException& tx) { -- cout << "ERROR: " << tx.what() << endl; -- } ++ + return 0; - } -diff --git a/tutorial/cpp/CppServer.cpp b/tutorial/cpp/CppServer.cpp -index eafffa9..c838b61 100644 ---- a/tutorial/cpp/CppServer.cpp -+++ b/tutorial/cpp/CppServer.cpp -@@ -1,181 +1,87 @@ - /* -- * Licensed to the Apache Software Foundation (ASF) under one -- * or more contributor license agreements. See the NOTICE file -- * distributed with this work for additional information -- * regarding copyright ownership. The ASF licenses this file -- * to you 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 -+ * Copyright 2015, Google Inc. ++} +diff --git a/tutorial/cpp/GrpcServer.cpp b/tutorial/cpp/GrpcServer.cpp +new file mode 100644 +index 0000000..f63db57 +--- /dev/null ++++ b/tutorial/cpp/GrpcServer.cpp +@@ -0,0 +1,87 @@ ++/* ++ * ++ * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without @@ -1068,147 +1283,39 @@ index eafffa9..c838b61 100644 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * -- * 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 --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include -- - #include --#include --#include -- --#include "../gen-cpp/Calculator.h" ++ * ++ */ ++ ++#include +#include +#include - --using namespace std; --using namespace apache::thrift; --using namespace apache::thrift::concurrency; --using namespace apache::thrift::protocol; --using namespace apache::thrift::transport; --using namespace apache::thrift::server; ++ +#include - --using namespace tutorial; --using namespace shared; -+#include "gen-cpp/Greeter.grpc.thrift.h" -+#include - --class CalculatorHandler : public CalculatorIf { --public: -- CalculatorHandler() {} ++ ++#include "gen-cpp/Greeter.grpc.thrift.h" ++#include ++ +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::Status; +using test::Greeter; - -- void ping() { cout << "ping()" << endl; } ++ +using namespace grpc; +using namespace test; - -- int32_t add(const int32_t n1, const int32_t n2) { -- cout << "add(" << n1 << ", " << n2 << ")" << endl; -- return n1 + n2; -- } ++ +// Logic and data behind the server's behavior. +class GreeterServiceImpl final : public Greeter::Service { + Status SayHello(ServerContext* context,const Greeter::SayHelloReq* request, + Greeter::SayHelloResp* reply) override { + std::string prefix("Hello "); - -- int32_t calculate(const int32_t logid, const Work& work) { -- cout << "calculate(" << logid << ", " << work << ")" << endl; -- int32_t val; ++ + reply->success.message = prefix + request->request.name; - -- switch (work.op) { -- case Operation::ADD: -- val = work.num1 + work.num2; -- break; -- case Operation::SUBTRACT: -- val = work.num1 - work.num2; -- break; -- case Operation::MULTIPLY: -- val = work.num1 * work.num2; -- break; -- case Operation::DIVIDE: -- if (work.num2 == 0) { -- InvalidOperation io; -- io.whatOp = work.op; -- io.why = "Cannot divide by 0"; -- throw io; -- } -- val = work.num1 / work.num2; -- break; -- default: -- InvalidOperation io; -- io.whatOp = work.op; -- io.why = "Invalid Operation"; -- throw io; -- } -- -- SharedStruct ss; -- ss.key = logid; -- ss.value = to_string(val); -- -- log[logid] = ss; -- -- return val; ++ + return Status::OK; - } -- -- void getStruct(SharedStruct& ret, const int32_t logid) { -- cout << "getStruct(" << logid << ")" << endl; -- ret = log[logid]; -- } -- -- void zip() { cout << "zip()" << endl; } -- --protected: -- map log; - }; - --/* -- CalculatorIfFactory is code generated. -- CalculatorCloneFactory is useful for getting access to the server side of the -- transport. It is also useful for making per-connection state. Without this -- CloneFactory, all connections will end up sharing the same handler instance. --*/ --class CalculatorCloneFactory : virtual public CalculatorIfFactory { -- public: -- virtual ~CalculatorCloneFactory() {} -- virtual CalculatorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) -- { -- boost::shared_ptr sock = boost::dynamic_pointer_cast(connInfo.transport); -- cout << "Incoming connection\n"; -- cout << "\tSocketInfo: " << sock->getSocketInfo() << "\n"; -- cout << "\tPeerHost: " << sock->getPeerHost() << "\n"; -- cout << "\tPeerAddress: " << sock->getPeerAddress() << "\n"; -- cout << "\tPeerPort: " << sock->getPeerPort() << "\n"; -- return new CalculatorHandler; -- } -- virtual void releaseHandler( ::shared::SharedServiceIf* handler) { -- delete handler; -- } --}; ++ } ++}; ++ +void RunServer() { + std::string server_address("0.0.0.0:50051"); + GreeterServiceImpl service; @@ -1227,58 +1334,14 @@ index eafffa9..c838b61 100644 + // responsible for shutting down the server for this call to ever return. + server->Wait(); +} - - int main() { -- TThreadedServer server( -- boost::make_shared(boost::make_shared()), -- boost::make_shared(9090), //port -- boost::make_shared(), -- boost::make_shared()); -- -- /* -- // if you don't need per-connection state, do the following instead -- TThreadedServer server( -- boost::make_shared(boost::make_shared()), -- boost::make_shared(9090), //port -- boost::make_shared(), -- boost::make_shared()); -- */ -- -- /** -- * Here are some alternate server types... -- -- // This server only allows one connection at a time, but spawns no threads -- TSimpleServer server( -- boost::make_shared(boost::make_shared()), -- boost::make_shared(9090), -- boost::make_shared(), -- boost::make_shared()); -- -- const int workerCount = 4; -- -- boost::shared_ptr threadManager = -- ThreadManager::newSimpleThreadManager(workerCount); -- threadManager->threadFactory( -- boost::make_shared()); -- threadManager->start(); -- -- // This server allows "workerCount" connection at a time, and reuses threads -- TThreadPoolServer server( -- boost::make_shared(boost::make_shared()), -- boost::make_shared(9090), -- boost::make_shared(), -- boost::make_shared(), -- threadManager); -- */ ++ ++int main() { + RunServer(); - -- cout << "Starting the server..." << endl; -- server.serve(); -- cout << "Done." << endl; - return 0; - } ++ ++ return 0; ++} diff --git a/tutorial/cpp/Makefile.am b/tutorial/cpp/Makefile.am -index 184a69d..581f75e 100755 +index 184a69d..39d85e1 100755 --- a/tutorial/cpp/Makefile.am +++ b/tutorial/cpp/Makefile.am @@ -18,44 +18,38 @@ @@ -1325,8 +1388,9 @@ index 184a69d..581f75e 100755 + TestClient -TutorialServer_SOURCES = \ +- CppServer.cpp +TestServer_SOURCES = \ - CppServer.cpp ++ GrpcServer.cpp -TutorialServer_LDADD = \ - libtutorialgencpp.la \ @@ -1335,8 +1399,9 @@ index 184a69d..581f75e 100755 $(top_builddir)/lib/cpp/libthrift.la -TutorialClient_SOURCES = \ +- CppClient.cpp +TestClient_SOURCES = \ - CppClient.cpp ++ GrpcClient.cpp -TutorialClient_LDADD = \ - libtutorialgencpp.la \ @@ -1345,7 +1410,7 @@ index 184a69d..581f75e 100755 $(top_builddir)/lib/cpp/libthrift.la # -@@ -63,21 +57,21 @@ TutorialClient_LDADD = \ +@@ -63,26 +57,26 @@ TutorialClient_LDADD = \ # THRIFT = $(top_builddir)/compiler/cpp/thrift @@ -1374,6 +1439,13 @@ index 184a69d..581f75e 100755 style-local: $(CPPSTYLE_CMD) + + EXTRA_DIST = \ + CMakeLists.txt \ +- CppClient.cpp \ +- CppServer.cpp ++ GrpcClient.cpp \ ++ GrpcServer.cpp diff --git a/tutorial/cpp/test.thrift b/tutorial/cpp/test.thrift new file mode 100644 index 0000000..de3c9a4 @@ -1398,10 +1470,10 @@ index 0000000..de3c9a4 2.8.0.rc3.226.g39d4020 -From 1d47ed062e62d136c3db9f6fc1dde9e2f794cf22 Mon Sep 17 00:00:00 2001 +From 096042c132126536870eea118127cf1e608969bc Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 16:23:53 -0700 -Subject: [PATCH 3/5] grpc java plugins generator +Subject: [PATCH 3/3] grpc java plugins generator for examples refer to https://github.com/grpc/grpc-java/tree/master/examples/thrift --- @@ -1410,7 +1482,7 @@ for examples refer to https://github.com/grpc/grpc-java/tree/master/examples/thr 2 files changed, 887 insertions(+), 27 deletions(-) diff --git a/compiler/cpp/src/generate/t_java_generator.cc b/compiler/cpp/src/generate/t_java_generator.cc -index 2db8cb8..95e1ca8 100644 +index 2db8cb8..8b28fe2 100644 --- a/compiler/cpp/src/generate/t_java_generator.cc +++ b/compiler/cpp/src/generate/t_java_generator.cc @@ -97,10 +97,10 @@ public: @@ -1487,7 +1559,7 @@ index 2db8cb8..95e1ca8 100644 +} + +string t_java_generator::import_extended_service(t_service* tservice) { -+ if (tservice == nullptr) { ++ if (!tservice) { + return string() + "\n"; + } + string ns = tservice->get_program()->get_namespace("java"); @@ -1575,7 +1647,7 @@ index 2db8cb8..95e1ca8 100644 + f_service_ << indent() << + "@java.lang.Deprecated public static interface " << service_name_; + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + f_service_ << " extends " << tservice->get_extends()->get_name() + "Grpc." << + tservice->get_extends()->get_name() << endl; + } @@ -1610,7 +1682,7 @@ index 2db8cb8..95e1ca8 100644 + } + f_service_ << endl; + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + f_service_ << indent() << "// ARG IDs for extended service" << endl; + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); @@ -1663,7 +1735,7 @@ index 2db8cb8..95e1ca8 100644 + endl << indent() << " break;" << endl; + } + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); + string extend_service_name = extend_service->get_name() + "Grpc"; @@ -1721,7 +1793,7 @@ index 2db8cb8..95e1ca8 100644 + indent() << "}" << endl << endl; + } + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); + string extend_service_name = extend_service->get_name() + "Grpc" ; @@ -1786,7 +1858,7 @@ index 2db8cb8..95e1ca8 100644 + indent_down(); + } + -+ if(tservice->get_extends() != nullptr) { ++ if(tservice->get_extends()) { + t_service* extends_service = tservice->get_extends(); + functions = extends_service->get_functions(); + string extend_service_name = extends_service->get_name() + "Grpc"; @@ -1886,7 +1958,7 @@ index 2db8cb8..95e1ca8 100644 + indent() << "}" << endl << endl; + } + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); + string extend_service_name = extend_service->get_name() + "Grpc"; @@ -1930,7 +2002,7 @@ index 2db8cb8..95e1ca8 100644 + indent() << "@java.lang.Deprecated public static interface " << service_name_ << + "BlockingClient " ; + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + string extend_service_name = tservice->get_extends()->get_name(); + f_service_ << endl << indent() << " extends " << extend_service_name << "Grpc." << + extend_service_name << "BlockingClient " ; @@ -2008,7 +2080,7 @@ index 2db8cb8..95e1ca8 100644 + indent() << "}" << endl << endl; + } + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); + string extend_service_name = extend_service->get_name() + "Grpc"; @@ -2050,7 +2122,7 @@ index 2db8cb8..95e1ca8 100644 + indent() << "@java.lang.Deprecated public static interface " << service_name_ << + "FutureClient " ; + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + string extend_service_name = tservice->get_extends()->get_name(); + f_service_ << endl << indent() << " extends " << extend_service_name << "Grpc." << + extend_service_name << "FutureClient " ; @@ -2068,7 +2140,7 @@ index 2db8cb8..95e1ca8 100644 + indent() << " " << (*f_iter)->get_name() << "_args request);" << endl << endl; + } + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); + string extend_service_name = extend_service->get_name() + "Grpc"; @@ -2141,7 +2213,7 @@ index 2db8cb8..95e1ca8 100644 + indent() << "}" << endl << endl; + } + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); + string extend_service_name = extend_service->get_name() + "Grpc"; @@ -2176,7 +2248,7 @@ index 2db8cb8..95e1ca8 100644 + indent() << "private static final int METHODID_" << + (*f_iter)->get_name() << " = " << i << ";" << endl; + } -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); + string extend_service_name = extend_service->get_name() + "Grpc"; @@ -2238,7 +2310,7 @@ index 2db8cb8..95e1ca8 100644 + indent() << "break;" << endl << endl; + indent_down(); + } -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); + string extend_service_name = extend_service->get_name() + "Grpc"; @@ -2303,7 +2375,7 @@ index 2db8cb8..95e1ca8 100644 + indent() << "," << endl << + indent() << " METHOD_" << (*f_iter)->get_name(); + } -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); + for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { @@ -2352,7 +2424,7 @@ index 2db8cb8..95e1ca8 100644 + indent_down(); + } + -+ if (tservice->get_extends() != nullptr) { ++ if (tservice->get_extends()) { + t_service* extend_service = tservice->get_extends(); + functions = extend_service->get_functions(); + string extend_service_name = extend_service->get_name() + "Grpc"; @@ -2415,193 +2487,3 @@ index 5865c54..1cffbe6 100755 -- 2.8.0.rc3.226.g39d4020 - -From a9769a0fa08f553da76215ca59a8fd797b92a853 Mon Sep 17 00:00:00 2001 -From: chedeti -Date: Mon, 1 Aug 2016 16:56:36 -0700 -Subject: [PATCH 4/5] maintain consistency with grpc - ---- - compiler/cpp/src/generate/t_cpp_generator.cc | 20 ++++++++++---------- - tutorial/cpp/{CppClient.cpp => GrpcClient.cpp} | 0 - tutorial/cpp/{CppServer.cpp => GrpcServer.cpp} | 0 - tutorial/cpp/Makefile.am | 8 ++++---- - 4 files changed, 14 insertions(+), 14 deletions(-) - rename tutorial/cpp/{CppClient.cpp => GrpcClient.cpp} (100%) - rename tutorial/cpp/{CppServer.cpp => GrpcServer.cpp} (100%) - -diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc -index 9c3399b..4e00129 100644 ---- a/compiler/cpp/src/generate/t_cpp_generator.cc -+++ b/compiler/cpp/src/generate/t_cpp_generator.cc -@@ -1641,7 +1641,7 @@ void t_cpp_generator::generate_service(t_service* tservice) { - << endl; - - t_service* extends_service = tservice->get_extends(); -- if (extends_service != nullptr) { -+ if (extends_service) { - f_header_ << "#include \"" << get_include_prefix(*(extends_service->get_program())) - << extends_service->get_name() << ".grpc.thrift.h\"" << endl; - } -@@ -1733,7 +1733,7 @@ void t_cpp_generator::generate_service(t_service* tservice) { - indent() << "\"/" << ns << "." << service_name_ << "/" << (*f_iter)->get_name() << "\"," << endl; - } - -- if (extends_service != nullptr) { -+ if (extends_service) { - vector functions = extends_service->get_functions(); - vector::iterator f_iter; - -@@ -1749,9 +1749,9 @@ void t_cpp_generator::generate_service(t_service* tservice) { - "};" << endl; - - // Generate service class -- if ( extends_service != nullptr ) { -+ if ( extends_service) { - f_header_ << "class " << service_name_ << " : public " << -- extends_service->get_name() << " {" << endl << -+ type_name(extends_service) << " {" << endl << - "public:" << endl; - } - else { -@@ -1841,7 +1841,7 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) { - void t_cpp_generator::generate_service_stub_interface(t_service* tservice) { - - string extends = ""; -- if (tservice->get_extends() != nullptr) { -+ if (tservice->get_extends()) { - extends = " : virtual public " + type_name(tservice->get_extends()) + "::StubInterface"; - } - -@@ -1890,7 +1890,7 @@ void t_cpp_generator::generate_service_stub(t_service* tservice) { - } - - t_service* extends_service = tservice->get_extends(); -- if (extends_service != nullptr) { -+ if (extends_service) { - // generate inherited methods - vector functions = extends_service->get_functions(); - vector::iterator f_iter; -@@ -1914,7 +1914,7 @@ void t_cpp_generator::generate_service_stub(t_service* tservice) { - indent() << "const ::grpc::RpcMethod rpcmethod_" << (*f_iter)->get_name() << "_;" << endl; - } - -- if (extends_service != nullptr) { -+ if (extends_service) { - // generate inherited methods - vector functions = extends_service->get_functions(); - vector::iterator f_iter; -@@ -1944,7 +1944,7 @@ void t_cpp_generator::generate_service_stub(t_service* tservice) { - service_name_ << "_method_names[" << i << "], ::grpc::RpcMethod::NORMAL_RPC, channel)" << endl; - } - -- if (extends_service != nullptr) { -+ if (extends_service) { - // generate inherited methods - vector functions = extends_service->get_functions(); - vector::iterator f_iter; -@@ -2002,7 +2002,7 @@ void t_cpp_generator::generate_service_stub(t_service* tservice) { - - } - -- if (extends_service != nullptr) { -+ if (extends_service) { - vector functions = extends_service->get_functions(); - vector::iterator f_iter; - for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { -@@ -2049,7 +2049,7 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty - } - - string extends = ""; -- if (tservice->get_extends() != NULL) { -+ if (tservice->get_extends()) { - extends = " : virtual public " + type_name(tservice->get_extends()) + style + "::Service"; - if (style == "CobCl" && gen_templates_) { - // TODO(simpkins): If gen_templates_ is enabled, we currently assume all -diff --git a/tutorial/cpp/CppClient.cpp b/tutorial/cpp/GrpcClient.cpp -similarity index 100% -rename from tutorial/cpp/CppClient.cpp -rename to tutorial/cpp/GrpcClient.cpp -diff --git a/tutorial/cpp/CppServer.cpp b/tutorial/cpp/GrpcServer.cpp -similarity index 100% -rename from tutorial/cpp/CppServer.cpp -rename to tutorial/cpp/GrpcServer.cpp -diff --git a/tutorial/cpp/Makefile.am b/tutorial/cpp/Makefile.am -index 581f75e..39d85e1 100755 ---- a/tutorial/cpp/Makefile.am -+++ b/tutorial/cpp/Makefile.am -@@ -39,14 +39,14 @@ noinst_PROGRAMS = \ - TestClient - - TestServer_SOURCES = \ -- CppServer.cpp -+ GrpcServer.cpp - - TestServer_LDADD = \ - libtestgencpp.la \ - $(top_builddir)/lib/cpp/libthrift.la - - TestClient_SOURCES = \ -- CppClient.cpp -+ GrpcClient.cpp - - TestClient_LDADD = \ - libtestgencpp.la \ -@@ -78,5 +78,5 @@ style-local: - - EXTRA_DIST = \ - CMakeLists.txt \ -- CppClient.cpp \ -- CppServer.cpp -+ GrpcClient.cpp \ -+ GrpcServer.cpp --- -2.8.0.rc3.226.g39d4020 - - -From bc74fca1ee73333819724f51d5aaff3546443ed0 Mon Sep 17 00:00:00 2001 -From: chedeti -Date: Mon, 1 Aug 2016 17:00:17 -0700 -Subject: [PATCH 5/5] fix typo - ---- - tutorial/cpp/GrpcClient.cpp | 4 ++-- - tutorial/cpp/GrpcServer.cpp | 2 +- - 2 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/tutorial/cpp/GrpcClient.cpp b/tutorial/cpp/GrpcClient.cpp -index c41604e..ab1fe77 100644 ---- a/tutorial/cpp/GrpcClient.cpp -+++ b/tutorial/cpp/GrpcClient.cpp -@@ -1,6 +1,6 @@ - /* - * -- * Copyright 2015, Google Inc. -+ * Copyright 2016, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without -@@ -50,7 +50,7 @@ class GreeterClient { - GreeterClient(std::shared_ptr channel) - : stub_(Greeter::NewStub(channel)) {} - -- // Assambles the client's payload, sends it and presents the response back -+ // Assembles the client's payload, sends it and presents the response back - // from the server. - std::string SayHello(const std::string& user) { - // Data we are sending to the server. -diff --git a/tutorial/cpp/GrpcServer.cpp b/tutorial/cpp/GrpcServer.cpp -index c838b61..f63db57 100644 ---- a/tutorial/cpp/GrpcServer.cpp -+++ b/tutorial/cpp/GrpcServer.cpp -@@ -1,6 +1,6 @@ - /* - * -- * Copyright 2015, Google Inc. -+ * Copyright 2016, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without --- -2.8.0.rc3.226.g39d4020 - From f32e71eaca170d182f104b83c761ea22b6783d61 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Tue, 2 Aug 2016 11:11:23 -0700 Subject: [PATCH 121/279] Downgrade docker setuptools --- tools/run_tests/build_python.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/run_tests/build_python.sh b/tools/run_tests/build_python.sh index 13d745d14fe..83e456d3ed2 100755 --- a/tools/run_tests/build_python.sh +++ b/tools/run_tests/build_python.sh @@ -168,7 +168,9 @@ pip_install_dir() { cd $PWD } -$VENV_PYTHON -m pip install --upgrade pip setuptools +$VENV_PYTHON -m pip install --upgrade pip +# TODO(https://github.com/pypa/setuptools/issues/709) get the latest setuptools +$VENV_PYTHON -m pip install setuptools==25.1.1 $VENV_PYTHON -m pip install cython pip_install_dir $ROOT $VENV_PYTHON $ROOT/tools/distrib/python/make_grpcio_tools.py From 2db3d9926997ba6a94c9d50bdf5ff4c75e7680e3 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 2 Aug 2016 13:07:35 -0700 Subject: [PATCH 122/279] Fix error handling authentication errors with non-numeric error codes --- src/node/src/credentials.js | 4 +++- src/node/test/credentials_test.js | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/node/src/credentials.js b/src/node/src/credentials.js index 043df06a669..51ff1da01ec 100644 --- a/src/node/src/credentials.js +++ b/src/node/src/credentials.js @@ -71,6 +71,8 @@ var Metadata = require('./metadata.js'); var common = require('./common.js'); +var _ = require('lodash'); + /** * Create an SSL Credentials object. If using a client-side certificate, both * the second and third arguments must be passed. @@ -99,7 +101,7 @@ exports.createFromMetadataGenerator = function(metadata_generator) { var message = ''; if (error) { message = error.message; - if (error.hasOwnProperty('code')) { + if (error.hasOwnProperty('code') && _.isFinite(error.code)) { code = error.code; } else { code = grpc.status.UNAUTHENTICATED; diff --git a/src/node/test/credentials_test.js b/src/node/test/credentials_test.js index 0a21572582e..305843f665e 100644 --- a/src/node/test/credentials_test.js +++ b/src/node/test/credentials_test.js @@ -71,7 +71,10 @@ var fakeSuccessfulGoogleCredentials = { var fakeFailingGoogleCredentials = { getRequestMetadata: function(service_url, callback) { setTimeout(function() { - callback(new Error('Authentication failure')); + // Google credentials currently adds string error codes to auth errors + var error = new Error('Authentication failure'); + error.code = 'ENOENT'; + callback(error); }, 0); } }; From cf501a717a34d3e7af8bdfcf8e5b02710d339440 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 2 Aug 2016 14:04:52 -0700 Subject: [PATCH 123/279] Clean up cq_verifier code. --- test/core/end2end/cq_verifier.c | 52 +++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/test/core/end2end/cq_verifier.c b/test/core/end2end/cq_verifier.c index b77568058cd..c98fb6b61b2 100644 --- a/test/core/end2end/cq_verifier.c +++ b/test/core/end2end/cq_verifier.c @@ -61,7 +61,6 @@ typedef struct metadata { list to detail other expectations */ typedef struct expectation { struct expectation *next; - struct expectation *prev; grpc_completion_type type; void *tag; int success; @@ -71,17 +70,16 @@ typedef struct expectation { struct cq_verifier { /* bound completion queue */ grpc_completion_queue *cq; - /* the root/sentinal expectation */ - expectation expect; + /* expectation list */ + expectation* first_expectation; + expectation* last_expectation; }; cq_verifier *cq_verifier_create(grpc_completion_queue *cq) { cq_verifier *v = gpr_malloc(sizeof(cq_verifier)); - v->expect.type = ROOT_EXPECTATION; - v->expect.tag = NULL; - v->expect.next = &v->expect; - v->expect.prev = &v->expect; v->cq = cq; + v->first_expectation = NULL; + v->last_expectation = NULL; return v; } @@ -198,7 +196,7 @@ static void expectation_to_strvec(gpr_strvec *buf, expectation *e) { static void expectations_to_strvec(gpr_strvec *buf, cq_verifier *v) { expectation *e; - for (e = v->expect.next; e != &v->expect; e = e->next) { + for (e = v->first_expectation; e != NULL; e = e->next) { expectation_to_strvec(buf, e); gpr_strvec_add(buf, gpr_strdup("\n")); } @@ -226,30 +224,36 @@ void cq_verify(cq_verifier *v) { gpr_strvec_init(&have_tags); - while (v->expect.next != &v->expect) { + while (v->first_expectation != NULL) { ev = grpc_completion_queue_next(v->cq, deadline, NULL); if (ev.type == GRPC_QUEUE_TIMEOUT) { fail_no_event_received(v); break; } - for (e = v->expect.next; e != &v->expect; e = e->next) { + expectation* prev = NULL; + for (e = v->first_expectation; e != NULL; e = e->next) { gpr_asprintf(&s, " %p", e->tag); gpr_strvec_add(&have_tags, s); if (e->tag == ev.tag) { verify_matches(e, &ev); - e->next->prev = e->prev; - e->prev->next = e->next; + if (e == v->first_expectation) + v->first_expectation = e->next; + if (prev != NULL) + prev->next = e->next; + if (e == v->last_expectation) + v->last_expectation = prev; gpr_free(e); break; } + prev = e; } - if (e == &v->expect) { + if (e == NULL) { s = grpc_event_string(&ev); - gpr_log(GPR_ERROR, "event not found: %s", s); + gpr_log(GPR_ERROR, "cq returned unexpected event: %s", s); gpr_free(s); s = gpr_strvec_flatten(&have_tags, NULL); - gpr_log(GPR_ERROR, "have tags:%s", s); + gpr_log(GPR_ERROR, "expected tags:%s", s); gpr_free(s); gpr_strvec_destroy(&have_tags); abort(); @@ -265,7 +269,7 @@ void cq_verify_empty_timeout(cq_verifier *v, int timeout_sec) { gpr_time_from_seconds(timeout_sec, GPR_TIMESPAN)); grpc_event ev; - GPR_ASSERT(v->expect.next == &v->expect && "expectation queue must be empty"); + GPR_ASSERT(v->first_expectation == NULL && "expectation queue must be empty"); ev = grpc_completion_queue_next(v->cq, deadline, NULL); if (ev.type != GRPC_QUEUE_TIMEOUT) { @@ -278,16 +282,20 @@ void cq_verify_empty_timeout(cq_verifier *v, int timeout_sec) { void cq_verify_empty(cq_verifier *v) { cq_verify_empty_timeout(v, 1); } -static expectation *add(cq_verifier *v, grpc_completion_type type, void *tag) { +static void add(cq_verifier *v, grpc_completion_type type, void *tag, + bool success) { expectation *e = gpr_malloc(sizeof(expectation)); e->type = type; e->tag = tag; - e->next = &v->expect; - e->prev = e->next->prev; - e->next->prev = e->prev->next = e; - return e; + e->success = success; + e->next = NULL; + if (v->first_expectation == NULL) + v->first_expectation = e; + if (v->last_expectation != NULL) + v->last_expectation->next = e; + v->last_expectation = e; } void cq_expect_completion(cq_verifier *v, void *tag, bool success) { - add(v, GRPC_OP_COMPLETE, tag)->success = success; + add(v, GRPC_OP_COMPLETE, tag, success); } From 3b4f99549db1ef93b67c4fca97d1ed84c1cd0825 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 2 Aug 2016 14:17:11 -0700 Subject: [PATCH 124/279] Update destroy_call_elem args from merge. --- src/cpp/common/channel_filter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h index 6a405f567c0..b7861b40f08 100644 --- a/src/cpp/common/channel_filter.h +++ b/src/cpp/common/channel_filter.h @@ -311,7 +311,7 @@ class ChannelFilter GRPC_FINAL { static void DestroyCallElement(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - const grpc_call_stats *stats, + const grpc_call_final_info* final_info, void *and_free_memory) { reinterpret_cast(elem->call_data)->~CallDataType(); } From 7df3597eb0953f826487ed670bf0613e59542a0e Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 2 Aug 2016 14:38:00 -0700 Subject: [PATCH 125/279] Regenerate packages --- src/node/health_check/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/health_check/package.json b/src/node/health_check/package.json index 472a80b6e7f..224e4ad6ca5 100644 --- a/src/node/health_check/package.json +++ b/src/node/health_check/package.json @@ -15,7 +15,7 @@ } ], "dependencies": { - "grpc": "^1.0.0-pre1", + "grpc": "^1.0.0-pre2", "lodash": "^3.9.3", "google-protobuf": "^3.0.0" }, From d47d03f6b60d1c67d4dee0e6f2283f9cdcaf4523 Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Tue, 2 Aug 2016 15:33:41 -0700 Subject: [PATCH 126/279] corrected typo --- INSTALL.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 14be87f8782..7bdb9b273fd 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -58,8 +58,8 @@ gRPC C Core library. ##Windows -There are several way to build under Windows, of varying complexity depending on -experience with the tools involved. +There are several ways to build under Windows, of varying complexity depending +on experience with the tools involved. + +###msys2 + +This approach requires having [msys2](https://msys2.github.io/) installed. + +- The Makefile (and source code) should support msys2's mingw32 and mingw64 + compilers. Building with msys2's native compiler is also possible, but + difficult. +- The Makefile is expecting the Windows versions of OpenSSL (see + https://slproweb.com/products/Win32OpenSSL.html). It's also possible to build + the Windows version of OpenSSL from scratch. The output should be `libeay32` + and `ssleay32`. +- If you are not installing the above files under msys2's path, you may specify + it, for instance, in the following way: + ```CPPFLAGS=â€-I/c/OpenSSL-Win32/include†LDFLAGS=â€-L/c/OpenSSL-Win32/lib†make static_c``` +- [protobuf3](https://github.com/google/protobuf/blob/master/src/README.md#c-installation---windows) + must be installed on the msys2 path. + +###Cmake (experimental) + +- Install [CMake](https://cmake.org/download/). +- Run it over [grpc's + CMakeLists.txt](https://github.com/grpc/grpc/blob/master/CMakeLists.txt) to + generate "projects" for your compiler. +- Build with your compiler of choice. The generated build files should have the + protobuf3 dependency baked in. From e60ae9c9672a52b0f49b4a654a9f3704e9d7244a Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Tue, 2 Aug 2016 16:37:41 -0700 Subject: [PATCH 128/279] deflake grpclb_test --- test/cpp/grpclb/grpclb_test.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/cpp/grpclb/grpclb_test.cc b/test/cpp/grpclb/grpclb_test.cc index 1430f9de58b..b2fdce2963d 100644 --- a/test/cpp/grpclb/grpclb_test.cc +++ b/test/cpp/grpclb/grpclb_test.cc @@ -676,11 +676,12 @@ int main(int argc, char **argv) { // If the LB server waits > 2000ms, the update arrives after the first two // request are done and the third pick is performed, which returns, in RR // fashion, the 1st server of the 1st update. Therefore, the second server of - // batch 1 is hit twice, whereas the first server of batch 2 is never hit. - tf_result = grpc::test_update(2100); - GPR_ASSERT(tf_result.lb_backends[0].num_calls_serviced == 2); - GPR_ASSERT(tf_result.lb_backends[1].num_calls_serviced == 1); - GPR_ASSERT(tf_result.lb_backends[2].num_calls_serviced == 1); + // batch 1 is hit at least one, whereas the first server of batch 2 is never + // hit. + tf_result = grpc::test_update(2500); + GPR_ASSERT(tf_result.lb_backends[0].num_calls_serviced >= 1); + GPR_ASSERT(tf_result.lb_backends[1].num_calls_serviced > 0); + GPR_ASSERT(tf_result.lb_backends[2].num_calls_serviced > 0); GPR_ASSERT(tf_result.lb_backends[3].num_calls_serviced == 0); grpc_shutdown(); From b205338467a145f27e9e3b52e9d2fd14e6979780 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Mon, 25 Jul 2016 11:36:55 -0700 Subject: [PATCH 129/279] changed ix-async dependencies to System.Interactive.Async version 3.0.0 --- src/csharp/Grpc.Core.Tests/packages.config | 2 +- src/csharp/Grpc.Core/Grpc.Core.nuspec | 2 +- src/csharp/Grpc.Core/packages.config | 2 +- src/csharp/Grpc.Core/project.json | 2 +- src/csharp/Grpc.Examples.Tests/packages.config | 2 +- src/csharp/Grpc.Examples/packages.config | 2 +- src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec | 2 +- src/csharp/Grpc.HealthCheck/packages.config | 2 +- src/csharp/Grpc.IntegrationTesting/packages.config | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/packages.config b/src/csharp/Grpc.Core.Tests/packages.config index 6a930c17ee6..456ffcd8d02 100644 --- a/src/csharp/Grpc.Core.Tests/packages.config +++ b/src/csharp/Grpc.Core.Tests/packages.config @@ -1,6 +1,6 @@  - + diff --git a/src/csharp/Grpc.Core/Grpc.Core.nuspec b/src/csharp/Grpc.Core/Grpc.Core.nuspec index 543549eb2d2..a8459c4d9cd 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.nuspec +++ b/src/csharp/Grpc.Core/Grpc.Core.nuspec @@ -15,7 +15,7 @@ Copyright 2015, Google Inc. gRPC RPC Protocol HTTP/2 - + diff --git a/src/csharp/Grpc.Core/packages.config b/src/csharp/Grpc.Core/packages.config index 80daf048d0b..65147740217 100644 --- a/src/csharp/Grpc.Core/packages.config +++ b/src/csharp/Grpc.Core/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/csharp/Grpc.Core/project.json b/src/csharp/Grpc.Core/project.json index 17191849e6c..4922b8c6163 100644 --- a/src/csharp/Grpc.Core/project.json +++ b/src/csharp/Grpc.Core/project.json @@ -31,7 +31,7 @@ "xmlDoc": true }, "dependencies": { - "Ix-Async": "1.2.5" + "System.Interactive.Async": "3.0.0" }, "frameworks": { "net45": { }, diff --git a/src/csharp/Grpc.Examples.Tests/packages.config b/src/csharp/Grpc.Examples.Tests/packages.config index 668601af8e7..cc473eb34c1 100644 --- a/src/csharp/Grpc.Examples.Tests/packages.config +++ b/src/csharp/Grpc.Examples.Tests/packages.config @@ -1,7 +1,7 @@  - + \ No newline at end of file diff --git a/src/csharp/Grpc.Examples/packages.config b/src/csharp/Grpc.Examples/packages.config index a70dcbd4c68..8985ae4c772 100644 --- a/src/csharp/Grpc.Examples/packages.config +++ b/src/csharp/Grpc.Examples/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec index 7b3b391009e..4ffd18ccb21 100644 --- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec +++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec @@ -16,7 +16,7 @@ - + diff --git a/src/csharp/Grpc.HealthCheck/packages.config b/src/csharp/Grpc.HealthCheck/packages.config index a52d9e508ff..063094f7757 100644 --- a/src/csharp/Grpc.HealthCheck/packages.config +++ b/src/csharp/Grpc.HealthCheck/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/src/csharp/Grpc.IntegrationTesting/packages.config b/src/csharp/Grpc.IntegrationTesting/packages.config index 3161c5b7557..e6e64e65581 100644 --- a/src/csharp/Grpc.IntegrationTesting/packages.config +++ b/src/csharp/Grpc.IntegrationTesting/packages.config @@ -5,7 +5,7 @@ - + From 82fd31ac35c38a81b15e25d61971a9811303ee79 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Mon, 25 Jul 2016 14:25:02 -0700 Subject: [PATCH 130/279] update nuget after installing in docker --- templates/tools/dockerfile/csharp_deps.include | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/tools/dockerfile/csharp_deps.include b/templates/tools/dockerfile/csharp_deps.include index 489dc44a436..7e89dec2cc2 100644 --- a/templates/tools/dockerfile/csharp_deps.include +++ b/templates/tools/dockerfile/csharp_deps.include @@ -14,3 +14,5 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y ${'\\'} ca-certificates-mono ${'\\'} nuget ${'\\'} && apt-get clean + +RUN nuget update -self From 809292a7afc8fe8fc1f98f174c8f261b9540242a Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Mon, 25 Jul 2016 17:27:35 -0700 Subject: [PATCH 131/279] ran script to update actual docker files --- src/csharp/Grpc.Core/project.json | 2 +- tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile | 2 ++ .../stress_test/grpc_interop_stress_csharp/Dockerfile | 2 ++ tools/dockerfile/test/csharp_coreclr_x64/Dockerfile | 2 ++ tools/dockerfile/test/csharp_jessie_x64/Dockerfile | 2 ++ tools/dockerfile/test/multilang_jessie_x64/Dockerfile | 2 ++ 6 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Core/project.json b/src/csharp/Grpc.Core/project.json index 4922b8c6163..17191849e6c 100644 --- a/src/csharp/Grpc.Core/project.json +++ b/src/csharp/Grpc.Core/project.json @@ -31,7 +31,7 @@ "xmlDoc": true }, "dependencies": { - "System.Interactive.Async": "3.0.0" + "Ix-Async": "1.2.5" }, "frameworks": { "net45": { }, diff --git a/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile index 150dde4f212..da1d2c645e5 100644 --- a/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile @@ -80,6 +80,8 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ nuget \ && apt-get clean +RUN nuget update -self + # Prepare ccache RUN ln -s /usr/bin/ccache /usr/local/bin/gcc RUN ln -s /usr/bin/ccache /usr/local/bin/g++ diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile index 823fe948fb2..4bd89b70ea5 100644 --- a/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile +++ b/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile @@ -97,5 +97,7 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ nuget \ && apt-get clean +RUN nuget update -self + # Define the default command. CMD ["bash"] diff --git a/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile b/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile index 98515aa5d73..46d1a9dced7 100644 --- a/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile +++ b/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile @@ -80,6 +80,8 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ nuget \ && apt-get clean +RUN nuget update -self + # Install dotnet SDK based on https://www.microsoft.com/net/core#debian RUN apt-get update && apt-get install -y curl libunwind8 gettext diff --git a/tools/dockerfile/test/csharp_jessie_x64/Dockerfile b/tools/dockerfile/test/csharp_jessie_x64/Dockerfile index 150dde4f212..da1d2c645e5 100644 --- a/tools/dockerfile/test/csharp_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/csharp_jessie_x64/Dockerfile @@ -80,6 +80,8 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ nuget \ && apt-get clean +RUN nuget update -self + # Prepare ccache RUN ln -s /usr/bin/ccache /usr/local/bin/gcc RUN ln -s /usr/bin/ccache /usr/local/bin/g++ diff --git a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile b/tools/dockerfile/test/multilang_jessie_x64/Dockerfile index 8790b0d4797..adb554db030 100644 --- a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/multilang_jessie_x64/Dockerfile @@ -80,6 +80,8 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ nuget \ && apt-get clean +RUN nuget update -self + #================= # C++ dependencies RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev clang && apt-get clean From 77008b0338cdbe6b6d2b8e56842cf0df1572cdd6 Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Mon, 25 Jul 2016 19:18:03 -0700 Subject: [PATCH 132/279] updated hint path to updated library in csproj files --- src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj | 4 ++-- src/csharp/Grpc.Core/Grpc.Core.csproj | 4 ++-- src/csharp/Grpc.Core/project.json | 2 +- src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj | 4 ++-- src/csharp/Grpc.Examples/Grpc.Examples.csproj | 4 ++-- src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj | 4 ++-- .../Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj index f6c226567d9..d99bf8e4e19 100644 --- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj +++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj @@ -40,7 +40,7 @@ ..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll ..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll @@ -108,4 +108,4 @@ - \ No newline at end of file + diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 1952ee37121..622813fb381 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -40,7 +40,7 @@ - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll @@ -152,4 +152,4 @@ roots.pem - \ No newline at end of file + diff --git a/src/csharp/Grpc.Core/project.json b/src/csharp/Grpc.Core/project.json index 17191849e6c..4922b8c6163 100644 --- a/src/csharp/Grpc.Core/project.json +++ b/src/csharp/Grpc.Core/project.json @@ -31,7 +31,7 @@ "xmlDoc": true }, "dependencies": { - "Ix-Async": "1.2.5" + "System.Interactive.Async": "3.0.0" }, "frameworks": { "net45": { }, diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj index 4c7d89309af..c8801a94131 100644 --- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj +++ b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj @@ -43,7 +43,7 @@ ..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll ..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll @@ -75,4 +75,4 @@ - \ No newline at end of file + diff --git a/src/csharp/Grpc.Examples/Grpc.Examples.csproj b/src/csharp/Grpc.Examples/Grpc.Examples.csproj index 3dfa84e896e..4521649b6fa 100644 --- a/src/csharp/Grpc.Examples/Grpc.Examples.csproj +++ b/src/csharp/Grpc.Examples/Grpc.Examples.csproj @@ -48,7 +48,7 @@ False - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll @@ -72,4 +72,4 @@ - \ No newline at end of file + diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj index 7db8b2d38e2..e13416cc1a5 100644 --- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj +++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj @@ -46,7 +46,7 @@ False - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll @@ -82,4 +82,4 @@ --> - \ No newline at end of file + diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj index 3a0764230d6..7512d2a5d11 100644 --- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj +++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj @@ -70,7 +70,7 @@ ..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll ..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll @@ -149,4 +149,4 @@ - \ No newline at end of file + From 84f0f791e9802a44dae1424c29dde3c5a13a6538 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 27 Jul 2016 10:37:06 -0700 Subject: [PATCH 133/279] removed runtime nodes from project.json libraries --- src/csharp/Grpc.Examples.MathClient/project.json | 5 ----- src/csharp/Grpc.Examples.MathServer/project.json | 5 ----- src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json | 5 ----- src/csharp/Grpc.IntegrationTesting.StressClient/project.json | 5 ----- 4 files changed, 20 deletions(-) diff --git a/src/csharp/Grpc.Examples.MathClient/project.json b/src/csharp/Grpc.Examples.MathClient/project.json index ad319478ab0..764a335ddfb 100644 --- a/src/csharp/Grpc.Examples.MathClient/project.json +++ b/src/csharp/Grpc.Examples.MathClient/project.json @@ -42,11 +42,6 @@ } } }, - "runtimes": { - "win7-x64": { }, - "debian.8-x64": { }, - "osx.10.11-x64": { } - }, "dependencies": { "Grpc.Examples": { diff --git a/src/csharp/Grpc.Examples.MathServer/project.json b/src/csharp/Grpc.Examples.MathServer/project.json index ad319478ab0..764a335ddfb 100644 --- a/src/csharp/Grpc.Examples.MathServer/project.json +++ b/src/csharp/Grpc.Examples.MathServer/project.json @@ -42,11 +42,6 @@ } } }, - "runtimes": { - "win7-x64": { }, - "debian.8-x64": { }, - "osx.10.11-x64": { } - }, "dependencies": { "Grpc.Examples": { diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json index 287950720fe..9afcb306b40 100644 --- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json +++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json @@ -44,11 +44,6 @@ } } }, - "runtimes": { - "win7-x64": { }, - "debian.8-x64": { }, - "osx.10.11-x64": { } - }, "dependencies": { "Grpc.IntegrationTesting": { diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json index 287950720fe..9afcb306b40 100644 --- a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json +++ b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json @@ -44,11 +44,6 @@ } } }, - "runtimes": { - "win7-x64": { }, - "debian.8-x64": { }, - "osx.10.11-x64": { } - }, "dependencies": { "Grpc.IntegrationTesting": { From 86e40c6e353ec07f928a0d8c15d368f3f0c6a84b Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 27 Jul 2016 14:43:33 -0700 Subject: [PATCH 134/279] update templates to not include runtime sections in project.json --- src/csharp/Grpc.Examples/project.json | 5 +++++ templates/src/csharp/Grpc.Core/project.json.template | 2 +- .../csharp/Grpc.Examples.MathClient/project.json.template | 2 +- .../csharp/Grpc.Examples.MathServer/project.json.template | 2 +- .../Grpc.IntegrationTesting.QpsWorker/project.json.template | 2 +- .../project.json.template | 2 +- templates/src/csharp/build_options.include | 4 +++- 7 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/csharp/Grpc.Examples/project.json b/src/csharp/Grpc.Examples/project.json index 48ec530abb1..5329f390e4e 100644 --- a/src/csharp/Grpc.Examples/project.json +++ b/src/csharp/Grpc.Examples/project.json @@ -1,6 +1,11 @@ { "buildOptions": { }, + "runtimes": { + "win7-x64": { }, + "debian.8-x64": { }, + "osx.10.11-x64": { } + }, "dependencies": { "Grpc.Core": { diff --git a/templates/src/csharp/Grpc.Core/project.json.template b/templates/src/csharp/Grpc.Core/project.json.template index bd0e8b2c138..e6f8290200e 100644 --- a/templates/src/csharp/Grpc.Core/project.json.template +++ b/templates/src/csharp/Grpc.Core/project.json.template @@ -33,7 +33,7 @@ "xmlDoc": true }, "dependencies": { - "Ix-Async": "1.2.5" + "System.Interactive.Async": "3.0.0" }, "frameworks": { "net45": { }, diff --git a/templates/src/csharp/Grpc.Examples.MathClient/project.json.template b/templates/src/csharp/Grpc.Examples.MathClient/project.json.template index 67151dbcfa8..51c5e85c66d 100644 --- a/templates/src/csharp/Grpc.Examples.MathClient/project.json.template +++ b/templates/src/csharp/Grpc.Examples.MathClient/project.json.template @@ -1,7 +1,7 @@ %YAML 1.2 --- | { - <%include file="../build_options.include" args="executable=True"/> + <%include file="../build_options.include" args="executable=True,includeRuntimes=False"/> "dependencies": { "Grpc.Examples": { "target": "project" diff --git a/templates/src/csharp/Grpc.Examples.MathServer/project.json.template b/templates/src/csharp/Grpc.Examples.MathServer/project.json.template index 67151dbcfa8..51c5e85c66d 100644 --- a/templates/src/csharp/Grpc.Examples.MathServer/project.json.template +++ b/templates/src/csharp/Grpc.Examples.MathServer/project.json.template @@ -1,7 +1,7 @@ %YAML 1.2 --- | { - <%include file="../build_options.include" args="executable=True"/> + <%include file="../build_options.include" args="executable=True,includeRuntimes=False"/> "dependencies": { "Grpc.Examples": { "target": "project" diff --git a/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template index 93151f2b89e..af1ee425096 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template @@ -1,7 +1,7 @@ %YAML 1.2 --- | { - <%include file="../build_options.include" args="executable=True,includeData=True"/> + <%include file="../build_options.include" args="executable=True,includeData=True,includeRuntimes=False"/> "dependencies": { "Grpc.IntegrationTesting": { "target": "project" diff --git a/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template index 93151f2b89e..af1ee425096 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template @@ -1,7 +1,7 @@ %YAML 1.2 --- | { - <%include file="../build_options.include" args="executable=True,includeData=True"/> + <%include file="../build_options.include" args="executable=True,includeData=True,includeRuntimes=False"/> "dependencies": { "Grpc.IntegrationTesting": { "target": "project" diff --git a/templates/src/csharp/build_options.include b/templates/src/csharp/build_options.include index 169a45a808a..a200897e0f2 100644 --- a/templates/src/csharp/build_options.include +++ b/templates/src/csharp/build_options.include @@ -1,4 +1,4 @@ -<%page args="executable=False,includeData=False"/>\ +<%page args="executable=False,includeData=False,includeRuntimes=True"/>\ "buildOptions": { % if executable: "emitEntryPoint": true @@ -51,6 +51,8 @@ } } }, + %endif + % if includeRuntimes: "runtimes": { "win7-x64": { }, "debian.8-x64": { }, From d0729dba7aafa6f76f3e487121ad96afc4fef9c4 Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Thu, 28 Jul 2016 08:30:48 -0700 Subject: [PATCH 135/279] move solution dependencies to Grpc.Core.Test dependencies --- src/csharp/Grpc.Core.Tests/project.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/csharp/Grpc.Core.Tests/project.json b/src/csharp/Grpc.Core.Tests/project.json index 014e2262e9f..8112e7c9688 100644 --- a/src/csharp/Grpc.Core.Tests/project.json +++ b/src/csharp/Grpc.Core.Tests/project.json @@ -59,6 +59,7 @@ "OpenCover": "4.6.519", "ReportGenerator": "2.4.4.0" }, + "frameworks": { "net45": { }, "netcoreapp1.0": { From 2feec72c87b9196f19bc6ace469270f7f16b0b40 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 3 Aug 2016 00:04:48 -0700 Subject: [PATCH 136/279] removed blank line --- src/csharp/Grpc.Core.Tests/project.json | 1 - 1 file changed, 1 deletion(-) diff --git a/src/csharp/Grpc.Core.Tests/project.json b/src/csharp/Grpc.Core.Tests/project.json index 8112e7c9688..014e2262e9f 100644 --- a/src/csharp/Grpc.Core.Tests/project.json +++ b/src/csharp/Grpc.Core.Tests/project.json @@ -59,7 +59,6 @@ "OpenCover": "4.6.519", "ReportGenerator": "2.4.4.0" }, - "frameworks": { "net45": { }, "netcoreapp1.0": { From 5d960562931f7a332bd58cf65d380646d4efdc4f Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Wed, 3 Aug 2016 00:24:37 -0700 Subject: [PATCH 137/279] regenerated projects --- Makefile | 1 + vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj | 3 +++ .../vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters | 6 ++++++ 3 files changed, 10 insertions(+) diff --git a/Makefile b/Makefile index 2620d7c9a0f..98dabb3f3da 100644 --- a/Makefile +++ b/Makefile @@ -3154,6 +3154,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/transport/metadata.c \ src/core/lib/transport/metadata_batch.c \ src/core/lib/transport/static_metadata.c \ + src/core/lib/transport/timeout_encoding.c \ src/core/lib/transport/transport.c \ src/core/lib/transport/transport_op_string.c \ diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj index cfa29d0c02a..84a71d217d9 100644 --- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj +++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj @@ -266,6 +266,7 @@ + @@ -476,6 +477,8 @@ + + diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters index 913774d71e0..18fe9264057 100644 --- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters @@ -310,6 +310,9 @@ src\core\lib\transport + + src\core\lib\transport + src\core\lib\transport @@ -671,6 +674,9 @@ src\core\lib\transport + + src\core\lib\transport + src\core\lib\transport From 2717aea3874752153d0e526ac95728f937b1af31 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 3 Aug 2016 00:38:08 -0700 Subject: [PATCH 138/279] using temporary nuget location on windows --- tools/run_tests/pre_build_csharp.bat | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/run_tests/pre_build_csharp.bat b/tools/run_tests/pre_build_csharp.bat index 580d5638fda..0dc22b8a1fb 100644 --- a/tools/run_tests/pre_build_csharp.bat +++ b/tools/run_tests/pre_build_csharp.bat @@ -35,7 +35,8 @@ setlocal cd /d %~dp0\..\.. @rem Location of nuget.exe -set NUGET=C:\nuget\nuget.exe +@rem TODO: change this before submitting. This is only for migrating nuget +set NUGET=C:\nuget_temp\nuget.exe if exist %NUGET% ( @rem Restore Grpc packages by packages since Nuget client 3.4.4 doesnt support restore From 3df9bdf88013e4c9cb5b5f092ac7cd1aad11fa96 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Wed, 3 Aug 2016 10:48:23 -0700 Subject: [PATCH 139/279] Update generated files with new protobuf version Also make the script fetch protoc from the usual place. --- include/grpc++/ext/reflection.pb.h | 64 ++++++-- src/cpp/ext/reflection.pb.cc | 137 +++++++++++------- .../extensions/gen_reflection_proto.sh | 2 +- 3 files changed, 130 insertions(+), 73 deletions(-) diff --git a/include/grpc++/ext/reflection.pb.h b/include/grpc++/ext/reflection.pb.h index 00d07735ee8..bdb86197d03 100644 --- a/include/grpc++/ext/reflection.pb.h +++ b/include/grpc++/ext/reflection.pb.h @@ -83,7 +83,7 @@ class ServiceResponse; // =================================================================== -class ServerReflectionRequest : public ::google::protobuf::Message { +class ServerReflectionRequest : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ServerReflectionRequest) */ { public: ServerReflectionRequest(); virtual ~ServerReflectionRequest(); @@ -126,7 +126,11 @@ class ServerReflectionRequest : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -260,7 +264,7 @@ class ServerReflectionRequest : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class ExtensionRequest : public ::google::protobuf::Message { +class ExtensionRequest : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ExtensionRequest) */ { public: ExtensionRequest(); virtual ~ExtensionRequest(); @@ -294,7 +298,11 @@ class ExtensionRequest : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -350,7 +358,7 @@ class ExtensionRequest : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class ServerReflectionResponse : public ::google::protobuf::Message { +class ServerReflectionResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ServerReflectionResponse) */ { public: ServerReflectionResponse(); virtual ~ServerReflectionResponse(); @@ -392,7 +400,11 @@ class ServerReflectionResponse : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -505,7 +517,7 @@ class ServerReflectionResponse : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class FileDescriptorResponse : public ::google::protobuf::Message { +class FileDescriptorResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.FileDescriptorResponse) */ { public: FileDescriptorResponse(); virtual ~FileDescriptorResponse(); @@ -539,7 +551,11 @@ class FileDescriptorResponse : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -593,7 +609,7 @@ class FileDescriptorResponse : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class ExtensionNumberResponse : public ::google::protobuf::Message { +class ExtensionNumberResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ExtensionNumberResponse) */ { public: ExtensionNumberResponse(); virtual ~ExtensionNumberResponse(); @@ -627,7 +643,11 @@ class ExtensionNumberResponse : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -690,7 +710,7 @@ class ExtensionNumberResponse : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class ListServiceResponse : public ::google::protobuf::Message { +class ListServiceResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ListServiceResponse) */ { public: ListServiceResponse(); virtual ~ListServiceResponse(); @@ -724,7 +744,11 @@ class ListServiceResponse : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -774,7 +798,7 @@ class ListServiceResponse : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class ServiceResponse : public ::google::protobuf::Message { +class ServiceResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ServiceResponse) */ { public: ServiceResponse(); virtual ~ServiceResponse(); @@ -808,7 +832,11 @@ class ServiceResponse : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -857,7 +885,7 @@ class ServiceResponse : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class ErrorResponse : public ::google::protobuf::Message { +class ErrorResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ErrorResponse) */ { public: ErrorResponse(); virtual ~ErrorResponse(); @@ -891,7 +919,11 @@ class ErrorResponse : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); diff --git a/src/cpp/ext/reflection.pb.cc b/src/cpp/ext/reflection.pb.cc index b73a65d0a02..a84494f9a98 100644 --- a/src/cpp/ext/reflection.pb.cc +++ b/src/cpp/ext/reflection.pb.cc @@ -98,6 +98,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection* } // namespace +void protobuf_AssignDesc_reflection_2eproto() GOOGLE_ATTRIBUTE_COLD; void protobuf_AssignDesc_reflection_2eproto() { protobuf_AddDesc_reflection_2eproto(); const ::google::protobuf::FileDescriptor* file = @@ -253,6 +254,7 @@ inline void protobuf_AssignDescriptorsOnce() { &protobuf_AssignDesc_reflection_2eproto); } +void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD; void protobuf_RegisterTypes(const ::std::string&) { protobuf_AssignDescriptorsOnce(); ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( @@ -296,6 +298,7 @@ void protobuf_ShutdownFile_reflection_2eproto() { delete ErrorResponse_reflection_; } +void protobuf_AddDesc_reflection_2eproto() GOOGLE_ATTRIBUTE_COLD; void protobuf_AddDesc_reflection_2eproto() { static bool already_here = false; if (already_here) return; @@ -366,16 +369,6 @@ struct StaticDescriptorInitializer_reflection_2eproto { } } static_descriptor_initializer_reflection_2eproto_; -namespace { - -static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD; -static void MergeFromFail(int line) { - GOOGLE_CHECK(false) << __FILE__ << ":" << line; -} - -} // namespace - - // =================================================================== #if !defined(_MSC_VER) || _MSC_VER >= 1900 @@ -684,8 +677,8 @@ void ServerReflectionRequest::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ServerReflectionRequest) } -::google::protobuf::uint8* ServerReflectionRequest::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ServerReflectionRequest::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ServerReflectionRequest) // optional string host = 1; if (this->host().size() > 0) { @@ -723,8 +716,8 @@ void ServerReflectionRequest::SerializeWithCachedSizes( // optional .grpc.reflection.v1alpha.ExtensionRequest file_containing_extension = 5; if (has_file_containing_extension()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 5, *message_request_.file_containing_extension_, target); + InternalWriteMessageNoVirtualToArray( + 5, *message_request_.file_containing_extension_, false, target); } // optional string all_extension_numbers_of_type = 6; @@ -812,7 +805,9 @@ int ServerReflectionRequest::ByteSize() const { void ServerReflectionRequest::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ServerReflectionRequest) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ServerReflectionRequest* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -827,7 +822,9 @@ void ServerReflectionRequest::MergeFrom(const ::google::protobuf::Message& from) void ServerReflectionRequest::MergeFrom(const ServerReflectionRequest& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ServerReflectionRequest) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } switch (from.message_request_case()) { case kFileByFilename: { set_file_by_filename(from.file_by_filename()); @@ -1486,8 +1483,8 @@ void ExtensionRequest::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ExtensionRequest) } -::google::protobuf::uint8* ExtensionRequest::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ExtensionRequest::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ExtensionRequest) // optional string containing_type = 1; if (this->containing_type().size() > 0) { @@ -1535,7 +1532,9 @@ int ExtensionRequest::ByteSize() const { void ExtensionRequest::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ExtensionRequest) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ExtensionRequest* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -1550,7 +1549,9 @@ void ExtensionRequest::MergeFrom(const ::google::protobuf::Message& from) { void ExtensionRequest::MergeFrom(const ExtensionRequest& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ExtensionRequest) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } if (from.containing_type().size() > 0) { containing_type_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.containing_type_); @@ -1937,8 +1938,8 @@ void ServerReflectionResponse::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ServerReflectionResponse) } -::google::protobuf::uint8* ServerReflectionResponse::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ServerReflectionResponse::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ServerReflectionResponse) // optional string valid_host = 1; if (this->valid_host().size() > 0) { @@ -1954,36 +1955,36 @@ void ServerReflectionResponse::SerializeWithCachedSizes( // optional .grpc.reflection.v1alpha.ServerReflectionRequest original_request = 2; if (this->has_original_request()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 2, *this->original_request_, target); + InternalWriteMessageNoVirtualToArray( + 2, *this->original_request_, false, target); } // optional .grpc.reflection.v1alpha.FileDescriptorResponse file_descriptor_response = 4; if (has_file_descriptor_response()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 4, *message_response_.file_descriptor_response_, target); + InternalWriteMessageNoVirtualToArray( + 4, *message_response_.file_descriptor_response_, false, target); } // optional .grpc.reflection.v1alpha.ExtensionNumberResponse all_extension_numbers_response = 5; if (has_all_extension_numbers_response()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 5, *message_response_.all_extension_numbers_response_, target); + InternalWriteMessageNoVirtualToArray( + 5, *message_response_.all_extension_numbers_response_, false, target); } // optional .grpc.reflection.v1alpha.ListServiceResponse list_services_response = 6; if (has_list_services_response()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 6, *message_response_.list_services_response_, target); + InternalWriteMessageNoVirtualToArray( + 6, *message_response_.list_services_response_, false, target); } // optional .grpc.reflection.v1alpha.ErrorResponse error_response = 7; if (has_error_response()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 7, *message_response_.error_response_, target); + InternalWriteMessageNoVirtualToArray( + 7, *message_response_.error_response_, false, target); } // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.ServerReflectionResponse) @@ -2049,7 +2050,9 @@ int ServerReflectionResponse::ByteSize() const { void ServerReflectionResponse::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ServerReflectionResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ServerReflectionResponse* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -2064,7 +2067,9 @@ void ServerReflectionResponse::MergeFrom(const ::google::protobuf::Message& from void ServerReflectionResponse::MergeFrom(const ServerReflectionResponse& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ServerReflectionResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } switch (from.message_response_case()) { case kFileDescriptorResponse: { mutable_file_descriptor_response()->::grpc::reflection::v1alpha::FileDescriptorResponse::MergeFrom(from.file_descriptor_response()); @@ -2550,8 +2555,8 @@ void FileDescriptorResponse::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.FileDescriptorResponse) } -::google::protobuf::uint8* FileDescriptorResponse::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* FileDescriptorResponse::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.FileDescriptorResponse) // repeated bytes file_descriptor_proto = 1; for (int i = 0; i < this->file_descriptor_proto_size(); i++) { @@ -2582,7 +2587,9 @@ int FileDescriptorResponse::ByteSize() const { void FileDescriptorResponse::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.FileDescriptorResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const FileDescriptorResponse* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -2597,7 +2604,9 @@ void FileDescriptorResponse::MergeFrom(const ::google::protobuf::Message& from) void FileDescriptorResponse::MergeFrom(const FileDescriptorResponse& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.FileDescriptorResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } file_descriptor_proto_.MergeFrom(from.file_descriptor_proto_); } @@ -2863,8 +2872,8 @@ void ExtensionNumberResponse::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ExtensionNumberResponse) } -::google::protobuf::uint8* ExtensionNumberResponse::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ExtensionNumberResponse::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ExtensionNumberResponse) // optional string base_type_name = 1; if (this->base_type_name().size() > 0) { @@ -2931,7 +2940,9 @@ int ExtensionNumberResponse::ByteSize() const { void ExtensionNumberResponse::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ExtensionNumberResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ExtensionNumberResponse* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -2946,7 +2957,9 @@ void ExtensionNumberResponse::MergeFrom(const ::google::protobuf::Message& from) void ExtensionNumberResponse::MergeFrom(const ExtensionNumberResponse& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ExtensionNumberResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } extension_number_.MergeFrom(from.extension_number_); if (from.base_type_name().size() > 0) { @@ -3199,14 +3212,14 @@ void ListServiceResponse::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ListServiceResponse) } -::google::protobuf::uint8* ListServiceResponse::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ListServiceResponse::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ListServiceResponse) // repeated .grpc.reflection.v1alpha.ServiceResponse service = 1; for (unsigned int i = 0, n = this->service_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 1, this->service(i), target); + InternalWriteMessageNoVirtualToArray( + 1, this->service(i), false, target); } // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.ListServiceResponse) @@ -3233,7 +3246,9 @@ int ListServiceResponse::ByteSize() const { void ListServiceResponse::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ListServiceResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ListServiceResponse* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -3248,7 +3263,9 @@ void ListServiceResponse::MergeFrom(const ::google::protobuf::Message& from) { void ListServiceResponse::MergeFrom(const ListServiceResponse& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ListServiceResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } service_.MergeFrom(from.service_); } @@ -3459,8 +3476,8 @@ void ServiceResponse::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ServiceResponse) } -::google::protobuf::uint8* ServiceResponse::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ServiceResponse::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ServiceResponse) // optional string name = 1; if (this->name().size() > 0) { @@ -3496,7 +3513,9 @@ int ServiceResponse::ByteSize() const { void ServiceResponse::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ServiceResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ServiceResponse* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -3511,7 +3530,9 @@ void ServiceResponse::MergeFrom(const ::google::protobuf::Message& from) { void ServiceResponse::MergeFrom(const ServiceResponse& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ServiceResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } if (from.name().size() > 0) { name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); @@ -3762,8 +3783,8 @@ void ErrorResponse::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ErrorResponse) } -::google::protobuf::uint8* ErrorResponse::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ErrorResponse::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ErrorResponse) // optional int32 error_code = 1; if (this->error_code() != 0) { @@ -3811,7 +3832,9 @@ int ErrorResponse::ByteSize() const { void ErrorResponse::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ErrorResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ErrorResponse* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -3826,7 +3849,9 @@ void ErrorResponse::MergeFrom(const ::google::protobuf::Message& from) { void ErrorResponse::MergeFrom(const ErrorResponse& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ErrorResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } if (from.error_code() != 0) { set_error_code(from.error_code()); } diff --git a/tools/codegen/extensions/gen_reflection_proto.sh b/tools/codegen/extensions/gen_reflection_proto.sh index 45a1a9f4ec1..bd8aac6a7b1 100755 --- a/tools/codegen/extensions/gen_reflection_proto.sh +++ b/tools/codegen/extensions/gen_reflection_proto.sh @@ -36,7 +36,7 @@ SRC_DIR="src/cpp/ext" INCLUDE_DIR="grpc++/ext" TMP_DIR="tmp" GRPC_PLUGIN="bins/opt/grpc_cpp_plugin" -PROTOC=third_party/protobuf/src/protoc +PROTOC="bins/opt/protobuf/protoc" set -e From 00e9c3bb3bfd6ef556dbee92ba982ea71238af40 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 3 Aug 2016 10:48:30 -0700 Subject: [PATCH 140/279] clang-format --- src/cpp/common/channel_filter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h index b7861b40f08..3fbacd824c9 100644 --- a/src/cpp/common/channel_filter.h +++ b/src/cpp/common/channel_filter.h @@ -311,7 +311,7 @@ class ChannelFilter GRPC_FINAL { static void DestroyCallElement(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - const grpc_call_final_info* final_info, + const grpc_call_final_info *final_info, void *and_free_memory) { reinterpret_cast(elem->call_data)->~CallDataType(); } From e5fd01a3892de022769615832266c24d4cc7bea4 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Tue, 2 Aug 2016 12:06:21 -0700 Subject: [PATCH 141/279] Bump python protobuf dependency to 3.0.0 --- requirements.txt | 4 ++-- setup.py | 2 +- src/python/grpcio_health_checking/setup.py | 1 + src/python/grpcio_tests/setup.py | 2 +- tools/distrib/python/grpcio_tools/setup.py | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/requirements.txt b/requirements.txt index 0ec0e75b762..bf87de07f89 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,6 @@ coverage>=4.0 cython>=0.23 enum34>=1.0.4 futures>=2.2.0 -protobuf>=3.0.0a3 +protobuf>=3.0.0 six>=1.10 -wheel>=0.29 \ No newline at end of file +wheel>=0.29 diff --git a/setup.py b/setup.py index b43ec9ae3d4..1dddf55e5e8 100644 --- a/setup.py +++ b/setup.py @@ -189,7 +189,7 @@ INSTALL_REQUIRES = ( 'futures>=2.2.0', # TODO(atash): eventually split the grpcio package into a metapackage # depending on protobuf and the runtime component (independent of protobuf) - 'protobuf>=3.0.0a3', + 'protobuf>=3.0.0', ) SETUP_REQUIRES = INSTALL_REQUIRES + ( diff --git a/src/python/grpcio_health_checking/setup.py b/src/python/grpcio_health_checking/setup.py index 727d6288853..6074175a449 100644 --- a/src/python/grpcio_health_checking/setup.py +++ b/src/python/grpcio_health_checking/setup.py @@ -50,6 +50,7 @@ SETUP_REQUIRES = ( ) INSTALL_REQUIRES = ( + 'protobuf>=3.0.0', 'grpcio>=0.15.0', ) diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py index 0afaf7dfa21..5c60eaca3a3 100644 --- a/src/python/grpcio_tests/setup.py +++ b/src/python/grpcio_tests/setup.py @@ -63,7 +63,7 @@ INSTALL_REQUIRES = ( 'grpcio>=0.14.0', 'grpcio-health-checking>=0.14.0', 'oauth2client>=1.4.7', - 'protobuf>=3.0.0a3', + 'protobuf>=3.0.0', 'six>=1.10', ) diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py index 8082c7a665a..43d0f5518a8 100644 --- a/tools/distrib/python/grpcio_tools/setup.py +++ b/tools/distrib/python/grpcio_tools/setup.py @@ -148,7 +148,7 @@ setuptools.setup( packages=setuptools.find_packages('.'), namespace_packages=['grpc'], install_requires=[ - 'protobuf>=3.0.0a3', + 'protobuf>=3.0.0', 'grpcio>=0.15.0', ], package_data=package_data(), From de84d566b8fad6808e5263a25a17fa231cb5713c Mon Sep 17 00:00:00 2001 From: siddharthshukla Date: Wed, 3 Aug 2016 17:55:10 +0200 Subject: [PATCH 142/279] Fix the ThreadPoolExecutor: max_workers can't be 0 Add a RecordingThreadPool that inherits from Executor, contains a ThreadPoolExecutor and has an extra method 'was_used' to indicate if submit method was ever called i.e. if the thread pool was ever used. --- .../tests/unit/_channel_connectivity_test.py | 10 ++-- .../tests/unit/_channel_ready_future_test.py | 6 ++- .../grpcio_tests/tests/unit/_thread_pool.py | 48 +++++++++++++++++++ 3 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 src/python/grpcio_tests/tests/unit/_thread_pool.py diff --git a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py index 3c00f686cec..9cae96a00d8 100644 --- a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py +++ b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py @@ -32,12 +32,12 @@ import threading import time import unittest -from concurrent import futures import grpc from grpc import _channel from grpc import _server from tests.unit.framework.common import test_constants +from tests.unit import _thread_pool def _ready_in_connectivities(connectivities): @@ -104,7 +104,8 @@ class ChannelConnectivityTest(unittest.TestCase): grpc.ChannelConnectivity.READY, fifth_connectivities) def test_immediately_connectable_channel_connectivity(self): - server = _server.Server(futures.ThreadPoolExecutor(max_workers=0), ()) + thread_pool = _thread_pool.RecordingThreadPool(max_workers=None) + server = _server.Server(thread_pool, ()) port = server.add_insecure_port('[::]:0') server.start() first_callback = _Callback() @@ -141,9 +142,11 @@ class ChannelConnectivityTest(unittest.TestCase): fourth_connectivities) self.assertNotIn( grpc.ChannelConnectivity.SHUTDOWN, fourth_connectivities) + self.assertFalse(thread_pool.was_used()) def test_reachable_then_unreachable_channel_connectivity(self): - server = _server.Server(futures.ThreadPoolExecutor(max_workers=0), ()) + thread_pool = _thread_pool.RecordingThreadPool(max_workers=None) + server = _server.Server(thread_pool, ()) port = server.add_insecure_port('[::]:0') server.start() callback = _Callback() @@ -155,6 +158,7 @@ class ChannelConnectivityTest(unittest.TestCase): server.stop(None) callback.block_until_connectivities_satisfy(_last_connectivity_is_not_ready) channel.unsubscribe(callback.update) + self.assertFalse(thread_pool.was_used()) if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py index e8982ed2ded..24f5b45b18e 100644 --- a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py +++ b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py @@ -31,12 +31,12 @@ import threading import unittest -from concurrent import futures import grpc from grpc import _channel from grpc import _server from tests.unit.framework.common import test_constants +from tests.unit import _thread_pool class _Callback(object): @@ -78,7 +78,8 @@ class ChannelReadyFutureTest(unittest.TestCase): self.assertFalse(ready_future.running()) def test_immediately_connectable_channel_connectivity(self): - server = _server.Server(futures.ThreadPoolExecutor(max_workers=0), ()) + thread_pool = _thread_pool.RecordingThreadPool(max_workers=None) + server = _server.Server(thread_pool, ()) port = server.add_insecure_port('[::]:0') server.start() channel = grpc.insecure_channel('localhost:{}'.format(port)) @@ -97,6 +98,7 @@ class ChannelReadyFutureTest(unittest.TestCase): self.assertFalse(ready_future.cancelled()) self.assertTrue(ready_future.done()) self.assertFalse(ready_future.running()) + self.assertFalse(thread_pool.was_used()) if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/unit/_thread_pool.py b/src/python/grpcio_tests/tests/unit/_thread_pool.py new file mode 100644 index 00000000000..f13cc2f86fc --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_thread_pool.py @@ -0,0 +1,48 @@ +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import threading +from concurrent import futures + + +class RecordingThreadPool(futures.Executor): + """A thread pool that records if used.""" + def __init__(self, max_workers): + self._tp_executor = futures.ThreadPoolExecutor(max_workers=max_workers) + self._lock = threading.Lock() + self._was_used = False + + def submit(self, fn, *args, **kwargs): + with self._lock: + self._was_used = True + self._tp_executor.submit(fn, *args, **kwargs) + + def was_used(self): + with self._lock: + return self._was_used From 5af33e925aed6b9fcaae4d5d1573ce561ebe11ed Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Thu, 4 Aug 2016 00:35:55 +0200 Subject: [PATCH 143/279] Forgot one file --- .../interop_server_lib.vcxproj | 212 ++++++++++++++++++ .../interop_server_lib.vcxproj.filters | 42 ++++ 2 files changed, 254 insertions(+) create mode 100644 vsprojects/vcxproj/interop_server_lib/interop_server_lib.vcxproj create mode 100644 vsprojects/vcxproj/interop_server_lib/interop_server_lib.vcxproj.filters diff --git a/vsprojects/vcxproj/interop_server_lib/interop_server_lib.vcxproj b/vsprojects/vcxproj/interop_server_lib/interop_server_lib.vcxproj new file mode 100644 index 00000000000..204d3f770b4 --- /dev/null +++ b/vsprojects/vcxproj/interop_server_lib/interop_server_lib.vcxproj @@ -0,0 +1,212 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {458DCA09-83B9-5E68-D7E9-118864ECBD94} + true + $(SolutionDir)IntDir\$(MSBuildProjectName)\ + + + + v100 + + + v110 + + + v120 + + + v140 + + + StaticLibrary + true + Unicode + + + StaticLibrary + false + true + Unicode + + + + + + + + + + + + interop_server_lib + + + interop_server_lib + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Windows + true + false + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Windows + true + false + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Windows + true + false + true + true + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Windows + true + false + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {F55BEA2C-B61D-AAFE-CA15-223B8AC0DE5A} + + + {0BE77741-552A-929B-A497-4EF7ECE17A64} + + + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} + + + {C187A093-A0FE-489D-A40A-6E33DE0F9FEB} + + + {29D16885-7228-4C31-81ED-5F9187C7F2A9} + + + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + + + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + + + {3F7D093D-11F9-C4BC-BEB7-18EB28E3F290} + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + diff --git a/vsprojects/vcxproj/interop_server_lib/interop_server_lib.vcxproj.filters b/vsprojects/vcxproj/interop_server_lib/interop_server_lib.vcxproj.filters new file mode 100644 index 00000000000..63fc0f7f515 --- /dev/null +++ b/vsprojects/vcxproj/interop_server_lib/interop_server_lib.vcxproj.filters @@ -0,0 +1,42 @@ + + + + + src\proto\grpc\testing + + + src\proto\grpc\testing + + + src\proto\grpc\testing + + + test\cpp\interop + + + + + + {356c90d7-2dcd-5f6a-d3ca-6461f2597581} + + + {70740334-0cbf-ab29-0e1c-f0ffa390d77f} + + + {d581eb6c-94b6-eb79-6b76-d122c13cff3c} + + + {27f43e87-cfd9-68cc-179a-fc44046797c4} + + + {3402c01e-a9f6-2dd8-6963-03a5774d37f2} + + + {656eed4b-782e-224c-6101-8a61c2daa94e} + + + {61c0dab5-5c69-82b0-2961-4104445f2e06} + + + + From e8f088e5224e73645d4b97bbd972170574b9a53b Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Wed, 3 Aug 2016 15:37:56 -0700 Subject: [PATCH 144/279] Remove obsolete template notices in podspecs --- gRPC-ProtoRPC.podspec | 6 ------ gRPC-RxLibrary.podspec | 6 ------ gRPC.podspec | 6 ------ 3 files changed, 18 deletions(-) diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index b75be448ef2..f3a83430419 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -1,9 +1,3 @@ -# GRPC CocoaPods podspec -# This file has been automatically generated from a template file. -# Please look at the templates directory instead. -# This file can be regenerated from the template by running -# tools/buildgen/generate_projects.sh - # Copyright 2015, Google Inc. # All rights reserved. # diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 862ed8974ba..9936d52df55 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -1,9 +1,3 @@ -# GRPC CocoaPods podspec -# This file has been automatically generated from a template file. -# Please look at the templates directory instead. -# This file can be regenerated from the template by running -# tools/buildgen/generate_projects.sh - # Copyright 2015, Google Inc. # All rights reserved. # diff --git a/gRPC.podspec b/gRPC.podspec index eda965a3280..3f6da3b141d 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -1,9 +1,3 @@ -# GRPC CocoaPods podspec -# This file has been automatically generated from a template file. -# Please look at the templates directory instead. -# This file can be regenerated from the template by running -# tools/buildgen/generate_projects.sh - # Copyright 2015, Google Inc. # All rights reserved. # From cc3ecd104f0c4aafbd005d2855049468dbf35236 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Wed, 3 Aug 2016 15:39:16 -0700 Subject: [PATCH 145/279] Point out what to do if the sanity check fails --- tools/distrib/check_generated_pb_files.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/distrib/check_generated_pb_files.sh b/tools/distrib/check_generated_pb_files.sh index 557067883c5..6b93895484c 100755 --- a/tools/distrib/check_generated_pb_files.sh +++ b/tools/distrib/check_generated_pb_files.sh @@ -38,3 +38,6 @@ docker build -t grpc_check_generated_pb_files tools/dockerfile/grpc_check_genera # run check_pb_files against the checked out codebase docker run -e TEST=$TEST --rm=true -v ${HOST_GIT_ROOT:-`pwd`}:/var/local/jenkins/grpc -t grpc_check_generated_pb_files /var/local/jenkins/grpc/tools/dockerfile/grpc_check_generated_pb_files/check_pb_files.sh + +# If the test fails, please make sure your protobuf submodule is up-to-date and run +# tools/codegen/extensions/gen_reflection_proto.sh to update the generated files. From 82afcaa009e85cba16422b94a23387a3b7a0bd06 Mon Sep 17 00:00:00 2001 From: chedeti Date: Wed, 3 Aug 2016 16:38:05 -0700 Subject: [PATCH 146/279] rename class variables to snake_case --- .../grpc++/impl/codegen/thrift_serializer.h | 94 ++++++++++--------- include/grpc++/impl/codegen/thrift_utils.h | 21 ++--- tools/grift/Dockerfile | 4 +- tools/grift/README.md | 2 +- tools/grift/grpc_plugins_generator.patch | 91 +++++++++--------- 5 files changed, 110 insertions(+), 102 deletions(-) diff --git a/include/grpc++/impl/codegen/thrift_serializer.h b/include/grpc++/impl/codegen/thrift_serializer.h index 46112ee5b23..04dcc699deb 100644 --- a/include/grpc++/impl/codegen/thrift_serializer.h +++ b/include/grpc++/impl/codegen/thrift_serializer.h @@ -31,12 +31,9 @@ * */ - #ifndef GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H - #define GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H +#ifndef GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H +#define GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H -#include -#include -#include #include #include #include @@ -46,6 +43,10 @@ #include #include #include +#include +#include +#include +#include namespace apache { namespace thrift { @@ -59,20 +60,22 @@ using apache::thrift::transport::TMemoryBuffer; using apache::thrift::transport::TBufferBase; using apache::thrift::transport::TTransport; -template class ThriftSerializer { -public: +template +class ThriftSerializer { + public: ThriftSerializer() - : prepared_ (false) - , last_deserialized_ (false) - , serialize_version_ (false) {} + : prepared_(false), + last_deserialized_(false), + serialize_version_(false) {} virtual ~ThriftSerializer() {} // Serialize the passed type into the internal buffer // and returns a pointer to internal buffer and its size - template void Serialize(const T& fields, const uint8_t** serializedBuffer, - size_t* serializedLen) { - // prepare or reset buffer + template + void Serialize(const T& fields, const uint8_t** serialized_buffer, + size_t* serialized_len) { + // prepare or reset buffer if (!prepared_ || last_deserialized_) { prepare(); } else { @@ -85,7 +88,7 @@ public: protocol_->writeMessageBegin("", TMessageType(0), 0); } - // serilaize fields into buffer + // serialize fields into buffer fields.write(protocol_.get()); // write the end of message @@ -93,22 +96,23 @@ public: protocol_->writeMessageEnd(); } - uint8_t* byteBuffer; - uint32_t byteBufferSize; - buffer_->getBuffer(&byteBuffer, &byteBufferSize); - *serializedBuffer = byteBuffer; - *serializedLen = byteBufferSize; + uint8_t* byte_buffer; + uint32_t byte_buffer_size; + buffer_->getBuffer(&byte_buffer, &byte_buffer_size); + *serialized_buffer = byte_buffer; + *serialized_len = byte_buffer_size; } // Serialize the passed type into the byte buffer - template void Serialize(const T& fields, grpc_byte_buffer** bp) { + template + void Serialize(const T& fields, grpc_byte_buffer** bp) { + const uint8_t* byte_buffer; + size_t byte_buffer_size; - const uint8_t* byteBuffer; - size_t byteBufferSize; + Serialize(fields, &byte_buffer, &byte_buffer_size); - Serialize(fields, &byteBuffer, &byteBufferSize); - - gpr_slice slice = gpr_slice_from_copied_buffer((char*)byteBuffer,byteBufferSize); + gpr_slice slice = + gpr_slice_from_copied_buffer((char*)byte_buffer, byte_buffer_size); *bp = grpc_raw_byte_buffer_create(&slice, 1); @@ -117,21 +121,22 @@ public: // Deserialize the passed char array into the passed type, returns the number // of bytes that have been consumed from the passed string. - template uint32_t Deserialize(const uint8_t* serializedBuffer, size_t length, - T* fields) { + template + uint32_t Deserialize(const uint8_t* serialized_buffer, size_t length, + T* fields) { // prepare buffer if necessary if (!prepared_) { prepare(); } last_deserialized_ = true; - //reset buffer transport - buffer_->resetBuffer((uint8_t*)serializedBuffer, length); + // reset buffer transport + buffer_->resetBuffer((uint8_t*)serialized_buffer, length); // read the protocol version if necessary if (serialize_version_) { std::string name = ""; - TMessageType mt = (TMessageType) 0; + TMessageType mt = (TMessageType)0; int32_t seq_id = 0; protocol_->readMessageBegin(name, mt, seq_id); } @@ -147,17 +152,17 @@ public: return len; } - // Deserialize the passed byte buffer to passed type, returns the number // of bytes consumed from byte buffer - template uint32_t Deserialize(grpc_byte_buffer* buffer, T* msg) { - + template + uint32_t Deserialize(grpc_byte_buffer* buffer, T* msg) { grpc_byte_buffer_reader reader; grpc_byte_buffer_reader_init(&reader, buffer); gpr_slice slice = grpc_byte_buffer_reader_readall(&reader); - uint32_t len = Deserialize(GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice), msg); + uint32_t len = + Deserialize(GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice), msg); gpr_slice_unref(slice); @@ -167,9 +172,7 @@ public: } // set serialization version flag - void SetSerializeVersion(bool value) { - serialize_version_ = value; - } + void SetSerializeVersion(bool value) { serialize_version_ = value; } // Set the container size limit to deserialize // This function should be called after buffer_ is initialized @@ -189,7 +192,7 @@ public: protocol_->setStringSizeLimit(string_limit); } -private: + private: bool prepared_; bool last_deserialized_; boost::shared_ptr buffer_; @@ -197,6 +200,7 @@ private: bool serialize_version_; void prepare() { + buffer_.reset(new TMemoryBuffer()); // create a protocol for the memory buffer transport @@ -205,13 +209,15 @@ private: prepared_ = true; } -}; // ThriftSerializer +}; // ThriftSerializer -typedef ThriftSerializer> ThriftSerializerBinary; -typedef ThriftSerializer> ThriftSerializerCompact; +typedef ThriftSerializer> + ThriftSerializerBinary; +typedef ThriftSerializer> + ThriftSerializerCompact; -} // namespace util -} // namespace thrift -} // namespace apache +} // namespace util +} // namespace thrift +} // namespace apache #endif \ No newline at end of file diff --git a/include/grpc++/impl/codegen/thrift_utils.h b/include/grpc++/impl/codegen/thrift_utils.h index 14332c05219..7d19b247f4c 100644 --- a/include/grpc++/impl/codegen/thrift_utils.h +++ b/include/grpc++/impl/codegen/thrift_utils.h @@ -34,16 +34,16 @@ #ifndef GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H #define GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H -#include -#include -#include -#include #include #include #include #include #include #include +#include +#include +#include +#include #include #include @@ -52,23 +52,20 @@ namespace grpc { using apache::thrift::util::ThriftSerializerCompact; template -class SerializationTraits::value>::type> { +class SerializationTraits::value>::type> { public: - - static Status Serialize(const T& msg, - grpc_byte_buffer** bp, bool* own_buffer) { - + static Status Serialize(const T& msg, grpc_byte_buffer** bp, + bool* own_buffer) { *own_buffer = true; ThriftSerializerCompact serializer; - serializer.Serialize(msg, bp); return Status(StatusCode::OK, "ok"); } - static Status Deserialize(grpc_byte_buffer* buffer, - T* msg, + static Status Deserialize(grpc_byte_buffer* buffer, T* msg, int max_message_size) { if (!buffer) { return Status(StatusCode::INTERNAL, "No payload"); diff --git a/tools/grift/Dockerfile b/tools/grift/Dockerfile index 5238010ea92..954640f0df0 100644 --- a/tools/grift/Dockerfile +++ b/tools/grift/Dockerfile @@ -46,8 +46,8 @@ RUN apt-get update && \ curl make automake libtool # Configure git -RUN git config --global user.name " " && \ - git config --global user.email " " +RUN git config --global user.name "Jenkins" && \ + git config --global user.email "jenkins@grpc" RUN git clone https://github.com/grpc/grpc diff --git a/tools/grift/README.md b/tools/grift/README.md index 25c67451326..2525f9b83dd 100644 --- a/tools/grift/README.md +++ b/tools/grift/README.md @@ -2,7 +2,7 @@ Copyright 2016 Google Inc. #Documentation -grift is integration of [Apache Thrift](https://github.com/apache/thrift.git) Serializer with GRPC. +grift is integration of [Apache Thrift](https://github.com/apache/thrift.git) Serializer with gRPC. This integration allows you to use grpc to send thrift messages in C++ and java. diff --git a/tools/grift/grpc_plugins_generator.patch b/tools/grift/grpc_plugins_generator.patch index 3a6710c224e..a1d4cecde04 100644 --- a/tools/grift/grpc_plugins_generator.patch +++ b/tools/grift/grpc_plugins_generator.patch @@ -59,7 +59,7 @@ index 6fd15d2..7de1fad 100755 2.8.0.rc3.226.g39d4020 -From c8577ad5513543c57a81ad1bf4927cc8a78baa03 Mon Sep 17 00:00:00 2001 +From e724d3abf096278615085bd58217321e32b43fd8 Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 16:16:40 -0700 Subject: [PATCH 2/3] grpc cpp plugins generator with example @@ -69,16 +69,16 @@ Subject: [PATCH 2/3] grpc cpp plugins generator with example tutorial/cpp/CMakeLists.txt | 53 --- tutorial/cpp/CppClient.cpp | 80 ----- tutorial/cpp/CppServer.cpp | 181 ---------- - tutorial/cpp/GrpcClient.cpp | 94 ++++++ - tutorial/cpp/GrpcServer.cpp | 87 +++++ + tutorial/cpp/GriftClient.cpp | 93 ++++++ + tutorial/cpp/GriftServer.cpp | 93 ++++++ tutorial/cpp/Makefile.am | 66 ++-- tutorial/cpp/test.thrift | 13 + - 8 files changed, 636 insertions(+), 416 deletions(-) + 8 files changed, 641 insertions(+), 416 deletions(-) delete mode 100644 tutorial/cpp/CMakeLists.txt delete mode 100644 tutorial/cpp/CppClient.cpp delete mode 100644 tutorial/cpp/CppServer.cpp - create mode 100644 tutorial/cpp/GrpcClient.cpp - create mode 100644 tutorial/cpp/GrpcServer.cpp + create mode 100644 tutorial/cpp/GriftClient.cpp + create mode 100644 tutorial/cpp/GriftServer.cpp create mode 100644 tutorial/cpp/test.thrift diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc @@ -1147,12 +1147,12 @@ index eafffa9..0000000 - cout << "Done." << endl; - return 0; -} -diff --git a/tutorial/cpp/GrpcClient.cpp b/tutorial/cpp/GrpcClient.cpp +diff --git a/tutorial/cpp/GriftClient.cpp b/tutorial/cpp/GriftClient.cpp new file mode 100644 -index 0000000..ab1fe77 +index 0000000..647a683 --- /dev/null -+++ b/tutorial/cpp/GrpcClient.cpp -@@ -0,0 +1,94 @@ ++++ b/tutorial/cpp/GriftClient.cpp +@@ -0,0 +1,93 @@ +/* + * + * Copyright 2016, Google Inc. @@ -1198,7 +1198,6 @@ index 0000000..ab1fe77 +using grpc::ClientContext; +using grpc::Status; +using test::Greeter; -+using namespace test; + +class GreeterClient { + public: @@ -1247,12 +1246,12 @@ index 0000000..ab1fe77 + + return 0; +} -diff --git a/tutorial/cpp/GrpcServer.cpp b/tutorial/cpp/GrpcServer.cpp +diff --git a/tutorial/cpp/GriftServer.cpp b/tutorial/cpp/GriftServer.cpp new file mode 100644 -index 0000000..f63db57 +index 0000000..7c01606 --- /dev/null -+++ b/tutorial/cpp/GrpcServer.cpp -@@ -0,0 +1,87 @@ ++++ b/tutorial/cpp/GriftServer.cpp +@@ -0,0 +1,93 @@ +/* + * + * Copyright 2016, Google Inc. @@ -1301,11 +1300,14 @@ index 0000000..f63db57 +using grpc::Status; +using test::Greeter; + -+using namespace grpc; -+using namespace test; -+ +// Logic and data behind the server's behavior. +class GreeterServiceImpl final : public Greeter::Service { ++ public: ++ ~GreeterServiceImpl() { ++ // shutdown server ++ server->Shutdown(); ++ } ++ + Status SayHello(ServerContext* context,const Greeter::SayHelloReq* request, + Greeter::SayHelloResp* reply) override { + std::string prefix("Hello "); @@ -1314,34 +1316,37 @@ index 0000000..f63db57 + + return Status::OK; + } -+}; + -+void RunServer() { -+ std::string server_address("0.0.0.0:50051"); -+ GreeterServiceImpl service; ++ void RunServer() { ++ std::string server_address("0.0.0.0:50051"); ++ ++ ServerBuilder builder; ++ // Listen on the given address without any authentication mechanism. ++ builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); ++ // Register "service" as the instance through which we'll communicate with ++ // clients. In this case it corresponds to an *synchronous* service. ++ builder.RegisterService(this); ++ // Finally assemble the server. ++ server = builder.BuildAndStart(); ++ std::cout << "Server listening on " << server_address << std::endl; ++ ++ // Wait for the server to shutdown. Note that some other thread must be ++ // responsible for shutting down the server for this call to ever return. ++ server->Wait(); ++ } + -+ ServerBuilder builder; -+ // Listen on the given address without any authentication mechanism. -+ builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); -+ // Register "service" as the instance through which we'll communicate with -+ // clients. In this case it corresponds to an *synchronous* service. -+ builder.RegisterService(&service); -+ // Finally assemble the server. -+ std::unique_ptr server(builder.BuildAndStart()); -+ std::cout << "Server listening on " << server_address << std::endl; -+ -+ // Wait for the server to shutdown. Note that some other thread must be -+ // responsible for shutting down the server for this call to ever return. -+ server->Wait(); -+} ++ private: ++ std::unique_ptr server; ++}; + +int main() { -+ RunServer(); ++ GreeterServiceImpl service; ++ service.RunServer(); + + return 0; +} diff --git a/tutorial/cpp/Makefile.am b/tutorial/cpp/Makefile.am -index 184a69d..39d85e1 100755 +index 184a69d..6f91e28 100755 --- a/tutorial/cpp/Makefile.am +++ b/tutorial/cpp/Makefile.am @@ -18,44 +18,38 @@ @@ -1390,7 +1395,7 @@ index 184a69d..39d85e1 100755 -TutorialServer_SOURCES = \ - CppServer.cpp +TestServer_SOURCES = \ -+ GrpcServer.cpp ++ GriftServer.cpp -TutorialServer_LDADD = \ - libtutorialgencpp.la \ @@ -1401,7 +1406,7 @@ index 184a69d..39d85e1 100755 -TutorialClient_SOURCES = \ - CppClient.cpp +TestClient_SOURCES = \ -+ GrpcClient.cpp ++ GriftClient.cpp -TutorialClient_LDADD = \ - libtutorialgencpp.la \ @@ -1444,8 +1449,8 @@ index 184a69d..39d85e1 100755 CMakeLists.txt \ - CppClient.cpp \ - CppServer.cpp -+ GrpcClient.cpp \ -+ GrpcServer.cpp ++ GriftClient.cpp \ ++ GriftServer.cpp diff --git a/tutorial/cpp/test.thrift b/tutorial/cpp/test.thrift new file mode 100644 index 0000000..de3c9a4 @@ -1470,7 +1475,7 @@ index 0000000..de3c9a4 2.8.0.rc3.226.g39d4020 -From 096042c132126536870eea118127cf1e608969bc Mon Sep 17 00:00:00 2001 +From f991f33dd6461eae197b6ad0e7088b571f2a7b22 Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 16:23:53 -0700 Subject: [PATCH 3/3] grpc java plugins generator From 2e698457f370091111d0fe620bad306c743a3548 Mon Sep 17 00:00:00 2001 From: chedeti Date: Wed, 3 Aug 2016 16:45:18 -0700 Subject: [PATCH 147/279] sanity check for thrift --- tools/run_tests/sanity/check_submodules.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh index b602d695649..e2bbd8cabfc 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -47,6 +47,7 @@ cat << EOF | awk '{ print $1 }' | sort > $want_submodules f8ac463766281625ad710900479130c7fcb4d63b third_party/nanopb (nanopb-0.3.4-29-gf8ac463) bdeb215cab2985195325fcd5e70c3fa751f46e0f third_party/protobuf (v3.0.0-beta-3.3) 50893291621658f355bc5b4d450a8d06a563053d third_party/zlib (v1.2.8) + bcad91771b7f0bff28a1cac1981d7ef2b9bcef3c third_party/thrift EOF diff -u $submodules $want_submodules From 6b59ac8da5e605b942ef7f344e5f0e57593385d8 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 2 Aug 2016 10:10:28 -0700 Subject: [PATCH 148/279] Fix Jenkins test error --- tools/run_tests/build_python.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/run_tests/build_python.sh b/tools/run_tests/build_python.sh index 13d745d14fe..f0c15a3ee49 100755 --- a/tools/run_tests/build_python.sh +++ b/tools/run_tests/build_python.sh @@ -111,6 +111,7 @@ TOOLCHAIN=${4:-$(toolchain)} ROOT=`pwd` export CFLAGS="-I$ROOT/include -std=gnu99 -fno-wrapv $CFLAGS" export GRPC_PYTHON_BUILD_WITH_CYTHON=1 +export LANG=en_US.UTF-8 # Default python on the host to fall back to when instantiating e.g. the # virtualenv. From f808eee33aaf81ad9ddae36eaebab9e40de97800 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 2 Aug 2016 10:10:28 -0700 Subject: [PATCH 149/279] Fix Jenkins test error --- tools/run_tests/build_python.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/run_tests/build_python.sh b/tools/run_tests/build_python.sh index a3fa8200d5d..57d98b98296 100755 --- a/tools/run_tests/build_python.sh +++ b/tools/run_tests/build_python.sh @@ -111,6 +111,7 @@ TOOLCHAIN=${4:-$(toolchain)} ROOT=`pwd` export CFLAGS="-I$ROOT/include -std=gnu99 -fno-wrapv $CFLAGS" export GRPC_PYTHON_BUILD_WITH_CYTHON=1 +export LANG=en_US.UTF-8 # Default python on the host to fall back to when instantiating e.g. the # virtualenv. From c6446bf3d8a2492cbe8bae213deb6b7cf547d95d Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Wed, 3 Aug 2016 15:17:01 -0700 Subject: [PATCH 150/279] add csharp hello world that uses dotnet cli --- .../helloworld-from-cli/Greeter/Helloworld.cs | 259 ++++++++++++++++++ .../Greeter/HelloworldGrpc.cs | 143 ++++++++++ .../helloworld-from-cli/Greeter/project.json | 19 ++ .../GreeterClient/Program.cs | 53 ++++ .../GreeterClient/project.json | 23 ++ .../GreeterServer/Program.cs | 66 +++++ .../GreeterServer/project.json | 23 ++ examples/csharp/helloworld-from-cli/README.md | 59 ++++ 8 files changed, 645 insertions(+) create mode 100644 examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs create mode 100644 examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs create mode 100644 examples/csharp/helloworld-from-cli/Greeter/project.json create mode 100644 examples/csharp/helloworld-from-cli/GreeterClient/Program.cs create mode 100644 examples/csharp/helloworld-from-cli/GreeterClient/project.json create mode 100644 examples/csharp/helloworld-from-cli/GreeterServer/Program.cs create mode 100644 examples/csharp/helloworld-from-cli/GreeterServer/project.json create mode 100644 examples/csharp/helloworld-from-cli/README.md diff --git a/examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs b/examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs new file mode 100644 index 00000000000..6477b4f35be --- /dev/null +++ b/examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs @@ -0,0 +1,259 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace Helloworld { + + /// Holder for reflection information generated from helloworld.proto + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public static partial class HelloworldReflection { + + #region Descriptor + /// File descriptor for helloworld.proto + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static HelloworldReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVz", + "dBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEo", + "CTJJCgdHcmVldGVyEj4KCFNheUhlbGxvEhguaGVsbG93b3JsZC5IZWxsb1Jl", + "cXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiAEI2Chtpby5ncnBjLmV4", + "YW1wbGVzLmhlbGxvd29ybGRCD0hlbGxvV29ybGRQcm90b1ABogIDSExXYgZw", + "cm90bzM=")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { }, + new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloRequest), global::Helloworld.HelloRequest.Parser, new[]{ "Name" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloReply), global::Helloworld.HelloReply.Parser, new[]{ "Message" }, null, null, null) + })); + } + #endregion + + } + #region Messages + /// + /// The request message containing the user's name. + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class HelloRequest : pb::IMessage { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HelloRequest()); + public static pb::MessageParser Parser { get { return _parser; } } + + public static pbr::MessageDescriptor Descriptor { + get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[0]; } + } + + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + public HelloRequest() { + OnConstruction(); + } + + partial void OnConstruction(); + + public HelloRequest(HelloRequest other) : this() { + name_ = other.name_; + } + + public HelloRequest Clone() { + return new HelloRequest(this); + } + + /// Field number for the "name" field. + public const int NameFieldNumber = 1; + private string name_ = ""; + public string Name { + get { return name_; } + set { + name_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + public override bool Equals(object other) { + return Equals(other as HelloRequest); + } + + public bool Equals(HelloRequest other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Name != other.Name) return false; + return true; + } + + public override int GetHashCode() { + int hash = 1; + if (Name.Length != 0) hash ^= Name.GetHashCode(); + return hash; + } + + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + public void WriteTo(pb::CodedOutputStream output) { + if (Name.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Name); + } + } + + public int CalculateSize() { + int size = 0; + if (Name.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); + } + return size; + } + + public void MergeFrom(HelloRequest other) { + if (other == null) { + return; + } + if (other.Name.Length != 0) { + Name = other.Name; + } + } + + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 10: { + Name = input.ReadString(); + break; + } + } + } + } + + } + + /// + /// The response message containing the greetings + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class HelloReply : pb::IMessage { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HelloReply()); + public static pb::MessageParser Parser { get { return _parser; } } + + public static pbr::MessageDescriptor Descriptor { + get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[1]; } + } + + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + public HelloReply() { + OnConstruction(); + } + + partial void OnConstruction(); + + public HelloReply(HelloReply other) : this() { + message_ = other.message_; + } + + public HelloReply Clone() { + return new HelloReply(this); + } + + /// Field number for the "message" field. + public const int MessageFieldNumber = 1; + private string message_ = ""; + public string Message { + get { return message_; } + set { + message_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + public override bool Equals(object other) { + return Equals(other as HelloReply); + } + + public bool Equals(HelloReply other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Message != other.Message) return false; + return true; + } + + public override int GetHashCode() { + int hash = 1; + if (Message.Length != 0) hash ^= Message.GetHashCode(); + return hash; + } + + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + public void WriteTo(pb::CodedOutputStream output) { + if (Message.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Message); + } + } + + public int CalculateSize() { + int size = 0; + if (Message.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Message); + } + return size; + } + + public void MergeFrom(HelloReply other) { + if (other == null) { + return; + } + if (other.Message.Length != 0) { + Message = other.Message; + } + } + + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 10: { + Message = input.ReadString(); + break; + } + } + } + } + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs b/examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs new file mode 100644 index 00000000000..041f5a78d75 --- /dev/null +++ b/examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs @@ -0,0 +1,143 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto +// Original file comments: +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +#region Designer generated code + +using System; +using System.Threading; +using System.Threading.Tasks; +using Grpc.Core; + +namespace Helloworld { + /// + /// The greeting service definition. + /// + public static class Greeter + { + static readonly string __ServiceName = "helloworld.Greeter"; + + static readonly Marshaller __Marshaller_HelloRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom); + static readonly Marshaller __Marshaller_HelloReply = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom); + + static readonly Method __Method_SayHello = new Method( + MethodType.Unary, + __ServiceName, + "SayHello", + __Marshaller_HelloRequest, + __Marshaller_HelloReply); + + /// Service descriptor + public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor + { + get { return global::Helloworld.HelloworldReflection.Descriptor.Services[0]; } + } + + /// Base class for server-side implementations of Greeter + public abstract class GreeterBase + { + /// + /// Sends a greeting + /// + public virtual global::System.Threading.Tasks.Task SayHello(global::Helloworld.HelloRequest request, ServerCallContext context) + { + throw new RpcException(new Status(StatusCode.Unimplemented, "")); + } + + } + + /// Client for Greeter + public class GreeterClient : ClientBase + { + /// Creates a new client for Greeter + /// The channel to use to make remote calls. + public GreeterClient(Channel channel) : base(channel) + { + } + /// Creates a new client for Greeter that uses a custom CallInvoker. + /// The callInvoker to use to make remote calls. + public GreeterClient(CallInvoker callInvoker) : base(callInvoker) + { + } + /// Protected parameterless constructor to allow creation of test doubles. + protected GreeterClient() : base() + { + } + /// Protected constructor to allow creation of configured clients. + /// The client configuration. + protected GreeterClient(ClientBaseConfiguration configuration) : base(configuration) + { + } + + /// + /// Sends a greeting + /// + public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) + { + return SayHello(request, new CallOptions(headers, deadline, cancellationToken)); + } + /// + /// Sends a greeting + /// + public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, CallOptions options) + { + return CallInvoker.BlockingUnaryCall(__Method_SayHello, null, options, request); + } + /// + /// Sends a greeting + /// + public virtual AsyncUnaryCall SayHelloAsync(global::Helloworld.HelloRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) + { + return SayHelloAsync(request, new CallOptions(headers, deadline, cancellationToken)); + } + /// + /// Sends a greeting + /// + public virtual AsyncUnaryCall SayHelloAsync(global::Helloworld.HelloRequest request, CallOptions options) + { + return CallInvoker.AsyncUnaryCall(__Method_SayHello, null, options, request); + } + protected override GreeterClient NewInstance(ClientBaseConfiguration configuration) + { + return new GreeterClient(configuration); + } + } + + /// Creates service definition that can be registered with a server + public static ServerServiceDefinition BindService(GreeterBase serviceImpl) + { + return ServerServiceDefinition.CreateBuilder() + .AddMethod(__Method_SayHello, serviceImpl.SayHello).Build(); + } + + } +} +#endregion diff --git a/examples/csharp/helloworld-from-cli/Greeter/project.json b/examples/csharp/helloworld-from-cli/Greeter/project.json new file mode 100644 index 00000000000..e06854d1226 --- /dev/null +++ b/examples/csharp/helloworld-from-cli/Greeter/project.json @@ -0,0 +1,19 @@ +{ + "title": "Greeter", + "version": "1.0.0-*", + "buildOptions": { + "debugType": "portable", + }, + "dependencies": { + "Google.Protobuf": "3.0.0-beta3", + "Grpc": "1.0.0-pre1", + }, + "frameworks": { + "net45": { + "frameworkAssemblies": { + "System.Runtime": "", + "System.IO": "" + } + } + } +} diff --git a/examples/csharp/helloworld-from-cli/GreeterClient/Program.cs b/examples/csharp/helloworld-from-cli/GreeterClient/Program.cs new file mode 100644 index 00000000000..444d4735095 --- /dev/null +++ b/examples/csharp/helloworld-from-cli/GreeterClient/Program.cs @@ -0,0 +1,53 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +using System; +using Grpc.Core; +using Helloworld; + +namespace GreeterClient +{ + class Program + { + public static void Main(string[] args) + { + Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure); + + var client = new Greeter.GreeterClient(channel); + String user = "you"; + + var reply = client.SayHello(new HelloRequest { Name = user }); + Console.WriteLine("Greeting: " + reply.Message); + + channel.ShutdownAsync().Wait(); + Console.WriteLine("Press any key to exit..."); + Console.ReadKey(); + } + } +} diff --git a/examples/csharp/helloworld-from-cli/GreeterClient/project.json b/examples/csharp/helloworld-from-cli/GreeterClient/project.json new file mode 100644 index 00000000000..dc72a30eb81 --- /dev/null +++ b/examples/csharp/helloworld-from-cli/GreeterClient/project.json @@ -0,0 +1,23 @@ +{ + "title": "GreeterClient", + "version": "1.0.0-*", + "buildOptions": { + "debugType": "portable", + "emitEntryPoint": "true" + }, + "dependencies": { + "Google.Protobuf": "3.0.0-beta3", + "Grpc": "1.0.0-pre1", + "Greeter": { + "target": "project" + } + }, + "frameworks": { + "net45": { + "frameworkAssemblies": { + "System.Runtime": "", + "System.IO": "" + } + } + } +} diff --git a/examples/csharp/helloworld-from-cli/GreeterServer/Program.cs b/examples/csharp/helloworld-from-cli/GreeterServer/Program.cs new file mode 100644 index 00000000000..fdab379e81d --- /dev/null +++ b/examples/csharp/helloworld-from-cli/GreeterServer/Program.cs @@ -0,0 +1,66 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +using System; +using System.Threading.Tasks; +using Grpc.Core; +using Helloworld; + +namespace GreeterServer +{ + class GreeterImpl : Greeter.GreeterBase + { + // Server side handler of the SayHello RPC + public override Task SayHello(HelloRequest request, ServerCallContext context) + { + return Task.FromResult(new HelloReply { Message = "Hello " + request.Name }); + } + } + + class Program + { + const int Port = 50051; + + public static void Main(string[] args) + { + Server server = new Server + { + Services = { Greeter.BindService(new GreeterImpl()) }, + Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) } + }; + server.Start(); + + Console.WriteLine("Greeter server listening on port " + Port); + Console.WriteLine("Press any key to stop the server..."); + Console.ReadKey(); + + server.ShutdownAsync().Wait(); + } + } +} diff --git a/examples/csharp/helloworld-from-cli/GreeterServer/project.json b/examples/csharp/helloworld-from-cli/GreeterServer/project.json new file mode 100644 index 00000000000..4bf201bef38 --- /dev/null +++ b/examples/csharp/helloworld-from-cli/GreeterServer/project.json @@ -0,0 +1,23 @@ +{ + "title": "GreeterServer", + "version": "1.0.0-*", + "buildOptions": { + "debugType": "portable", + "emitEntryPoint": "true" + }, + "dependencies": { + "Google.Protobuf": "3.0.0-beta3", + "Grpc": "1.0.0-pre1", + "Greeter": { + "target": "project" + } + }, + "frameworks": { + "net45": { + "frameworkAssemblies": { + "System.Runtime": "", + "System.IO": "" + } + } + } +} diff --git a/examples/csharp/helloworld-from-cli/README.md b/examples/csharp/helloworld-from-cli/README.md new file mode 100644 index 00000000000..4db077631d8 --- /dev/null +++ b/examples/csharp/helloworld-from-cli/README.md @@ -0,0 +1,59 @@ +gRPC in 3 minutes (C#) +======================== + +BACKGROUND +------------- +This is a different version of the helloworld example, using the dotnet sdk +tools to build and run. + +For this sample, we've already generated the server and client stubs from [helloworld.proto][]. + +Example projects in this directory depend on the [Grpc](https://www.nuget.org/packages/Grpc/) +and [Google.Protobuf](https://www.nuget.org/packages/Google.Protobuf/) NuGet packages +which have been already added to the project for you. + +The examples in this directory target .NET 4.5 framework, as .NET Core support is +currently experimental. + +PREREQUISITES +------------- + +- The DotNetCore SDK cli. + +- The .NET 4.5 framework. + +Both are available to download at https://www.microsoft.com/net/download + +BUILD +------- + +From the `examples/csharp/helloworld-from-cli` directory: + +- `dotnet restore` + +- `dotnet build **/project.json` (this will automatically download NuGet dependencies) + +Try it! +------- + +- Run the server + + ``` + > cd GreeterServer + > dotnet run + ``` + +- Run the client + + ``` + > cd GreeterClient + > dotnet run + ``` + +Tutorial +-------- + +You can find a more detailed tutorial about Grpc in [gRPC Basics: C#][] + +[helloworld.proto]:../../protos/helloworld.proto +[gRPC Basics: C#]:http://www.grpc.io/docs/tutorials/basic/csharp.html From 5b4d3625ebbf638080d07b7d267c5d90904d4f14 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Wed, 3 Aug 2016 15:33:37 -0700 Subject: [PATCH 151/279] Update ruby examples to use new _pb protobuf format --- examples/ruby/greeter_client.rb | 2 +- examples/ruby/greeter_server.rb | 2 +- examples/ruby/grpc-demo.gemspec | 4 ++-- examples/ruby/lib/{helloworld.rb => helloworld_pb.rb} | 0 .../lib/{helloworld_services.rb => helloworld_services_pb.rb} | 2 +- examples/ruby/lib/{route_guide.rb => route_guide_pb.rb} | 0 .../{route_guide_services.rb => route_guide_services_pb.rb} | 2 +- examples/ruby/route_guide/route_guide_client.rb | 2 +- examples/ruby/route_guide/route_guide_server.rb | 2 +- 9 files changed, 8 insertions(+), 8 deletions(-) rename examples/ruby/lib/{helloworld.rb => helloworld_pb.rb} (100%) rename examples/ruby/lib/{helloworld_services.rb => helloworld_services_pb.rb} (98%) rename examples/ruby/lib/{route_guide.rb => route_guide_pb.rb} (100%) rename examples/ruby/lib/{route_guide_services.rb => route_guide_services_pb.rb} (99%) diff --git a/examples/ruby/greeter_client.rb b/examples/ruby/greeter_client.rb index cb4aa195e77..1cdf79ebf40 100755 --- a/examples/ruby/greeter_client.rb +++ b/examples/ruby/greeter_client.rb @@ -38,7 +38,7 @@ lib_dir = File.join(this_dir, 'lib') $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) require 'grpc' -require 'helloworld_services' +require 'helloworld_services_pb' def main stub = Helloworld::Greeter::Stub.new('localhost:50051', :this_channel_is_insecure) diff --git a/examples/ruby/greeter_server.rb b/examples/ruby/greeter_server.rb index 622513d3805..6d82043c526 100755 --- a/examples/ruby/greeter_server.rb +++ b/examples/ruby/greeter_server.rb @@ -38,7 +38,7 @@ lib_dir = File.join(this_dir, 'lib') $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) require 'grpc' -require 'helloworld_services' +require 'helloworld_services_pb' # GreeterServer is simple server that implements the Helloworld Greeter server. class GreeterServer < Helloworld::Greeter::Service diff --git a/examples/ruby/grpc-demo.gemspec b/examples/ruby/grpc-demo.gemspec index b1dfdae6ab3..e1b77a56ac9 100644 --- a/examples/ruby/grpc-demo.gemspec +++ b/examples/ruby/grpc-demo.gemspec @@ -3,7 +3,7 @@ Gem::Specification.new do |s| s.name = 'grpc-demo' - s.version = '0.11.0' + s.version = '1.0.0' s.authors = ['gRPC Authors'] s.email = 'temiola@google.com' s.homepage = 'https://github.com/grpc/grpc' @@ -17,7 +17,7 @@ Gem::Specification.new do |s| s.require_paths = ['lib'] s.platform = Gem::Platform::RUBY - s.add_dependency 'grpc', '~> 0.11' + s.add_dependency 'grpc', '~> 1.0.0' s.add_development_dependency 'bundler', '~> 1.7' end diff --git a/examples/ruby/lib/helloworld.rb b/examples/ruby/lib/helloworld_pb.rb similarity index 100% rename from examples/ruby/lib/helloworld.rb rename to examples/ruby/lib/helloworld_pb.rb diff --git a/examples/ruby/lib/helloworld_services.rb b/examples/ruby/lib/helloworld_services_pb.rb similarity index 98% rename from examples/ruby/lib/helloworld_services.rb rename to examples/ruby/lib/helloworld_services_pb.rb index fbec6677942..4fee0aa2a91 100644 --- a/examples/ruby/lib/helloworld_services.rb +++ b/examples/ruby/lib/helloworld_services_pb.rb @@ -32,7 +32,7 @@ # require 'grpc' -require 'helloworld' +require 'helloworld_pb' module Helloworld module Greeter diff --git a/examples/ruby/lib/route_guide.rb b/examples/ruby/lib/route_guide_pb.rb similarity index 100% rename from examples/ruby/lib/route_guide.rb rename to examples/ruby/lib/route_guide_pb.rb diff --git a/examples/ruby/lib/route_guide_services.rb b/examples/ruby/lib/route_guide_services_pb.rb similarity index 99% rename from examples/ruby/lib/route_guide_services.rb rename to examples/ruby/lib/route_guide_services_pb.rb index d8f123dd95b..d43fcc64e9a 100644 --- a/examples/ruby/lib/route_guide_services.rb +++ b/examples/ruby/lib/route_guide_services_pb.rb @@ -32,7 +32,7 @@ # require 'grpc' -require 'route_guide' +require 'route_guide_pb' module Routeguide module RouteGuide diff --git a/examples/ruby/route_guide/route_guide_client.rb b/examples/ruby/route_guide/route_guide_client.rb index e7f802c21e6..330725ece0d 100755 --- a/examples/ruby/route_guide/route_guide_client.rb +++ b/examples/ruby/route_guide/route_guide_client.rb @@ -39,7 +39,7 @@ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) require 'grpc' require 'multi_json' -require 'route_guide_services' +require 'route_guide_services_pb' include Routeguide diff --git a/examples/ruby/route_guide/route_guide_server.rb b/examples/ruby/route_guide/route_guide_server.rb index bebe49b3beb..a5a73a8bac1 100755 --- a/examples/ruby/route_guide/route_guide_server.rb +++ b/examples/ruby/route_guide/route_guide_server.rb @@ -40,7 +40,7 @@ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) require 'grpc' require 'multi_json' -require 'route_guide_services' +require 'route_guide_services_pb' include Routeguide COORD_FACTOR = 1e7 From 7d9f276ea278313f6ba1930931b5dde14167b8ac Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 4 Aug 2016 11:06:49 -0700 Subject: [PATCH 152/279] Change handshaker API to use a read buffer to pass leftover bytes read between handshakers. --- .../chttp2/client/insecure/channel_create.c | 19 +++++++--- .../client/insecure/channel_create_posix.c | 2 +- .../client/secure/secure_channel_create.c | 13 ++++--- .../chttp2/server/insecure/server_chttp2.c | 6 ++- .../server/insecure/server_chttp2_posix.c | 2 +- .../server/secure/server_secure_chttp2.c | 12 +++--- .../chttp2/transport/chttp2_transport.c | 7 +++- .../chttp2/transport/chttp2_transport.h | 4 +- src/core/lib/channel/handshaker.c | 25 ++++++++----- src/core/lib/channel/handshaker.h | 8 +++- .../lib/http/httpcli_security_connector.c | 8 +++- src/core/lib/security/transport/handshake.c | 9 ++++- src/core/lib/security/transport/handshake.h | 7 ++-- .../security/transport/security_connector.c | 37 +++++++++++++------ .../security/transport/security_connector.h | 14 ++++--- 15 files changed, 115 insertions(+), 58 deletions(-) diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c index 6f6855584a7..cbaa75a90af 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c @@ -88,14 +88,21 @@ static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, } static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, - grpc_channel_args *args, void *user_data, + grpc_channel_args *args, + gpr_slice_buffer *read_buffer, void *user_data, grpc_error *error) { connector *c = user_data; - c->result->transport = - grpc_create_chttp2_transport(exec_ctx, args, endpoint, 1); - GPR_ASSERT(c->result->transport); - grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, 0); - c->result->channel_args = args; + if (error != GRPC_ERROR_NONE) { + grpc_channel_args_destroy(args); + gpr_free(read_buffer); + } else { + c->result->transport = + grpc_create_chttp2_transport(exec_ctx, args, endpoint, 1); + GPR_ASSERT(c->result->transport); + grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, + read_buffer); + c->result->channel_args = args; + } grpc_closure *notify = c->notify; c->notify = NULL; grpc_exec_ctx_sched(exec_ctx, notify, error, NULL); diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c b/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c index ca435c25cec..b2c5e5b088c 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c @@ -75,7 +75,7 @@ grpc_channel *grpc_insecure_channel_create_from_fd( grpc_channel *channel = grpc_channel_create( &exec_ctx, target, final_args, GRPC_CLIENT_DIRECT_CHANNEL, transport); grpc_channel_args_destroy(final_args); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_exec_ctx_finish(&exec_ctx); diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c index 4e33b6fa612..9e2bdd758f9 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c @@ -114,8 +114,7 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, gpr_mu_unlock(&c->mu); c->result->transport = grpc_create_chttp2_transport( exec_ctx, c->args.channel_args, secure_endpoint, 1); - grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, - 0); + grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL); auth_context_arg = grpc_auth_context_to_arg(auth_context); c->result->channel_args = grpc_channel_args_copy_and_add(c->tmp_args, &auth_context_arg, 1); @@ -126,10 +125,13 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, } static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, - grpc_channel_args *args, void *user_data, + grpc_channel_args *args, + gpr_slice_buffer *read_buffer, void *user_data, grpc_error *error) { connector *c = user_data; + c->tmp_args = args; if (error != GRPC_ERROR_NONE) { + gpr_free(read_buffer); grpc_closure *notify = c->notify; c->notify = NULL; grpc_exec_ctx_sched(exec_ctx, notify, error, NULL); @@ -137,10 +139,9 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, // TODO(roth, jboeuf): Convert security connector handshaking to use new // handshake API, and then move the code from on_secure_handshake_done() // into this function. - c->tmp_args = args; grpc_channel_security_connector_do_handshake( - exec_ctx, c->security_connector, endpoint, c->args.deadline, - on_secure_handshake_done, c); + exec_ctx, c->security_connector, endpoint, read_buffer, + c->args.deadline, on_secure_handshake_done, c); } } diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c index 9cd374777e9..f0e07429faf 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c @@ -55,7 +55,8 @@ typedef struct server_connect_state { } server_connect_state; static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, - grpc_channel_args *args, void *user_data, + grpc_channel_args *args, + gpr_slice_buffer *read_buffer, void *user_data, grpc_error *error) { server_connect_state *state = user_data; if (error != GRPC_ERROR_NONE) { @@ -64,6 +65,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, grpc_error_free_string(error_str); GRPC_ERROR_UNREF(error); grpc_handshake_manager_shutdown(exec_ctx, state->handshake_mgr); + gpr_free(read_buffer); } else { // Beware that the call to grpc_create_chttp2_transport() has to happen // before grpc_tcp_server_destroy(). This is fine here, but similar code @@ -75,7 +77,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, grpc_server_setup_transport(exec_ctx, state->server, transport, state->accepting_pollset, grpc_server_get_channel_args(state->server)); - grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(exec_ctx, transport, read_buffer); } // Clean up. grpc_channel_args_destroy(args); diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c index 96bf4d6f308..4350543c27a 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c @@ -67,7 +67,7 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server *server, &exec_ctx, server_args, server_endpoint, 0 /* is_client */); grpc_endpoint_add_to_pollset(&exec_ctx, server_endpoint, grpc_cq_pollset(cq)); grpc_server_setup_transport(&exec_ctx, server, transport, NULL, server_args); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_exec_ctx_finish(&exec_ctx); } diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c index ccea15a648d..da3e284fcf2 100644 --- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c @@ -111,7 +111,7 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep, grpc_server_setup_transport(exec_ctx, state->state->server, transport, state->accepting_pollset, args_copy); grpc_channel_args_destroy(args_copy); - grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL); } else { /* We need to consume this here, because the server may already have * gone away. */ @@ -128,7 +128,8 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep, } static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, - grpc_channel_args *args, void *user_data, + grpc_channel_args *args, + gpr_slice_buffer *read_buffer, void *user_data, grpc_error *error) { server_secure_connect *state = user_data; if (error != GRPC_ERROR_NONE) { @@ -136,9 +137,10 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, gpr_log(GPR_ERROR, "Handshaking failed: %s", error_str); grpc_error_free_string(error_str); GRPC_ERROR_UNREF(error); + grpc_channel_args_destroy(args); + gpr_free(read_buffer); grpc_handshake_manager_shutdown(exec_ctx, state->handshake_mgr); grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr); - grpc_channel_args_destroy(args); state_unref(state->state); gpr_free(state); return; @@ -150,8 +152,8 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, // into this function. state->args = args; grpc_server_security_connector_do_handshake( - exec_ctx, state->state->sc, state->acceptor, endpoint, state->deadline, - on_secure_handshake_done, state); + exec_ctx, state->state->sc, state->acceptor, endpoint, read_buffer, + state->deadline, on_secure_handshake_done, state); } static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp, diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 6bd65cea02c..f2f5465201d 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -2538,9 +2538,12 @@ grpc_transport *grpc_create_chttp2_transport( void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx, grpc_transport *transport, - gpr_slice *slices, size_t nslices) { + gpr_slice_buffer *read_buffer) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)transport; REF_TRANSPORT(t, "reading_action"); /* matches unref inside reading_action */ - gpr_slice_buffer_addn(&t->read_buffer, slices, nslices); + if (read_buffer != NULL) { + gpr_slice_buffer_move_into(read_buffer, &t->read_buffer); + gpr_free(read_buffer); + } reading_action(exec_ctx, t, GRPC_ERROR_NONE); } diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.h b/src/core/ext/transport/chttp2/transport/chttp2_transport.h index 5da4276f826..4e2d0954bf1 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.h +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.h @@ -44,8 +44,10 @@ grpc_transport *grpc_create_chttp2_transport( grpc_exec_ctx *exec_ctx, const grpc_channel_args *channel_args, grpc_endpoint *ep, int is_client); +/// Takes ownership of \a read_buffer, which (if non-NULL) contains +/// leftover bytes previously read from the endpoint (e.g., by handshakers). void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx, grpc_transport *transport, - gpr_slice *slices, size_t nslices); + gpr_slice_buffer *read_buffer); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CHTTP2_TRANSPORT_H */ diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c index 6c3ca198b72..01fcbb20235 100644 --- a/src/core/lib/channel/handshaker.c +++ b/src/core/lib/channel/handshaker.c @@ -62,11 +62,13 @@ void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, grpc_endpoint* endpoint, grpc_channel_args* args, + gpr_slice_buffer* read_buffer, gpr_timespec deadline, grpc_tcp_server_acceptor* acceptor, grpc_handshaker_done_cb cb, void* user_data) { handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint, args, - deadline, acceptor, cb, user_data); + read_buffer, deadline, acceptor, cb, + user_data); } // @@ -143,16 +145,17 @@ void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, // handshakers together. static void call_next_handshaker(grpc_exec_ctx* exec_ctx, grpc_endpoint* endpoint, - grpc_channel_args* args, void* user_data, - grpc_error* error) { + grpc_channel_args* args, + gpr_slice_buffer* read_buffer, + void* user_data, grpc_error* error) { grpc_handshake_manager* mgr = user_data; GPR_ASSERT(mgr->state != NULL); GPR_ASSERT(mgr->state->index < mgr->count); // If we got an error, skip all remaining handshakers and invoke the // caller-supplied callback immediately. if (error != GRPC_ERROR_NONE) { - mgr->state->final_cb(exec_ctx, endpoint, args, mgr->state->final_user_data, - error); + mgr->state->final_cb(exec_ctx, endpoint, args, read_buffer, + mgr->state->final_user_data, error); return; } grpc_handshaker_done_cb cb = call_next_handshaker; @@ -164,8 +167,9 @@ static void call_next_handshaker(grpc_exec_ctx* exec_ctx, } // Invoke handshaker. grpc_handshaker_do_handshake(exec_ctx, mgr->handshakers[mgr->state->index], - endpoint, args, mgr->state->deadline, - mgr->state->acceptor, cb, user_data); + endpoint, args, read_buffer, + mgr->state->deadline, mgr->state->acceptor, + cb, user_data); ++mgr->state->index; // If this is the last handshaker, clean up state. if (mgr->state->index == mgr->count) { @@ -180,10 +184,12 @@ void grpc_handshake_manager_do_handshake( gpr_timespec deadline, grpc_tcp_server_acceptor* acceptor, grpc_handshaker_done_cb cb, void* user_data) { grpc_channel_args* args_copy = grpc_channel_args_copy(args); + gpr_slice_buffer* read_buffer = malloc(sizeof(*read_buffer)); + gpr_slice_buffer_init(read_buffer); if (mgr->count == 0) { // No handshakers registered, so we just immediately call the done // callback with the passed-in endpoint. - cb(exec_ctx, endpoint, args_copy, user_data, GRPC_ERROR_NONE); + cb(exec_ctx, endpoint, args_copy, read_buffer, user_data, GRPC_ERROR_NONE); } else { GPR_ASSERT(mgr->state == NULL); mgr->state = gpr_malloc(sizeof(struct grpc_handshaker_state)); @@ -192,6 +198,7 @@ void grpc_handshake_manager_do_handshake( mgr->state->acceptor = acceptor; mgr->state->final_cb = cb; mgr->state->final_user_data = user_data; - call_next_handshaker(exec_ctx, endpoint, args_copy, mgr, GRPC_ERROR_NONE); + call_next_handshaker(exec_ctx, endpoint, args_copy, read_buffer, mgr, + GRPC_ERROR_NONE); } } diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index dfc469c417b..fac4935b16b 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -36,6 +36,7 @@ #include #include +#include #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/endpoint.h" @@ -56,10 +57,11 @@ typedef struct grpc_handshaker grpc_handshaker; /// Callback type invoked when a handshaker is done. -/// Takes ownership of \a args. +/// Takes ownership of \a args and \a read_buffer. typedef void (*grpc_handshaker_done_cb)(grpc_exec_ctx* exec_ctx, grpc_endpoint* endpoint, grpc_channel_args* args, + gpr_slice_buffer* read_buffer, void* user_data, grpc_error* error); struct grpc_handshaker_vtable { @@ -72,9 +74,12 @@ struct grpc_handshaker_vtable { /// Performs handshaking. When finished, calls \a cb with \a user_data. /// Takes ownership of \a args. + /// Takes ownership of \a read_buffer, which contains leftover bytes read + /// from the endpoint by the previous handshaker. /// \a acceptor will be NULL for client-side handshakers. void (*do_handshake)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, grpc_endpoint* endpoint, grpc_channel_args* args, + gpr_slice_buffer* read_buffer, gpr_timespec deadline, grpc_tcp_server_acceptor* acceptor, grpc_handshaker_done_cb cb, void* user_data); @@ -101,6 +106,7 @@ void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, grpc_endpoint* endpoint, grpc_channel_args* args, + gpr_slice_buffer* read_buffer, gpr_timespec deadline, grpc_tcp_server_acceptor* acceptor, grpc_handshaker_done_cb cb, void* user_data); diff --git a/src/core/lib/http/httpcli_security_connector.c b/src/core/lib/http/httpcli_security_connector.c index a57d93bb7bb..0006e809a6a 100644 --- a/src/core/lib/http/httpcli_security_connector.c +++ b/src/core/lib/http/httpcli_security_connector.c @@ -61,6 +61,7 @@ static void httpcli_ssl_destroy(grpc_security_connector *sc) { static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, grpc_endpoint *nonsecure_endpoint, + gpr_slice_buffer *read_buffer, gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data) { @@ -69,6 +70,7 @@ static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx, tsi_result result = TSI_OK; tsi_handshaker *handshaker; if (c->handshaker_factory == NULL) { + gpr_free(read_buffer); cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); return; } @@ -77,10 +79,12 @@ static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx, if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", tsi_result_to_string(result)); + gpr_free(read_buffer); cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); } else { grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true, - nonsecure_endpoint, deadline, cb, user_data); + nonsecure_endpoint, read_buffer, deadline, cb, + user_data); } } @@ -183,7 +187,7 @@ static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg, pem_root_certs, pem_root_certs_size, host, &sc) == GRPC_SECURITY_OK); grpc_channel_security_connector_do_handshake( - exec_ctx, sc, tcp, deadline, on_secure_transport_setup_done, c); + exec_ctx, sc, tcp, NULL, deadline, on_secure_transport_setup_done, c); GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli"); } diff --git a/src/core/lib/security/transport/handshake.c b/src/core/lib/security/transport/handshake.c index 540a17283d3..fbeec312b6f 100644 --- a/src/core/lib/security/transport/handshake.c +++ b/src/core/lib/security/transport/handshake.c @@ -325,8 +325,9 @@ static void on_timeout(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { void grpc_do_security_handshake( grpc_exec_ctx *exec_ctx, tsi_handshaker *handshaker, grpc_security_connector *connector, bool is_client_side, - grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline, - grpc_security_handshake_done_cb cb, void *user_data) { + grpc_endpoint *nonsecure_endpoint, gpr_slice_buffer *read_buffer, + gpr_timespec deadline, grpc_security_handshake_done_cb cb, + void *user_data) { grpc_security_connector_handshake_list *handshake_node; grpc_security_handshake *h = gpr_malloc(sizeof(grpc_security_handshake)); memset(h, 0, sizeof(grpc_security_handshake)); @@ -346,6 +347,10 @@ void grpc_do_security_handshake( gpr_slice_buffer_init(&h->left_overs); gpr_slice_buffer_init(&h->outgoing); gpr_slice_buffer_init(&h->incoming); + if (read_buffer != NULL) { + gpr_slice_buffer_move_into(read_buffer, &h->incoming); + gpr_free(read_buffer); + } if (!is_client_side) { grpc_server_security_connector *server_connector = (grpc_server_security_connector *)connector; diff --git a/src/core/lib/security/transport/handshake.h b/src/core/lib/security/transport/handshake.h index c0906dd6af0..53092f54214 100644 --- a/src/core/lib/security/transport/handshake.h +++ b/src/core/lib/security/transport/handshake.h @@ -37,12 +37,13 @@ #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/security/transport/security_connector.h" -/* Calls the callback upon completion. Takes owership of handshaker. */ +/* Calls the callback upon completion. Takes owership of handshaker and + * read_buffer. */ void grpc_do_security_handshake( grpc_exec_ctx *exec_ctx, tsi_handshaker *handshaker, grpc_security_connector *connector, bool is_client_side, - grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline, - grpc_security_handshake_done_cb cb, void *user_data); + grpc_endpoint *nonsecure_endpoint, gpr_slice_buffer *read_buffer, + gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data); void grpc_security_handshake_shutdown(grpc_exec_ctx *exec_ctx, void *handshake); diff --git a/src/core/lib/security/transport/security_connector.c b/src/core/lib/security/transport/security_connector.c index f0ee6770e5f..1ee12319005 100644 --- a/src/core/lib/security/transport/security_connector.c +++ b/src/core/lib/security/transport/security_connector.c @@ -127,25 +127,29 @@ void grpc_server_security_connector_shutdown( void grpc_channel_security_connector_do_handshake( grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, - grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline, - grpc_security_handshake_done_cb cb, void *user_data) { + grpc_endpoint *nonsecure_endpoint, gpr_slice_buffer *read_buffer, + gpr_timespec deadline, grpc_security_handshake_done_cb cb, + void *user_data) { if (sc == NULL || nonsecure_endpoint == NULL) { + gpr_free(read_buffer); cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); } else { - sc->do_handshake(exec_ctx, sc, nonsecure_endpoint, deadline, cb, user_data); + sc->do_handshake(exec_ctx, sc, nonsecure_endpoint, read_buffer, deadline, + cb, user_data); } } void grpc_server_security_connector_do_handshake( grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc, grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint, - gpr_timespec deadline, grpc_security_handshake_done_cb cb, - void *user_data) { + gpr_slice_buffer *read_buffer, gpr_timespec deadline, + grpc_security_handshake_done_cb cb, void *user_data) { if (sc == NULL || nonsecure_endpoint == NULL) { + gpr_free(read_buffer); cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); } else { - sc->do_handshake(exec_ctx, sc, acceptor, nonsecure_endpoint, deadline, cb, - user_data); + sc->do_handshake(exec_ctx, sc, acceptor, nonsecure_endpoint, read_buffer, + deadline, cb, user_data); } } @@ -312,23 +316,26 @@ static void fake_channel_check_call_host(grpc_exec_ctx *exec_ctx, static void fake_channel_do_handshake(grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, grpc_endpoint *nonsecure_endpoint, + gpr_slice_buffer *read_buffer, gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data) { grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(1), &sc->base, - true, nonsecure_endpoint, deadline, cb, user_data); + true, nonsecure_endpoint, read_buffer, deadline, + cb, user_data); } static void fake_server_do_handshake(grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc, grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint, + gpr_slice_buffer *read_buffer, gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data) { grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(0), &sc->base, - false, nonsecure_endpoint, deadline, cb, - user_data); + false, nonsecure_endpoint, read_buffer, deadline, + cb, user_data); } static grpc_security_connector_vtable fake_channel_vtable = { @@ -418,6 +425,7 @@ static grpc_security_status ssl_create_handshaker( static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, grpc_endpoint *nonsecure_endpoint, + gpr_slice_buffer *read_buffer, gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data) { @@ -430,10 +438,12 @@ static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx, : c->target_name, &handshaker); if (status != GRPC_SECURITY_OK) { + gpr_free(read_buffer); cb(exec_ctx, user_data, status, NULL, NULL); } else { grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true, - nonsecure_endpoint, deadline, cb, user_data); + nonsecure_endpoint, read_buffer, deadline, cb, + user_data); } } @@ -441,6 +451,7 @@ static void ssl_server_do_handshake(grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc, grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint, + gpr_slice_buffer *read_buffer, gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data) { @@ -450,10 +461,12 @@ static void ssl_server_do_handshake(grpc_exec_ctx *exec_ctx, grpc_security_status status = ssl_create_handshaker(c->handshaker_factory, false, NULL, &handshaker); if (status != GRPC_SECURITY_OK) { + gpr_free(read_buffer); cb(exec_ctx, user_data, status, NULL, NULL); } else { grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, false, - nonsecure_endpoint, deadline, cb, user_data); + nonsecure_endpoint, read_buffer, deadline, cb, + user_data); } } diff --git a/src/core/lib/security/transport/security_connector.h b/src/core/lib/security/transport/security_connector.h index c2ddf5ee1eb..917100f8025 100644 --- a/src/core/lib/security/transport/security_connector.h +++ b/src/core/lib/security/transport/security_connector.h @@ -143,7 +143,8 @@ struct grpc_channel_security_connector { grpc_security_call_host_check_cb cb, void *user_data); void (*do_handshake)(grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, - grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline, + grpc_endpoint *nonsecure_endpoint, + gpr_slice_buffer *read_buffer, gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data); }; @@ -156,8 +157,9 @@ void grpc_channel_security_connector_check_call_host( /* Handshake. */ void grpc_channel_security_connector_do_handshake( grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *connector, - grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline, - grpc_security_handshake_done_cb cb, void *user_data); + grpc_endpoint *nonsecure_endpoint, gpr_slice_buffer *read_buffer, + gpr_timespec deadline, grpc_security_handshake_done_cb cb, + void *user_data); /* --- server_security_connector object. --- @@ -174,14 +176,16 @@ struct grpc_server_security_connector { void (*do_handshake)(grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc, grpc_tcp_server_acceptor *acceptor, - grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline, + grpc_endpoint *nonsecure_endpoint, + gpr_slice_buffer *read_buffer, gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data); }; void grpc_server_security_connector_do_handshake( grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc, grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint, - gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data); + gpr_slice_buffer *read_buffer, gpr_timespec deadline, + grpc_security_handshake_done_cb cb, void *user_data); void grpc_server_security_connector_shutdown( grpc_exec_ctx *exec_ctx, grpc_server_security_connector *connector); From 28ee43b9c83a82614d0f09e5b214ab4ae771584c Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 4 Aug 2016 11:11:46 -0700 Subject: [PATCH 153/279] Updated tests. --- test/core/bad_client/bad_client.c | 2 +- test/core/end2end/fixtures/h2_sockpair+trace.c | 4 ++-- test/core/end2end/fixtures/h2_sockpair.c | 4 ++-- test/core/end2end/fixtures/h2_sockpair_1byte.c | 4 ++-- test/core/end2end/fuzzers/api_fuzzer.c | 2 +- test/core/end2end/fuzzers/client_fuzzer.c | 2 +- test/core/end2end/fuzzers/server_fuzzer.c | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/core/bad_client/bad_client.c b/test/core/bad_client/bad_client.c index 24ee3387a0f..be88d4a69a9 100644 --- a/test/core/bad_client/bad_client.c +++ b/test/core/bad_client/bad_client.c @@ -130,7 +130,7 @@ void grpc_run_bad_client_test( grpc_server_start(a.server); transport = grpc_create_chttp2_transport(&exec_ctx, NULL, sfd.server, 0); server_setup_transport(&a, transport); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_exec_ctx_finish(&exec_ctx); /* Bind everything into the same pollset */ diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.c b/test/core/end2end/fixtures/h2_sockpair+trace.c index 6b0769b6088..b8a5257ab2a 100644 --- a/test/core/end2end/fixtures/h2_sockpair+trace.c +++ b/test/core/end2end/fixtures/h2_sockpair+trace.c @@ -108,7 +108,7 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture *f, grpc_create_chttp2_transport(&exec_ctx, client_args, sfd->client, 1); client_setup_transport(&exec_ctx, &cs, transport); GPR_ASSERT(f->client); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_exec_ctx_finish(&exec_ctx); } @@ -124,7 +124,7 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture *f, transport = grpc_create_chttp2_transport(&exec_ctx, server_args, sfd->server, 0); server_setup_transport(f, transport); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_exec_ctx_finish(&exec_ctx); } diff --git a/test/core/end2end/fixtures/h2_sockpair.c b/test/core/end2end/fixtures/h2_sockpair.c index 7be88f8a68e..a57990d6e73 100644 --- a/test/core/end2end/fixtures/h2_sockpair.c +++ b/test/core/end2end/fixtures/h2_sockpair.c @@ -107,7 +107,7 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture *f, grpc_create_chttp2_transport(&exec_ctx, client_args, sfd->client, 1); client_setup_transport(&exec_ctx, &cs, transport); GPR_ASSERT(f->client); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_exec_ctx_finish(&exec_ctx); } @@ -123,7 +123,7 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture *f, transport = grpc_create_chttp2_transport(&exec_ctx, server_args, sfd->server, 0); server_setup_transport(f, transport); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_exec_ctx_finish(&exec_ctx); } diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.c b/test/core/end2end/fixtures/h2_sockpair_1byte.c index 166654bcbfd..50aac8045a9 100644 --- a/test/core/end2end/fixtures/h2_sockpair_1byte.c +++ b/test/core/end2end/fixtures/h2_sockpair_1byte.c @@ -107,7 +107,7 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture *f, grpc_create_chttp2_transport(&exec_ctx, client_args, sfd->client, 1); client_setup_transport(&exec_ctx, &cs, transport); GPR_ASSERT(f->client); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_exec_ctx_finish(&exec_ctx); } @@ -123,7 +123,7 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture *f, transport = grpc_create_chttp2_transport(&exec_ctx, server_args, sfd->server, 0); server_setup_transport(f, transport); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_exec_ctx_finish(&exec_ctx); } diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c index 13b8bf7561a..96ea82d95ea 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.c +++ b/test/core/end2end/fuzzers/api_fuzzer.c @@ -258,7 +258,7 @@ static void do_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_transport *transport = grpc_create_chttp2_transport(exec_ctx, NULL, server, 0); grpc_server_setup_transport(exec_ctx, g_server, transport, NULL, NULL); - grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL); grpc_exec_ctx_sched(exec_ctx, fc->closure, GRPC_ERROR_NONE, NULL); } else { diff --git a/test/core/end2end/fuzzers/client_fuzzer.c b/test/core/end2end/fuzzers/client_fuzzer.c index 79b23d78569..00e650a30b9 100644 --- a/test/core/end2end/fuzzers/client_fuzzer.c +++ b/test/core/end2end/fuzzers/client_fuzzer.c @@ -63,7 +63,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { grpc_completion_queue *cq = grpc_completion_queue_create(NULL); grpc_transport *transport = grpc_create_chttp2_transport(&exec_ctx, NULL, mock_endpoint, 1); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_channel *channel = grpc_channel_create( &exec_ctx, "test-target", NULL, GRPC_CLIENT_DIRECT_CHANNEL, transport); diff --git a/test/core/end2end/fuzzers/server_fuzzer.c b/test/core/end2end/fuzzers/server_fuzzer.c index 80f568ac927..79eaad70c5d 100644 --- a/test/core/end2end/fuzzers/server_fuzzer.c +++ b/test/core/end2end/fuzzers/server_fuzzer.c @@ -71,7 +71,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { grpc_transport *transport = grpc_create_chttp2_transport(&exec_ctx, NULL, mock_endpoint, 0); grpc_server_setup_transport(&exec_ctx, server, transport, NULL, NULL); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_call *call1 = NULL; grpc_call_details call_details1; From a3e7bd85c064da9a1011fd31209e5af6a7ff8f38 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 4 Aug 2016 11:17:22 -0700 Subject: [PATCH 154/279] clang-format --- src/core/lib/channel/handshaker.c | 11 ++++---- src/core/lib/channel/handshaker.h | 3 +-- .../security/transport/security_connector.c | 26 +++++++------------ .../security/transport/security_connector.h | 3 +-- 4 files changed, 17 insertions(+), 26 deletions(-) diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c index 01fcbb20235..c0979f5e806 100644 --- a/src/core/lib/channel/handshaker.c +++ b/src/core/lib/channel/handshaker.c @@ -146,8 +146,8 @@ void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, static void call_next_handshaker(grpc_exec_ctx* exec_ctx, grpc_endpoint* endpoint, grpc_channel_args* args, - gpr_slice_buffer* read_buffer, - void* user_data, grpc_error* error) { + gpr_slice_buffer* read_buffer, void* user_data, + grpc_error* error) { grpc_handshake_manager* mgr = user_data; GPR_ASSERT(mgr->state != NULL); GPR_ASSERT(mgr->state->index < mgr->count); @@ -166,10 +166,9 @@ static void call_next_handshaker(grpc_exec_ctx* exec_ctx, user_data = mgr->state->final_user_data; } // Invoke handshaker. - grpc_handshaker_do_handshake(exec_ctx, mgr->handshakers[mgr->state->index], - endpoint, args, read_buffer, - mgr->state->deadline, mgr->state->acceptor, - cb, user_data); + grpc_handshaker_do_handshake( + exec_ctx, mgr->handshakers[mgr->state->index], endpoint, args, + read_buffer, mgr->state->deadline, mgr->state->acceptor, cb, user_data); ++mgr->state->index; // If this is the last handshaker, clean up state. if (mgr->state->index == mgr->count) { diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index fac4935b16b..b276f6028c1 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -79,8 +79,7 @@ struct grpc_handshaker_vtable { /// \a acceptor will be NULL for client-side handshakers. void (*do_handshake)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, grpc_endpoint* endpoint, grpc_channel_args* args, - gpr_slice_buffer* read_buffer, - gpr_timespec deadline, + gpr_slice_buffer* read_buffer, gpr_timespec deadline, grpc_tcp_server_acceptor* acceptor, grpc_handshaker_done_cb cb, void* user_data); }; diff --git a/src/core/lib/security/transport/security_connector.c b/src/core/lib/security/transport/security_connector.c index 1ee12319005..0eca46eb525 100644 --- a/src/core/lib/security/transport/security_connector.c +++ b/src/core/lib/security/transport/security_connector.c @@ -325,14 +325,11 @@ static void fake_channel_do_handshake(grpc_exec_ctx *exec_ctx, cb, user_data); } -static void fake_server_do_handshake(grpc_exec_ctx *exec_ctx, - grpc_server_security_connector *sc, - grpc_tcp_server_acceptor *acceptor, - grpc_endpoint *nonsecure_endpoint, - gpr_slice_buffer *read_buffer, - gpr_timespec deadline, - grpc_security_handshake_done_cb cb, - void *user_data) { +static void fake_server_do_handshake( + grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc, + grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint, + gpr_slice_buffer *read_buffer, gpr_timespec deadline, + grpc_security_handshake_done_cb cb, void *user_data) { grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(0), &sc->base, false, nonsecure_endpoint, read_buffer, deadline, cb, user_data); @@ -447,14 +444,11 @@ static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx, } } -static void ssl_server_do_handshake(grpc_exec_ctx *exec_ctx, - grpc_server_security_connector *sc, - grpc_tcp_server_acceptor *acceptor, - grpc_endpoint *nonsecure_endpoint, - gpr_slice_buffer *read_buffer, - gpr_timespec deadline, - grpc_security_handshake_done_cb cb, - void *user_data) { +static void ssl_server_do_handshake( + grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc, + grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint, + gpr_slice_buffer *read_buffer, gpr_timespec deadline, + grpc_security_handshake_done_cb cb, void *user_data) { grpc_ssl_server_security_connector *c = (grpc_ssl_server_security_connector *)sc; tsi_handshaker *handshaker; diff --git a/src/core/lib/security/transport/security_connector.h b/src/core/lib/security/transport/security_connector.h index 917100f8025..0b5b44bf1a0 100644 --- a/src/core/lib/security/transport/security_connector.h +++ b/src/core/lib/security/transport/security_connector.h @@ -158,8 +158,7 @@ void grpc_channel_security_connector_check_call_host( void grpc_channel_security_connector_do_handshake( grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *connector, grpc_endpoint *nonsecure_endpoint, gpr_slice_buffer *read_buffer, - gpr_timespec deadline, grpc_security_handshake_done_cb cb, - void *user_data); + gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data); /* --- server_security_connector object. --- From 76db7f9a7cdf6b5fd6706037c72de1dd131b181e Mon Sep 17 00:00:00 2001 From: chedeti Date: Thu, 4 Aug 2016 11:56:54 -0700 Subject: [PATCH 155/279] use boost::make_shared --- include/grpc++/impl/codegen/thrift_serializer.h | 14 ++++++-------- tools/grift/README.md | 3 +-- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/include/grpc++/impl/codegen/thrift_serializer.h b/include/grpc++/impl/codegen/thrift_serializer.h index 04dcc699deb..fcb0ffaad6e 100644 --- a/include/grpc++/impl/codegen/thrift_serializer.h +++ b/include/grpc++/impl/codegen/thrift_serializer.h @@ -111,8 +111,8 @@ class ThriftSerializer { Serialize(fields, &byte_buffer, &byte_buffer_size); - gpr_slice slice = - gpr_slice_from_copied_buffer((char*)byte_buffer, byte_buffer_size); + gpr_slice slice = gpr_slice_from_copied_buffer( + reinterpret_cast(byte_buffer), byte_buffer_size); *bp = grpc_raw_byte_buffer_create(&slice, 1); @@ -131,12 +131,12 @@ class ThriftSerializer { last_deserialized_ = true; // reset buffer transport - buffer_->resetBuffer((uint8_t*)serialized_buffer, length); + buffer_->resetBuffer(const_cast(serialized_buffer), length); // read the protocol version if necessary if (serialize_version_) { std::string name = ""; - TMessageType mt = (TMessageType)0; + TMessageType mt = static_cast(0); int32_t seq_id = 0; protocol_->readMessageBegin(name, mt, seq_id); } @@ -200,11 +200,9 @@ class ThriftSerializer { bool serialize_version_; void prepare() { - - buffer_.reset(new TMemoryBuffer()); - + buffer_ = boost::make_shared(*(new TMemoryBuffer())); // create a protocol for the memory buffer transport - protocol_.reset(new Protocol(buffer_)); + protocol_ = std::make_shared(*(new Protocol(buffer_))); prepared_ = true; } diff --git a/tools/grift/README.md b/tools/grift/README.md index 2525f9b83dd..7cbbdc567bf 100644 --- a/tools/grift/README.md +++ b/tools/grift/README.md @@ -23,5 +23,4 @@ grift uses Compact Protocol to serialize thrift messages. #Installation Before Installing thrift make sure to apply this [patch](grpc_plugins_generator.patch) to third_party/thrift. -Go to third_party/thrift and follow the [INSTALLATION](https://github.com/apache/thrift.git) instructions to -install thrift. \ No newline at end of file +Go to third_party/thrift and follow the [INSTALLATION](https://github.com/apache/thrift.git) instructions to install thrift with commit id bcad91771b7f0bff28a1cac1981d7ef2b9bcef3c. \ No newline at end of file From 2135a1b557f8b992186d5317cb767ac4dbcdfe5c Mon Sep 17 00:00:00 2001 From: siddharthshukla Date: Thu, 4 Aug 2016 02:11:53 +0200 Subject: [PATCH 156/279] add PyPy to testing toolchain --- tools/run_tests/run_tests.py | 92 +++++++++++++++++++++++++++++------- 1 file changed, 74 insertions(+), 18 deletions(-) diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 542415d9085..fde9297beb5 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -139,6 +139,53 @@ def _is_use_docker_child(): return True if os.getenv('RUN_TESTS_COMMAND') else False +_PythonConfigVars = collections.namedtuple( + '_ConfigVars', ['shell', 'builder', 'builder_prefix_arguments', + 'venv_relative_python', 'toolchain', 'runner']) + + +def _python_config_generator(name, major, minor, bits, config_vars): + return PythonConfig( + name, + config_vars.shell + config_vars.builder + config_vars.builder_prefix_arguments + [ + _python_pattern_function(major=major, minor=minor, bits=bits)] + [ + name] + config_vars.venv_relative_python + config_vars.toolchain, + config_vars.shell + config_vars.runner + [ + os.path.join(name, config_vars.venv_relative_python[0])]) + + +def _pypy_config_generator(name, major, config_vars): + return PythonConfig( + name, + config_vars.shell + config_vars.builder + config_vars.builder_prefix_arguments + [ + _pypy_pattern_function(major=major)] + [ + name] + config_vars.venv_relative_python + config_vars.toolchain, + config_vars.shell + config_vars.runner + [ + os.path.join(name, config_vars.venv_relative_python[0])]) + + +def _python_pattern_function(major, minor, bits): + # Bit-ness is handled by the test machine's environment + if os.name == "nt": + if bits == "64": + return '/c/Python{major}{minor}/python.exe'.format( + major=major, minor=minor, bits=bits) + else: + return '/c/Python{major}{minor}_{bits}bits/python.exe'.format( + major=major, minor=minor, bits=bits) + else: + return 'python{major}.{minor}'.format(major=major, minor=minor) + + +def _pypy_pattern_function(major): + if major == '2': + return 'pypy' + elif major == '3': + return 'pypy3' + else: + raise ValueError("Unknown PyPy major version") + + class CLanguage(object): def __init__(self, make_target, test_lang): @@ -471,36 +518,40 @@ class PythonLanguage(object): bits = '32' else: bits = '64' + if os.name == 'nt': shell = ['bash'] builder = [os.path.abspath('tools/run_tests/build_python_msys2.sh')] builder_prefix_arguments = ['MINGW{}'.format(bits)] venv_relative_python = ['Scripts/python.exe'] toolchain = ['mingw32'] - python_pattern_function = lambda major, minor, bits: ( - '/c/Python{major}{minor}/python.exe'.format(major=major, minor=minor, bits=bits) - if bits == '64' else - '/c/Python{major}{minor}_{bits}bits/python.exe'.format( - major=major, minor=minor, bits=bits)) else: shell = [] builder = [os.path.abspath('tools/run_tests/build_python.sh')] builder_prefix_arguments = [] venv_relative_python = ['bin/python'] toolchain = ['unix'] - # Bit-ness is handled by the test machine's environment - python_pattern_function = lambda major, minor, bits: 'python{major}.{minor}'.format(major=major, minor=minor) + runner = [os.path.abspath('tools/run_tests/run_python.sh')] - python_config_generator = lambda name, major, minor, bits: PythonConfig( - name, - shell + builder + builder_prefix_arguments - + [python_pattern_function(major=major, minor=minor, bits=bits)] - + [name] + venv_relative_python + toolchain, - shell + runner + [os.path.join(name, venv_relative_python[0])]) - python27_config = python_config_generator(name='py27', major='2', minor='7', bits=bits) - python34_config = python_config_generator(name='py34', major='3', minor='4', bits=bits) - python35_config = python_config_generator(name='py35', major='3', minor='5', bits=bits) - python36_config = python_config_generator(name='py36', major='3', minor='6', bits=bits) + config_vars = _PythonConfigVars(shell, builder, builder_prefix_arguments, + venv_relative_python, toolchain, runner) + python27_config = _python_config_generator(name='py27', major='2', + minor='7', bits=bits, + config_vars=config_vars) + python34_config = _python_config_generator(name='py34', major='3', + minor='4', bits=bits, + config_vars=config_vars) + python35_config = _python_config_generator(name='py35', major='3', + minor='5', bits=bits, + config_vars=config_vars) + python36_config = _python_config_generator(name='py36', major='3', + minor='6', bits=bits, + config_vars=config_vars) + pypy27_config = _pypy_config_generator(name='pypy', major='2', + config_vars=config_vars) + pypy32_config = _pypy_config_generator(name='pypy3', major='3', + config_vars=config_vars) + if args.compiler == 'default': if os.name == 'nt': return (python27_config,) @@ -514,6 +565,10 @@ class PythonLanguage(object): return (python35_config,) elif args.compiler == 'python3.6': return (python36_config,) + elif args.compiler == 'pypy': + return (pypy27_config,) + elif args.compiler == 'pypy3': + return (pypy32_config,) else: raise Exception('Compiler %s not supported.' % args.compiler) @@ -893,6 +948,7 @@ def runs_per_test_type(arg_str): msg = '\'{}\' is not a positive integer or \'inf\''.format(arg_str) raise argparse.ArgumentTypeError(msg) + # parse command line argp = argparse.ArgumentParser(description='Run grpc tests.') argp.add_argument('-c', '--config', @@ -946,7 +1002,7 @@ argp.add_argument('--compiler', 'gcc4.4', 'gcc4.6', 'gcc4.9', 'gcc5.3', 'clang3.4', 'clang3.5', 'clang3.6', 'clang3.7', 'vs2010', 'vs2013', 'vs2015', - 'python2.7', 'python3.4', 'python3.5', 'python3.6', + 'python2.7', 'python3.4', 'python3.5', 'python3.6', 'pypy', 'pypy3', 'node0.12', 'node4', 'node5', 'coreclr'], default='default', From a7ee93864a2e822ec510dccec19012e59acdeb7d Mon Sep 17 00:00:00 2001 From: chedeti Date: Thu, 4 Aug 2016 14:42:35 -0700 Subject: [PATCH 157/279] remove const in Deserialize --- include/grpc++/impl/codegen/thrift_serializer.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/include/grpc++/impl/codegen/thrift_serializer.h b/include/grpc++/impl/codegen/thrift_serializer.h index fcb0ffaad6e..7308a1577c8 100644 --- a/include/grpc++/impl/codegen/thrift_serializer.h +++ b/include/grpc++/impl/codegen/thrift_serializer.h @@ -122,8 +122,7 @@ class ThriftSerializer { // Deserialize the passed char array into the passed type, returns the number // of bytes that have been consumed from the passed string. template - uint32_t Deserialize(const uint8_t* serialized_buffer, size_t length, - T* fields) { + uint32_t Deserialize(uint8_t* serialized_buffer, size_t length, T* fields) { // prepare buffer if necessary if (!prepared_) { prepare(); @@ -131,7 +130,7 @@ class ThriftSerializer { last_deserialized_ = true; // reset buffer transport - buffer_->resetBuffer(const_cast(serialized_buffer), length); + buffer_->resetBuffer(serialized_buffer, length); // read the protocol version if necessary if (serialize_version_) { @@ -200,10 +199,9 @@ class ThriftSerializer { bool serialize_version_; void prepare() { - buffer_ = boost::make_shared(*(new TMemoryBuffer())); + buffer_ = boost::make_shared(); // create a protocol for the memory buffer transport - protocol_ = std::make_shared(*(new Protocol(buffer_))); - + protocol_ = std::make_shared(buffer_); prepared_ = true; } From 6801b225a811934f54abfe87702af82759f25942 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Thu, 4 Aug 2016 14:50:45 -0700 Subject: [PATCH 158/279] Repeat of commit f808eee for interop tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trying to fix: + cd grpc + tools/jenkins/run_interop.sh ++ dirname tools/jenkins/run_interop.sh + cd tools/jenkins/../.. + tools/run_tests/run_interop_tests.py -l all -s all --cloud_to_prod \ —cloud_to_prod_auth --use_docker --http2_interop -t -j 12 START: Building interop docker images. START: build_docker_php7 Traceback (most recent call last): File "tools/run_tests/run_interop_tests.py", line 738, in build_jobs, newline_on_success=True, maxjobs=args.jobs) File "tools/run_tests/jobset.py", line 456, in run if not js.start(cmdline): File "tools/run_tests/jobset.py", line 369, in start self._add_env) File "tools/run_tests/jobset.py", line 218, in __init__ self.start() File "tools/run_tests/jobset.py", line 228, in start env = sanitized_environment(env) File "tools/run_tests/jobset.py", line 53, in sanitized_environment sanitized[str(key).encode()] = str(value).encode() UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 20: ordinal not in range(128) --- tools/jenkins/run_interop.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/jenkins/run_interop.sh b/tools/jenkins/run_interop.sh index a424aea7fc4..4a7bff33891 100755 --- a/tools/jenkins/run_interop.sh +++ b/tools/jenkins/run_interop.sh @@ -31,6 +31,8 @@ # This script is invoked by Jenkins and runs interop test suite. set -ex +export LANG=en_US.UTF-8 + # Enter the gRPC repo root cd $(dirname $0)/../.. From 31871df58f2a99b21c7a85aebac73ed6d9bdaf9b Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Thu, 4 Aug 2016 15:12:53 -0700 Subject: [PATCH 159/279] =?UTF-8?q?@pgrosu=E2=80=99s=20fix=20of=20Go?= =?UTF-8?q?=E2=80=99s=20docker=20build?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh index e8915493422..5c597a12efa 100755 --- a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh @@ -42,6 +42,7 @@ cp -r /var/local/jenkins/service_account $HOME || true # Get dependencies from GitHub # NOTE: once grpc-go dependencies change, this needs to be updated manually # but we don't expect this to happen any time soon. +go get google.golang.org/cloud/compute/metadata go get github.com/golang/protobuf/proto go get golang.org/x/net/context go get golang.org/x/net/trace From d07c17e3430bbf1cc1a802b76cf57175bbb6603c Mon Sep 17 00:00:00 2001 From: chedeti Date: Thu, 4 Aug 2016 17:52:00 -0700 Subject: [PATCH 160/279] fix Dockerfile --- tools/grift/Dockerfile | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/grift/Dockerfile b/tools/grift/Dockerfile index 954640f0df0..223ee939927 100644 --- a/tools/grift/Dockerfile +++ b/tools/grift/Dockerfile @@ -43,21 +43,25 @@ RUN apt-get update && \ cmake \ libiberty-dev \ g++ unzip \ - curl make automake libtool + curl make automake libtool libboost-dev # Configure git RUN git config --global user.name "Jenkins" && \ git config --global user.email "jenkins@grpc" +# Clone gRPC RUN git clone https://github.com/grpc/grpc +# Update Submodules RUN cd grpc && git submodule update --init -RUN cd grpc/third_party/thrift && git am --signoff < ../../tools/grift/grpc_plugins_generator.patch - +# Install protobuf RUN cd grpc/third_party/protobuf && ./autogen.sh && ./configure && \ make -j && make check -j && make install && ldconfig +# Install gRPC RUN cd grpc && make -j && make install -RUN cd grpc/third_party/thrift && ./bootstrap.sh && ./configure && make -j && make install \ No newline at end of file +# Install thrift +RUN cd grpc/third_party/thrift && git am --signoff < ../../tools/grift/grpc_plugins_generator.patch && \ + ./bootstrap.sh && ./configure && make -j && make install \ No newline at end of file From 4f17395b81508ceedc824602e52876ae94d13c43 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 5 Aug 2016 01:32:34 -0700 Subject: [PATCH 161/279] Properly use unique_ptr rather than explicitly deleting server context wrappers in QPS test --- test/cpp/qps/server_async.cc | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index dea87463312..082b4bc72fe 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -108,14 +108,14 @@ class AsyncQpsServerTest : public Server { auto request_unary = std::bind(request_unary_function, &async_service_, _1, _2, _3, srv_cqs_[j].get(), srv_cqs_[j].get(), _4); - contexts_.push_front( + contexts_.emplace_back( new ServerRpcContextUnaryImpl(request_unary, process_rpc_bound)); } if (request_streaming_function) { auto request_streaming = std::bind(request_streaming_function, &async_service_, _1, _2, srv_cqs_[j].get(), srv_cqs_[j].get(), _3); - contexts_.push_front(new ServerRpcContextStreamingImpl( + contexts_.emplace_back(new ServerRpcContextStreamingImpl( request_streaming, process_rpc_bound)); } } @@ -146,10 +146,6 @@ class AsyncQpsServerTest : public Server { while ((*cq)->Next(&got_tag, &ok)) ; } - while (!contexts_.empty()) { - delete contexts_.front(); - contexts_.pop_front(); - } } private: @@ -336,7 +332,7 @@ class AsyncQpsServerTest : public Server { std::unique_ptr server_; std::vector> srv_cqs_; ServiceType async_service_; - std::forward_list contexts_; + std::vector> contexts_; struct PerThreadShutdownState { mutable std::mutex mutex; From 773ecd62ddeea4c483d3d248fa30a978d2520ee8 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 5 Aug 2016 09:26:56 -0700 Subject: [PATCH 162/279] Dramatically reduce time required to complete sync test when running with lots of threads (by parallelizing shutdown of course) --- test/cpp/qps/client.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index 4045e13460f..8a750196b26 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -169,6 +169,7 @@ class Client { // Must call AwaitThreadsCompletion before destructor to avoid a race // between destructor and invocation of virtual ThreadFunc void AwaitThreadsCompletion() { + gpr_atm_rel_store(&thread_pool_done_, static_cast(1)); DestroyMultithreading(); std::unique_lock g(thread_completion_mu_); while (threads_remaining_ != 0) { @@ -180,6 +181,7 @@ class Client { bool closed_loop_; void StartThreads(size_t num_threads) { + gpr_atm_rel_store(&thread_pool_done_, static_cast(0)); threads_remaining_ = num_threads; for (size_t i = 0; i < num_threads; i++) { threads_.emplace_back(new Thread(this, i)); @@ -241,16 +243,11 @@ class Client { class Thread { public: Thread(Client* client, size_t idx) - : done_(false), - client_(client), + : client_(client), idx_(idx), impl_(&Thread::ThreadFunc, this) {} ~Thread() { - { - std::lock_guard g(mu_); - done_ = true; - } impl_.join(); } @@ -280,11 +277,14 @@ class Client { if (entry.used()) { histogram_.Add(entry.value()); } + bool done = false; if (!thread_still_ok) { gpr_log(GPR_ERROR, "Finishing client thread due to RPC error"); - done_ = true; + done = true; } - if (done_) { + done = done || (gpr_atm_acq_load(&client_->thread_pool_done_) != + static_cast(0)); + if (done) { client_->CompleteThread(); return; } @@ -292,7 +292,6 @@ class Client { } std::mutex mu_; - bool done_; Histogram histogram_; Client* client_; const size_t idx_; @@ -305,6 +304,7 @@ class Client { InterarrivalTimer interarrival_timer_; std::vector next_time_; + gpr_atm thread_pool_done_; std::mutex thread_completion_mu_; size_t threads_remaining_; std::condition_variable threads_complete_; From b561102794ed4a779313e03512d5f79788fe185f Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Fri, 5 Aug 2016 09:41:49 -0700 Subject: [PATCH 163/279] change location of nuget back to normal --- tools/run_tests/pre_build_csharp.bat | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/run_tests/pre_build_csharp.bat b/tools/run_tests/pre_build_csharp.bat index 0dc22b8a1fb..580d5638fda 100644 --- a/tools/run_tests/pre_build_csharp.bat +++ b/tools/run_tests/pre_build_csharp.bat @@ -35,8 +35,7 @@ setlocal cd /d %~dp0\..\.. @rem Location of nuget.exe -@rem TODO: change this before submitting. This is only for migrating nuget -set NUGET=C:\nuget_temp\nuget.exe +set NUGET=C:\nuget\nuget.exe if exist %NUGET% ( @rem Restore Grpc packages by packages since Nuget client 3.4.4 doesnt support restore From 25128f1adf836e63cf76b6666fba8bcf31d7a5a8 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 5 Aug 2016 09:45:03 -0700 Subject: [PATCH 164/279] Better ending for open-loop tests: never wait more than 1 second if we are in termination mode --- test/cpp/qps/client.h | 2 +- test/cpp/qps/client_sync.cc | 31 +++++++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index 8a750196b26..1f98a7fc286 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -179,6 +179,7 @@ class Client { protected: bool closed_loop_; + gpr_atm thread_pool_done_; void StartThreads(size_t num_threads) { gpr_atm_rel_store(&thread_pool_done_, static_cast(0)); @@ -304,7 +305,6 @@ class Client { InterarrivalTimer interarrival_timer_; std::vector next_time_; - gpr_atm thread_pool_done_; std::mutex thread_completion_mu_; size_t threads_remaining_; std::condition_variable threads_complete_; diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc index 25c78235532..b677fc1070e 100644 --- a/test/cpp/qps/client_sync.cc +++ b/test/cpp/qps/client_sync.cc @@ -79,10 +79,29 @@ class SynchronousClient virtual ~SynchronousClient(){}; protected: - void WaitToIssue(int thread_idx) { + // WaitToIssue returns false if we realize that we need to break out + bool WaitToIssue(int thread_idx) { if (!closed_loop_) { - gpr_sleep_until(NextIssueTime(thread_idx)); + gpr_timespec next_issue_time = NextIssueTime(thread_idx); + // Avoid sleeping for too long continuously because we might + // need to terminate before then. This is an issue since + // exponential distribution can occasionally produce bad outliers + while (true) { + gpr_timespec one_sec_delay = + gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_seconds(1, GPR_TIMESPAN)); + if (gpr_time_cmp(next_issue_time, one_sec_delay) <= 0) { + gpr_sleep_until(next_issue_time); + return true; + } else { + gpr_sleep_until(one_sec_delay); + if (gpr_atm_acq_load(&thread_pool_done_) != static_cast(0)) { + return false; + } + } + } } + return true; } size_t num_threads_; @@ -101,7 +120,9 @@ class SynchronousUnaryClient GRPC_FINAL : public SynchronousClient { ~SynchronousUnaryClient() {} bool ThreadFunc(HistogramEntry* entry, size_t thread_idx) GRPC_OVERRIDE { - WaitToIssue(thread_idx); + if (!WaitToIssue(thread_idx)) { + return true; + } auto* stub = channels_[thread_idx % channels_.size()].get_stub(); double start = UsageTimer::Now(); GPR_TIMER_SCOPE("SynchronousUnaryClient::ThreadFunc", 0); @@ -144,7 +165,9 @@ class SynchronousStreamingClient GRPC_FINAL : public SynchronousClient { } bool ThreadFunc(HistogramEntry* entry, size_t thread_idx) GRPC_OVERRIDE { - WaitToIssue(thread_idx); + if (!WaitToIssue(thread_idx)) { + return true; + } GPR_TIMER_SCOPE("SynchronousStreamingClient::ThreadFunc", 0); double start = UsageTimer::Now(); if (stream_[thread_idx]->Write(request_) && From d02988d6b55c7724548ed556c319222f5e2cf665 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 5 Aug 2016 09:47:47 -0700 Subject: [PATCH 165/279] clang-format --- test/cpp/qps/client.h | 14 +++++--------- test/cpp/qps/client_sync.cc | 24 ++++++++++++------------ 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index 1f98a7fc286..5b1a1c3b827 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -244,13 +244,9 @@ class Client { class Thread { public: Thread(Client* client, size_t idx) - : client_(client), - idx_(idx), - impl_(&Thread::ThreadFunc, this) {} + : client_(client), idx_(idx), impl_(&Thread::ThreadFunc, this) {} - ~Thread() { - impl_.join(); - } + ~Thread() { impl_.join(); } void BeginSwap(Histogram* n) { std::lock_guard g(mu_); @@ -278,13 +274,13 @@ class Client { if (entry.used()) { histogram_.Add(entry.value()); } - bool done = false; + bool done = false; if (!thread_still_ok) { gpr_log(GPR_ERROR, "Finishing client thread due to RPC error"); done = true; } - done = done || (gpr_atm_acq_load(&client_->thread_pool_done_) != - static_cast(0)); + done = done || (gpr_atm_acq_load(&client_->thread_pool_done_) != + static_cast(0)); if (done) { client_->CompleteThread(); return; diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc index b677fc1070e..53e004ffa02 100644 --- a/test/cpp/qps/client_sync.cc +++ b/test/cpp/qps/client_sync.cc @@ -87,18 +87,18 @@ class SynchronousClient // need to terminate before then. This is an issue since // exponential distribution can occasionally produce bad outliers while (true) { - gpr_timespec one_sec_delay = - gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_seconds(1, GPR_TIMESPAN)); - if (gpr_time_cmp(next_issue_time, one_sec_delay) <= 0) { - gpr_sleep_until(next_issue_time); - return true; - } else { - gpr_sleep_until(one_sec_delay); - if (gpr_atm_acq_load(&thread_pool_done_) != static_cast(0)) { - return false; - } - } + gpr_timespec one_sec_delay = + gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_seconds(1, GPR_TIMESPAN)); + if (gpr_time_cmp(next_issue_time, one_sec_delay) <= 0) { + gpr_sleep_until(next_issue_time); + return true; + } else { + gpr_sleep_until(one_sec_delay); + if (gpr_atm_acq_load(&thread_pool_done_) != static_cast(0)) { + return false; + } + } } } return true; From fb1a318b6f04f0635525f65ed69407a77b28493e Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 5 Aug 2016 19:33:59 +0200 Subject: [PATCH 166/279] Hopefully fixing #7639. --- .../interoptest/grpc_interop_go/build_interop.sh | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh index e8915493422..6e7813ef0b1 100755 --- a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh @@ -31,6 +31,8 @@ # Builds Go interop server and client in a base image. set -e +go get google.golang.org/grpc + # Clone just the grpc-go source code without any dependencies. # We are cloning from a local git repo that contains the right revision # to test instead of using "go get" to download from Github directly. @@ -39,15 +41,6 @@ git clone --recursive /var/local/jenkins/grpc-go src/google.golang.org/grpc # copy service account keys if available cp -r /var/local/jenkins/service_account $HOME || true -# Get dependencies from GitHub -# NOTE: once grpc-go dependencies change, this needs to be updated manually -# but we don't expect this to happen any time soon. -go get github.com/golang/protobuf/proto -go get golang.org/x/net/context -go get golang.org/x/net/trace -go get golang.org/x/oauth2 -go get google.golang.org/cloud - # Build the interop client and server (cd src/google.golang.org/grpc/interop/client && go install) (cd src/google.golang.org/grpc/interop/server && go install) From ba02ee1adce3a22cb2f83c79bcaf2c26b28f0893 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 5 Aug 2016 20:12:22 +0200 Subject: [PATCH 167/279] Using the interop dependencies instead. --- tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh index 6e7813ef0b1..82bb4a64835 100755 --- a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh @@ -31,7 +31,7 @@ # Builds Go interop server and client in a base image. set -e -go get google.golang.org/grpc +go get google.golang.org/grpc/interop # Clone just the grpc-go source code without any dependencies. # We are cloning from a local git repo that contains the right revision From 9eedb4ffd74aed8d246a07f8007960b2bc167f55 Mon Sep 17 00:00:00 2001 From: siddharthshukla Date: Tue, 12 Jul 2016 14:02:12 +0200 Subject: [PATCH 168/279] Switch init/shutdown: lib-wide -> per-object Incremental changes towards PyPy support. --- .../grpcio/grpc/_cython/_cygrpc/call.pyx.pxi | 2 ++ .../grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi | 2 ++ .../grpc/_cython/_cygrpc/completion_queue.pyx.pxi | 2 ++ .../grpc/_cython/_cygrpc/credentials.pyx.pxi | 14 ++++++++++++++ .../grpcio/grpc/_cython/_cygrpc/records.pyx.pxi | 12 ++++++++++++ .../grpcio/grpc/_cython/_cygrpc/server.pyx.pxi | 2 ++ src/python/grpcio/grpc/_cython/cygrpc.pyx | 4 ---- 7 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi index ba60986143c..cc3bd7a0672 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi @@ -34,6 +34,7 @@ cdef class Call: def __cinit__(self): # Create an *empty* call + grpc_init() self.c_call = NULL self.references = [] @@ -106,6 +107,7 @@ cdef class Call: def __dealloc__(self): if self.c_call != NULL: grpc_call_destroy(self.c_call) + grpc_shutdown() # The object *should* always be valid from Python. Used for debugging. @property diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi index 54164014313..3df937eb14f 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi @@ -34,6 +34,7 @@ cdef class Channel: def __cinit__(self, bytes target, ChannelArgs arguments=None, ChannelCredentials channel_credentials=None): + grpc_init() cdef grpc_channel_args *c_arguments = NULL cdef char *c_target = NULL self.c_channel = NULL @@ -103,3 +104,4 @@ cdef class Channel: def __dealloc__(self): if self.c_channel != NULL: grpc_channel_destroy(self.c_channel) + grpc_shutdown() diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi index 5955021ceb7..a258ba40639 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi @@ -38,6 +38,7 @@ cdef int _INTERRUPT_CHECK_PERIOD_MS = 200 cdef class CompletionQueue: def __cinit__(self): + grpc_init() with nogil: self.c_completion_queue = grpc_completion_queue_create(NULL) self.is_shutting_down = False @@ -129,3 +130,4 @@ cdef class CompletionQueue: self.c_completion_queue, c_deadline, NULL) self._interpret_event(event) grpc_completion_queue_destroy(self.c_completion_queue) + grpc_shutdown() diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index 035ac49a8bf..04872b9c09a 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -33,6 +33,7 @@ cimport cpython cdef class ChannelCredentials: def __cinit__(self): + grpc_init() self.c_credentials = NULL self.c_ssl_pem_key_cert_pair.private_key = NULL self.c_ssl_pem_key_cert_pair.certificate_chain = NULL @@ -47,11 +48,13 @@ cdef class ChannelCredentials: def __dealloc__(self): if self.c_credentials != NULL: grpc_channel_credentials_release(self.c_credentials) + grpc_shutdown() cdef class CallCredentials: def __cinit__(self): + grpc_init() self.c_credentials = NULL self.references = [] @@ -64,17 +67,20 @@ cdef class CallCredentials: def __dealloc__(self): if self.c_credentials != NULL: grpc_call_credentials_release(self.c_credentials) + grpc_shutdown() cdef class ServerCredentials: def __cinit__(self): + grpc_init() self.c_credentials = NULL self.references = [] def __dealloc__(self): if self.c_credentials != NULL: grpc_server_credentials_release(self.c_credentials) + grpc_shutdown() cdef class CredentialsMetadataPlugin: @@ -90,6 +96,7 @@ cdef class CredentialsMetadataPlugin: successful). name (bytes): Plugin name. """ + grpc_init() if not callable(plugin_callback): raise ValueError('expected callable plugin_callback') self.plugin_callback = plugin_callback @@ -105,10 +112,14 @@ cdef class CredentialsMetadataPlugin: cpython.Py_INCREF(self) return result + def __dealloc__(self): + grpc_shutdown() + cdef class AuthMetadataContext: def __cinit__(self): + grpc_init() self.context.service_url = NULL self.context.method_name = NULL @@ -120,6 +131,9 @@ cdef class AuthMetadataContext: def method_name(self): return self.context.method_name + def __dealloc__(self): + grpc_shutdown() + cdef void plugin_get_metadata( void *state, grpc_auth_metadata_context context, diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi index 54b3d00dfc7..834a44123d4 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi @@ -176,12 +176,14 @@ cdef class Timespec: cdef class CallDetails: def __cinit__(self): + grpc_init() with nogil: grpc_call_details_init(&self.c_details) def __dealloc__(self): with nogil: grpc_call_details_destroy(&self.c_details) + grpc_shutdown() @property def method(self): @@ -232,6 +234,7 @@ cdef class Event: cdef class ByteBuffer: def __cinit__(self, bytes data): + grpc_init() if data is None: self.c_byte_buffer = NULL return @@ -288,6 +291,7 @@ cdef class ByteBuffer: def __dealloc__(self): if self.c_byte_buffer != NULL: grpc_byte_buffer_destroy(self.c_byte_buffer) + grpc_shutdown() cdef class SslPemKeyCertPair: @@ -319,6 +323,7 @@ cdef class ChannelArg: cdef class ChannelArgs: def __cinit__(self, args): + grpc_init() self.args = list(args) for arg in self.args: if not isinstance(arg, ChannelArg): @@ -333,6 +338,7 @@ cdef class ChannelArgs: def __dealloc__(self): with nogil: gpr_free(self.c_args.arguments) + grpc_shutdown() def __len__(self): # self.args is never stale; it's only updated from this file @@ -399,6 +405,7 @@ cdef class _MetadataIterator: cdef class Metadata: def __cinit__(self, metadata): + grpc_init() self.metadata = list(metadata) for metadatum in metadata: if not isinstance(metadatum, Metadatum): @@ -420,6 +427,7 @@ cdef class Metadata: # it'd be nice if that were documented somewhere...) # TODO(atash): document this in the C core grpc_metadata_array_destroy(&self.c_metadata_array) + grpc_shutdown() def __len__(self): return self.c_metadata_array.count @@ -437,6 +445,7 @@ cdef class Metadata: cdef class Operation: def __cinit__(self): + grpc_init() self.references = [] self._received_status_details = NULL self._received_status_details_capacity = 0 @@ -529,6 +538,7 @@ cdef class Operation: # This means that we need to clean up after receive_status_on_client. if self.c_op.type == GRPC_OP_RECV_STATUS_ON_CLIENT: gpr_free(self._received_status_details) + grpc_shutdown() def operation_send_initial_metadata(Metadata metadata, int flags): cdef Operation op = Operation() @@ -645,6 +655,7 @@ cdef class _OperationsIterator: cdef class Operations: def __cinit__(self, operations): + grpc_init() self.operations = list(operations) # normalize iterable self.c_ops = NULL self.c_nops = 0 @@ -667,6 +678,7 @@ cdef class Operations: def __dealloc__(self): with nogil: gpr_free(self.c_ops) + grpc_shutdown() def __iter__(self): return _OperationsIterator(self) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index 4f2d51b03f5..ca2b8311147 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -35,6 +35,7 @@ import time cdef class Server: def __cinit__(self, ChannelArgs arguments=None): + grpc_init() cdef grpc_channel_args *c_arguments = NULL self.references = [] self.registered_completion_queues = [] @@ -172,3 +173,4 @@ cdef class Server: while not self.is_shutdown: time.sleep(0) grpc_server_destroy(self.c_server) + grpc_shutdown() diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx index a9520b9c0fa..08089994a95 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pyx +++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx @@ -55,12 +55,8 @@ cdef extern from "Python.h": def _initialize(): - grpc_init() grpc_set_ssl_roots_override_callback( ssl_roots_override_callback) - if Py_AtExit(grpc_shutdown) != 0: - raise ImportError('failed to register gRPC library shutdown callbacks') - _initialize() From 7e024be839687470bd1343f70f08ec1e703eb9ec Mon Sep 17 00:00:00 2001 From: chedeti Date: Fri, 5 Aug 2016 11:15:37 -0700 Subject: [PATCH 169/279] fix multilevel inheritence codegen --- tools/grift/grpc_plugins_generator.patch | 75 ++++++++++++++---------- 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/tools/grift/grpc_plugins_generator.patch b/tools/grift/grpc_plugins_generator.patch index a1d4cecde04..de82a01f625 100644 --- a/tools/grift/grpc_plugins_generator.patch +++ b/tools/grift/grpc_plugins_generator.patch @@ -59,21 +59,21 @@ index 6fd15d2..7de1fad 100755 2.8.0.rc3.226.g39d4020 -From e724d3abf096278615085bd58217321e32b43fd8 Mon Sep 17 00:00:00 2001 +From 387e4300bc9d98176a92a7c010621443a538e7f2 Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 16:16:40 -0700 Subject: [PATCH 2/3] grpc cpp plugins generator with example --- - compiler/cpp/src/generate/t_cpp_generator.cc | 478 +++++++++++++++++++++++---- + compiler/cpp/src/generate/t_cpp_generator.cc | 489 +++++++++++++++++++++++---- tutorial/cpp/CMakeLists.txt | 53 --- tutorial/cpp/CppClient.cpp | 80 ----- tutorial/cpp/CppServer.cpp | 181 ---------- - tutorial/cpp/GriftClient.cpp | 93 ++++++ - tutorial/cpp/GriftServer.cpp | 93 ++++++ + tutorial/cpp/GriftClient.cpp | 93 +++++ + tutorial/cpp/GriftServer.cpp | 93 +++++ tutorial/cpp/Makefile.am | 66 ++-- tutorial/cpp/test.thrift | 13 + - 8 files changed, 641 insertions(+), 416 deletions(-) + 8 files changed, 652 insertions(+), 416 deletions(-) delete mode 100644 tutorial/cpp/CMakeLists.txt delete mode 100644 tutorial/cpp/CppClient.cpp delete mode 100644 tutorial/cpp/CppServer.cpp @@ -82,7 +82,7 @@ Subject: [PATCH 2/3] grpc cpp plugins generator with example create mode 100644 tutorial/cpp/test.thrift diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc -index 6c04899..4e00129 100644 +index 6c04899..1557241 100644 --- a/compiler/cpp/src/generate/t_cpp_generator.cc +++ b/compiler/cpp/src/generate/t_cpp_generator.cc @@ -162,6 +162,8 @@ public: @@ -328,7 +328,7 @@ index 6c04899..4e00129 100644 << endl; f_service_tcc_ << "#ifndef " << svcname << "_TCC" << endl << "#define " << svcname << "_TCC" -@@ -1663,19 +1704,66 @@ void t_cpp_generator::generate_service(t_service* tservice) { +@@ -1663,19 +1704,69 @@ void t_cpp_generator::generate_service(t_service* tservice) { } } @@ -361,15 +361,18 @@ index 6c04899..4e00129 100644 + indent() << "\"/" << ns << "." << service_name_ << "/" << (*f_iter)->get_name() << "\"," << endl; + } + -+ if (extends_service) { -+ vector functions = extends_service->get_functions(); ++ ++ t_service* service_iter = extends_service; ++ while (service_iter) { ++ vector functions = service_iter->get_functions(); + vector::iterator f_iter; + + for ( f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { + f_service_ << -+ indent() << "\"/" << extends_service->get_program()->get_namespace("cpp") << -+ "." << extends_service->get_name() << "/" << (*f_iter)->get_name() << "\"," << endl; ++ indent() << "\"/" << service_iter->get_program()->get_namespace("cpp") << ++ "." << service_iter->get_name() << "/" << (*f_iter)->get_name() << "\"," << endl; + } ++ service_iter = service_iter->get_extends(); + } + + indent_down(); @@ -403,7 +406,7 @@ index 6c04899..4e00129 100644 // Generate all the cob components if (gen_cob_style_) { -@@ -1688,10 +1776,14 @@ void t_cpp_generator::generate_service(t_service* tservice) { +@@ -1688,10 +1779,14 @@ void t_cpp_generator::generate_service(t_service* tservice) { generate_service_async_skeleton(tservice); } @@ -418,7 +421,7 @@ index 6c04899..4e00129 100644 // Close the namespace f_service_ << ns_close_ << endl << endl; f_service_tcc_ << ns_close_ << endl << endl; -@@ -1729,15 +1821,11 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) { +@@ -1729,15 +1824,11 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) { string name_orig = ts->get_name(); // TODO(dreiss): Why is this stuff not in generate_function_helpers? @@ -436,7 +439,7 @@ index 6c04899..4e00129 100644 ts->set_name(name_orig); generate_function_helpers(tservice, *f_iter); -@@ -1745,13 +1833,210 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) { +@@ -1745,13 +1836,218 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) { } /** @@ -497,9 +500,10 @@ index 6c04899..4e00129 100644 + } + + t_service* extends_service = tservice->get_extends(); -+ if (extends_service) { ++ t_service* service_iter = extends_service; ++ while (service_iter) { + // generate inherited methods -+ vector functions = extends_service->get_functions(); ++ vector functions = service_iter->get_functions(); + vector::iterator f_iter; + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { + string function_name = (*f_iter)->get_name(); @@ -508,6 +512,7 @@ index 6c04899..4e00129 100644 + "(::grpc::ClientContext* context, const " << function_name << + "Req& request, " << function_name << "Resp* response) override;" << endl; + } ++ service_iter = service_iter->get_extends(); + } + + f_header_ << @@ -521,14 +526,16 @@ index 6c04899..4e00129 100644 + indent() << "const ::grpc::RpcMethod rpcmethod_" << (*f_iter)->get_name() << "_;" << endl; + } + -+ if (extends_service) { ++ service_iter = extends_service; ++ while (service_iter) { + // generate inherited methods -+ vector functions = extends_service->get_functions(); ++ vector functions = service_iter->get_functions(); + vector::iterator f_iter; + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { + f_header_ << + indent() << "const ::grpc::RpcMethod rpcmethod_" << (*f_iter)->get_name() << "_;" << endl; + } ++ service_iter = service_iter->get_extends(); + } + + indent_down(); @@ -551,9 +558,10 @@ index 6c04899..4e00129 100644 + service_name_ << "_method_names[" << i << "], ::grpc::RpcMethod::NORMAL_RPC, channel)" << endl; + } + -+ if (extends_service) { ++ service_iter = extends_service; ++ while (service_iter) { + // generate inherited methods -+ vector functions = extends_service->get_functions(); ++ vector functions = service_iter->get_functions(); + vector::iterator f_iter; + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter, ++i) { + f_service_ << @@ -561,6 +569,7 @@ index 6c04899..4e00129 100644 + ", rpcmethod_" << (*f_iter)->get_name() << "_(" << + service_name_ << "_method_names[" << i << "], ::grpc::RpcMethod::NORMAL_RPC, channel)" << endl; + } ++ service_iter = service_iter->get_extends(); + } + f_service_ << + indent() << "{}" << endl; @@ -609,8 +618,9 @@ index 6c04899..4e00129 100644 + + } + -+ if (extends_service) { -+ vector functions = extends_service->get_functions(); ++ service_iter = extends_service; ++ while (service_iter) { ++ vector functions = service_iter->get_functions(); + vector::iterator f_iter; + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { + string function_name = (*f_iter)->get_name(); @@ -631,6 +641,7 @@ index 6c04899..4e00129 100644 + "}" << endl; + + } ++ service_iter = service_iter->get_extends(); + } + +} @@ -648,7 +659,7 @@ index 6c04899..4e00129 100644 if (style == "CobCl") { // Forward declare the client. string client_name = service_name_ + "CobClient"; -@@ -1764,13 +2049,15 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty +@@ -1764,13 +2060,15 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty } string extends = ""; @@ -666,7 +677,7 @@ index 6c04899..4e00129 100644 } if (style == "CobCl" && gen_templates_) { -@@ -1778,7 +2065,9 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty +@@ -1778,7 +2076,9 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty } f_header_ << "class " << service_if_name << extends << " {" << endl << " public:" << endl; indent_up(); @@ -677,7 +688,7 @@ index 6c04899..4e00129 100644 vector functions = tservice->get_functions(); vector::iterator f_iter; -@@ -1786,7 +2075,12 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty +@@ -1786,7 +2086,12 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty if ((*f_iter)->has_doc()) f_header_ << endl; generate_java_doc(f_header_, *f_iter); @@ -691,7 +702,7 @@ index 6c04899..4e00129 100644 } indent_down(); f_header_ << "};" << endl << endl; -@@ -1797,6 +2091,66 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty +@@ -1797,6 +2102,66 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty f_header_ << "typedef " << service_if_name << "< ::apache::thrift::protocol::TProtocol> " << service_name_ << style << "If;" << endl << endl; } @@ -758,7 +769,7 @@ index 6c04899..4e00129 100644 } /** -@@ -3095,7 +3449,7 @@ void t_cpp_generator::generate_function_helpers(t_service* tservice, t_function* +@@ -3095,7 +3460,7 @@ void t_cpp_generator::generate_function_helpers(t_service* tservice, t_function* std::ofstream& out = (gen_templates_ ? f_service_tcc_ : f_service_); @@ -767,7 +778,7 @@ index 6c04899..4e00129 100644 t_field success(tfunction->get_returntype(), "success", 0); if (!tfunction->get_returntype()->is_void()) { result.append(&success); -@@ -3109,17 +3463,9 @@ void t_cpp_generator::generate_function_helpers(t_service* tservice, t_function* +@@ -3109,17 +3474,9 @@ void t_cpp_generator::generate_function_helpers(t_service* tservice, t_function* } generate_struct_declaration(f_header_, &result, false); @@ -786,7 +797,7 @@ index 6c04899..4e00129 100644 } /** -@@ -3162,8 +3508,8 @@ void t_cpp_generator::generate_process_function(t_service* tservice, +@@ -3162,8 +3519,8 @@ void t_cpp_generator::generate_process_function(t_service* tservice, << endl; scope_up(out); @@ -797,7 +808,7 @@ index 6c04899..4e00129 100644 if (tfunction->is_oneway() && !unnamed_oprot_seqid) { out << indent() << "(void) seqid;" << endl << indent() << "(void) oprot;" << endl; -@@ -3320,7 +3666,7 @@ void t_cpp_generator::generate_process_function(t_service* tservice, +@@ -3320,7 +3677,7 @@ void t_cpp_generator::generate_process_function(t_service* tservice, out << indent() << "(void) seqid;" << endl << indent() << "(void) oprot;" << endl; } @@ -806,7 +817,7 @@ index 6c04899..4e00129 100644 << indent() << "void* ctx = NULL;" << endl << indent() << "if (this->eventHandler_.get() != NULL) {" << endl << indent() << " ctx = this->eventHandler_->getContext(" << service_func_name << ", NULL);" << endl -@@ -3487,7 +3833,7 @@ void t_cpp_generator::generate_process_function(t_service* tservice, +@@ -3487,7 +3844,7 @@ void t_cpp_generator::generate_process_function(t_service* tservice, << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << endl << endl; // Throw the TDelayedException, and catch the result @@ -1475,7 +1486,7 @@ index 0000000..de3c9a4 2.8.0.rc3.226.g39d4020 -From f991f33dd6461eae197b6ad0e7088b571f2a7b22 Mon Sep 17 00:00:00 2001 +From 3e4d75a2e2c474ee7700e7c9acaf89fdb768bedc Mon Sep 17 00:00:00 2001 From: chedeti Date: Sun, 31 Jul 2016 16:23:53 -0700 Subject: [PATCH 3/3] grpc java plugins generator From 45fa6323dbcfd806183eb8380251768406652d4c Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 5 Aug 2016 20:19:24 +0200 Subject: [PATCH 170/279] That won't work properly. Falling back on fixing the list of dependencies. --- .../interoptest/grpc_interop_go/build_interop.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh index 82bb4a64835..7110aaf9e56 100755 --- a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh @@ -31,13 +31,22 @@ # Builds Go interop server and client in a base image. set -e -go get google.golang.org/grpc/interop # Clone just the grpc-go source code without any dependencies. # We are cloning from a local git repo that contains the right revision # to test instead of using "go get" to download from Github directly. git clone --recursive /var/local/jenkins/grpc-go src/google.golang.org/grpc +# Get dependencies from GitHub +# NOTE: once grpc-go dependencies change, this needs to be updated manually +# but we don't expect this to happen any time soon. +go get github.com/golang/protobuf/proto +go get golang.org/x/net/context +go get golang.org/x/net/trace +go get golang.org/x/oauth2 +go get golang.org/x/oauth2/google +go get google.golang.org/cloud + # copy service account keys if available cp -r /var/local/jenkins/service_account $HOME || true From 30f809556fc7dda50408980d239853418307d203 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 5 Aug 2016 21:01:53 +0200 Subject: [PATCH 171/279] Reducing diff. --- .../interoptest/grpc_interop_go/build_interop.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh index 7110aaf9e56..1fd088322cd 100755 --- a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh @@ -31,12 +31,14 @@ # Builds Go interop server and client in a base image. set -e - # Clone just the grpc-go source code without any dependencies. # We are cloning from a local git repo that contains the right revision # to test instead of using "go get" to download from Github directly. git clone --recursive /var/local/jenkins/grpc-go src/google.golang.org/grpc +# copy service account keys if available +cp -r /var/local/jenkins/service_account $HOME || true + # Get dependencies from GitHub # NOTE: once grpc-go dependencies change, this needs to be updated manually # but we don't expect this to happen any time soon. @@ -47,9 +49,6 @@ go get golang.org/x/oauth2 go get golang.org/x/oauth2/google go get google.golang.org/cloud -# copy service account keys if available -cp -r /var/local/jenkins/service_account $HOME || true - # Build the interop client and server (cd src/google.golang.org/grpc/interop/client && go install) (cd src/google.golang.org/grpc/interop/server && go install) From 0db98cda0d81de2117501fd62020a7bbe6095eee Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 5 Aug 2016 17:19:34 -0700 Subject: [PATCH 172/279] Undo Go Docker fix - fixed in another PR --- tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh index 5c597a12efa..e8915493422 100755 --- a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh @@ -42,7 +42,6 @@ cp -r /var/local/jenkins/service_account $HOME || true # Get dependencies from GitHub # NOTE: once grpc-go dependencies change, this needs to be updated manually # but we don't expect this to happen any time soon. -go get google.golang.org/cloud/compute/metadata go get github.com/golang/protobuf/proto go get golang.org/x/net/context go get golang.org/x/net/trace From 737bd555cfb9e4ada4eea3f2e7944bda76d58b20 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 5 Aug 2016 19:33:59 +0200 Subject: [PATCH 173/279] Hopefully fixing #7639. --- .../interoptest/grpc_interop_go/build_interop.sh | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh index e8915493422..6e7813ef0b1 100755 --- a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh @@ -31,6 +31,8 @@ # Builds Go interop server and client in a base image. set -e +go get google.golang.org/grpc + # Clone just the grpc-go source code without any dependencies. # We are cloning from a local git repo that contains the right revision # to test instead of using "go get" to download from Github directly. @@ -39,15 +41,6 @@ git clone --recursive /var/local/jenkins/grpc-go src/google.golang.org/grpc # copy service account keys if available cp -r /var/local/jenkins/service_account $HOME || true -# Get dependencies from GitHub -# NOTE: once grpc-go dependencies change, this needs to be updated manually -# but we don't expect this to happen any time soon. -go get github.com/golang/protobuf/proto -go get golang.org/x/net/context -go get golang.org/x/net/trace -go get golang.org/x/oauth2 -go get google.golang.org/cloud - # Build the interop client and server (cd src/google.golang.org/grpc/interop/client && go install) (cd src/google.golang.org/grpc/interop/server && go install) From e667fe19bf3d9e49888af1b736d65e19c04990f1 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 5 Aug 2016 20:12:22 +0200 Subject: [PATCH 174/279] Using the interop dependencies instead. --- tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh index 6e7813ef0b1..82bb4a64835 100755 --- a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh @@ -31,7 +31,7 @@ # Builds Go interop server and client in a base image. set -e -go get google.golang.org/grpc +go get google.golang.org/grpc/interop # Clone just the grpc-go source code without any dependencies. # We are cloning from a local git repo that contains the right revision From 6fd8a7fa03215dcb99c8f042fb393552a077ea2b Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 5 Aug 2016 20:19:24 +0200 Subject: [PATCH 175/279] That won't work properly. Falling back on fixing the list of dependencies. --- .../interoptest/grpc_interop_go/build_interop.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh index 82bb4a64835..7110aaf9e56 100755 --- a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh @@ -31,13 +31,22 @@ # Builds Go interop server and client in a base image. set -e -go get google.golang.org/grpc/interop # Clone just the grpc-go source code without any dependencies. # We are cloning from a local git repo that contains the right revision # to test instead of using "go get" to download from Github directly. git clone --recursive /var/local/jenkins/grpc-go src/google.golang.org/grpc +# Get dependencies from GitHub +# NOTE: once grpc-go dependencies change, this needs to be updated manually +# but we don't expect this to happen any time soon. +go get github.com/golang/protobuf/proto +go get golang.org/x/net/context +go get golang.org/x/net/trace +go get golang.org/x/oauth2 +go get golang.org/x/oauth2/google +go get google.golang.org/cloud + # copy service account keys if available cp -r /var/local/jenkins/service_account $HOME || true From 0275d8c65b7bd509b76cc46b2314078dd785c6e7 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 5 Aug 2016 21:01:53 +0200 Subject: [PATCH 176/279] Reducing diff. --- .../interoptest/grpc_interop_go/build_interop.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh index 7110aaf9e56..1fd088322cd 100755 --- a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh @@ -31,12 +31,14 @@ # Builds Go interop server and client in a base image. set -e - # Clone just the grpc-go source code without any dependencies. # We are cloning from a local git repo that contains the right revision # to test instead of using "go get" to download from Github directly. git clone --recursive /var/local/jenkins/grpc-go src/google.golang.org/grpc +# copy service account keys if available +cp -r /var/local/jenkins/service_account $HOME || true + # Get dependencies from GitHub # NOTE: once grpc-go dependencies change, this needs to be updated manually # but we don't expect this to happen any time soon. @@ -47,9 +49,6 @@ go get golang.org/x/oauth2 go get golang.org/x/oauth2/google go get google.golang.org/cloud -# copy service account keys if available -cp -r /var/local/jenkins/service_account $HOME || true - # Build the interop client and server (cd src/google.golang.org/grpc/interop/client && go install) (cd src/google.golang.org/grpc/interop/server && go install) From f50020ce038411b2a0864cb61296b67ac1cc032e Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 8 Aug 2016 07:29:31 -0700 Subject: [PATCH 177/279] Appease the const gods, improve readability, stop using 0 and 1 as proxies for false and true. --- test/cpp/qps/client.h | 11 ++++------- test/cpp/qps/client_sync.cc | 4 ++-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index 5b1a1c3b827..fada4ba7679 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -169,7 +169,7 @@ class Client { // Must call AwaitThreadsCompletion before destructor to avoid a race // between destructor and invocation of virtual ThreadFunc void AwaitThreadsCompletion() { - gpr_atm_rel_store(&thread_pool_done_, static_cast(1)); + gpr_atm_rel_store(&thread_pool_done_, static_cast(true)); DestroyMultithreading(); std::unique_lock g(thread_completion_mu_); while (threads_remaining_ != 0) { @@ -182,7 +182,7 @@ class Client { gpr_atm thread_pool_done_; void StartThreads(size_t num_threads) { - gpr_atm_rel_store(&thread_pool_done_, static_cast(0)); + gpr_atm_rel_store(&thread_pool_done_, static_cast(false)); threads_remaining_ = num_threads; for (size_t i = 0; i < num_threads; i++) { threads_.emplace_back(new Thread(this, i)); @@ -274,14 +274,11 @@ class Client { if (entry.used()) { histogram_.Add(entry.value()); } - bool done = false; if (!thread_still_ok) { gpr_log(GPR_ERROR, "Finishing client thread due to RPC error"); - done = true; } - done = done || (gpr_atm_acq_load(&client_->thread_pool_done_) != - static_cast(0)); - if (done) { + if (!thread_still_ok || + static_cast(gpr_atm_acq_load(&client_->thread_pool_done_))) { client_->CompleteThread(); return; } diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc index 53e004ffa02..8062424a1fb 100644 --- a/test/cpp/qps/client_sync.cc +++ b/test/cpp/qps/client_sync.cc @@ -82,12 +82,12 @@ class SynchronousClient // WaitToIssue returns false if we realize that we need to break out bool WaitToIssue(int thread_idx) { if (!closed_loop_) { - gpr_timespec next_issue_time = NextIssueTime(thread_idx); + const gpr_timespec next_issue_time = NextIssueTime(thread_idx); // Avoid sleeping for too long continuously because we might // need to terminate before then. This is an issue since // exponential distribution can occasionally produce bad outliers while (true) { - gpr_timespec one_sec_delay = + const gpr_timespec one_sec_delay = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(1, GPR_TIMESPAN)); if (gpr_time_cmp(next_issue_time, one_sec_delay) <= 0) { From dc3d561f4a470490d75a3018683f4a67705f1250 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Mon, 8 Aug 2016 16:30:10 -0700 Subject: [PATCH 178/279] remove dedicated thread for read loop in ruby bidi calls --- src/ruby/lib/grpc/generic/bidi_call.rb | 95 ++++++++++---------------- 1 file changed, 36 insertions(+), 59 deletions(-) diff --git a/src/ruby/lib/grpc/generic/bidi_call.rb b/src/ruby/lib/grpc/generic/bidi_call.rb index c2ac3c4dafe..75ddff0bfd9 100644 --- a/src/ruby/lib/grpc/generic/bidi_call.rb +++ b/src/ruby/lib/grpc/generic/bidi_call.rb @@ -61,7 +61,6 @@ module GRPC @call = call @marshal = marshal @op_notifier = nil # signals completion on clients - @readq = Queue.new @unmarshal = unmarshal @metadata_received = metadata_received @reads_complete = false @@ -81,8 +80,7 @@ module GRPC def run_on_client(requests, op_notifier, &blk) @op_notifier = op_notifier @enq_th = Thread.new { write_loop(requests) } - @loop_th = start_read_loop - each_queued_msg(&blk) + read_loop(&blk) end # Begins orchestration of the Bidi stream for a server generating replies. @@ -97,8 +95,7 @@ module GRPC # # @param gen_each_reply [Proc] generates the BiDi stream replies. def run_on_server(gen_each_reply) - replys = gen_each_reply.call(each_queued_msg) - @loop_th = start_read_loop(is_client: false) + replys = gen_each_reply.call(read_loop(is_client: false)) write_loop(replys, is_client: false) end @@ -135,24 +132,6 @@ module GRPC batch_result end - # each_queued_msg yields each message on this instances readq - # - # - messages are added to the readq by #read_loop - # - iteration ends when the instance itself is added - def each_queued_msg - return enum_for(:each_queued_msg) unless block_given? - count = 0 - loop do - GRPC.logger.debug("each_queued_msg: waiting##{count}") - count += 1 - req = @readq.pop - GRPC.logger.debug("each_queued_msg: req = #{req}") - fail req if req.is_a? StandardError - break if req.equal?(END_OF_READS) - yield req - end - end - def write_loop(requests, is_client: true) GRPC.logger.debug('bidi-write-loop: starting') count = 0 @@ -190,47 +169,45 @@ module GRPC raise e end - # starts the read loop - def start_read_loop(is_client: true) - Thread.new do - GRPC.logger.debug('bidi-read-loop: starting') - begin - count = 0 - # queue the initial read before beginning the loop - loop do - GRPC.logger.debug("bidi-read-loop: #{count}") - count += 1 - batch_result = read_using_run_batch - - # handle the next message - if batch_result.message.nil? - GRPC.logger.debug("bidi-read-loop: null batch #{batch_result}") - - if is_client - batch_result = @call.run_batch(RECV_STATUS_ON_CLIENT => nil) - @call.status = batch_result.status - batch_result.check_status - GRPC.logger.debug("bidi-read-loop: done status #{@call.status}") - end - - @readq.push(END_OF_READS) - GRPC.logger.debug('bidi-read-loop: done reading!') - break + # Provides an enumerator that yields results of remote reads + def read_loop(is_client: true) + return enum_for(:read_loop, + is_client: is_client) unless block_given? + GRPC.logger.debug('bidi-read-loop: starting') + begin + count = 0 + # queue the initial read before beginning the loop + loop do + GRPC.logger.debug("bidi-read-loop: #{count}") + count += 1 + batch_result = read_using_run_batch + + # handle the next message + if batch_result.message.nil? + GRPC.logger.debug("bidi-read-loop: null batch #{batch_result}") + + if is_client + batch_result = @call.run_batch(RECV_STATUS_ON_CLIENT => nil) + @call.status = batch_result.status + batch_result.check_status + GRPC.logger.debug("bidi-read-loop: done status #{@call.status}") end - # push the latest read onto the queue and continue reading - res = @unmarshal.call(batch_result.message) - @readq.push(res) + GRPC.logger.debug('bidi-read-loop: done reading!') + break end - rescue StandardError => e - GRPC.logger.warn('bidi: read-loop failed') - GRPC.logger.warn(e) - @readq.push(e) # let each_queued_msg terminate with this error + + res = @unmarshal.call(batch_result.message) + yield res end - GRPC.logger.debug('bidi-read-loop: finished') - @reads_complete = true - finished + rescue StandardError => e + GRPC.logger.warn('bidi: read-loop failed') + GRPC.logger.warn(e) + raise e end + GRPC.logger.debug('bidi-read-loop: finished') + @reads_complete = true + finished end end end From f0f58e68738abbc317f7f449c5104f7fbbff26bd Mon Sep 17 00:00:00 2001 From: siddharthshukla Date: Mon, 8 Aug 2016 22:46:50 +0200 Subject: [PATCH 179/279] skip test run if running with pypy don't run cygrpc_test.TypeSmokeTest.testCallCredentialsFromPluginUpdown if the interpreter is PyPy --- src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py b/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py index f9a8e2401bb..2f50263730f 100644 --- a/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py +++ b/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py @@ -30,6 +30,7 @@ import time import threading import unittest +import platform from grpc._cython import cygrpc from tests.unit._cython import test_utilities @@ -113,6 +114,9 @@ class TypeSmokeTest(unittest.TestCase): lambda ignored_a, ignored_b: None, b'') del plugin + @unittest.skipIf( + platform.python_implementation() == "PyPy", + 'TODO(issue 7672): figure out why this fails on PyPy') def testCallCredentialsFromPluginUpDown(self): plugin = cygrpc.CredentialsMetadataPlugin(_metadata_plugin_callback, b'') call_credentials = cygrpc.call_credentials_metadata_plugin(plugin) From d745a6f682a9aaab0f20fc4ba8bfc17920e0604b Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Mon, 8 Aug 2016 20:44:36 -0700 Subject: [PATCH 180/279] Disable SO_REUSEPORT for UNIX socket --- src/core/lib/iomgr/tcp_server_posix.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c index 38ebd2dbcb0..475bb6068f3 100644 --- a/src/core/lib/iomgr/tcp_server_posix.c +++ b/src/core/lib/iomgr/tcp_server_posix.c @@ -685,7 +685,8 @@ void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s, s->pollset_count = pollset_count; sp = s->head; while (sp != NULL) { - if (s->so_reuseport && pollset_count > 1) { + if (s->so_reuseport && !grpc_is_unix_socket(&sp->addr.sockaddr) && + pollset_count > 1) { GPR_ASSERT(GRPC_LOG_IF_ERROR( "clone_port", clone_port(sp, (unsigned)(pollset_count - 1)))); for (i = 0; i < pollset_count; i++) { From 2414bbb9e772a65b0dc5c04361b052b0cf16d597 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Mon, 8 Aug 2016 21:22:54 -0700 Subject: [PATCH 181/279] Disable SO_REUSEPORT at prepare_socket() for unix sockets --- src/core/lib/iomgr/tcp_server_posix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c index 475bb6068f3..6bba0202a54 100644 --- a/src/core/lib/iomgr/tcp_server_posix.c +++ b/src/core/lib/iomgr/tcp_server_posix.c @@ -306,7 +306,7 @@ static grpc_error *prepare_socket(int fd, const struct sockaddr *addr, GPR_ASSERT(fd >= 0); - if (so_reuseport) { + if (so_reuseport && !grpc_is_unix_socket(addr)) { err = grpc_set_socket_reuse_port(fd, 1); if (err != GRPC_ERROR_NONE) goto error; } From 2d33d78ac5d5f5eca862bdbb0dd6a2e986b6ddbc Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 9 Aug 2016 00:50:59 -0500 Subject: [PATCH 182/279] Proxy for @ghemawat: Removed an unnecessary error allocation from chttp2 code. --- .../chttp2/transport/chttp2_transport.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 6bd65cea02c..751bc8d72ec 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -94,7 +94,8 @@ static void initiate_writing(grpc_exec_ctx *exec_ctx, void *t, static void start_writing(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t); static void end_waiting_for_write(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t, grpc_error *error); + grpc_chttp2_transport *t, grpc_error *error, + const char *reason); /** Set a transport level setting, and push it to our peer */ static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, @@ -876,7 +877,7 @@ static void start_writing(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { set_write_state(t, GRPC_CHTTP2_WRITING_INACTIVE, "start_writing:nothing_to_write"); } - end_waiting_for_write(exec_ctx, t, GRPC_ERROR_CREATE("Nothing to write")); + end_waiting_for_write(exec_ctx, t, GRPC_ERROR_NONE, "Nothing to write"); if (t->ep && !t->endpoint_reading) { destroy_endpoint(exec_ctx, t); } @@ -925,11 +926,18 @@ static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, } } +/* error may be GRPC_ERROR_NONE if there is no error allocated yet. + In that case, use "reason" as the text for a new error. */ static void end_waiting_for_write(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t, grpc_error *error) { + grpc_chttp2_transport *t, grpc_error *error, + const char *reason) { grpc_chttp2_stream_global *stream_global; while (grpc_chttp2_list_pop_closed_waiting_for_writing(&t->global, &stream_global)) { + if (error == GRPC_ERROR_NONE && reason != NULL) { + /* create error object. */ + error = GRPC_ERROR_CREATE(reason); + } fail_pending_writes(exec_ctx, &t->global, stream_global, GRPC_ERROR_REF(error)); GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "finish_writes"); @@ -951,7 +959,7 @@ static void terminate_writing_with_lock(grpc_exec_ctx *exec_ctx, grpc_chttp2_cleanup_writing(exec_ctx, &t->global, &t->writing); - end_waiting_for_write(exec_ctx, t, error); + end_waiting_for_write(exec_ctx, t, error, NULL); switch (t->executor.write_state) { case GRPC_CHTTP2_WRITING_INACTIVE: From 40160d17a8afa4f8b394a61c78313684e9231c9c Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 8 Aug 2016 22:55:16 -0700 Subject: [PATCH 183/279] clang-format --- src/core/ext/transport/chttp2/transport/chttp2_transport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 751bc8d72ec..28768f57f0a 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -95,7 +95,7 @@ static void initiate_writing(grpc_exec_ctx *exec_ctx, void *t, static void start_writing(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t); static void end_waiting_for_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_error *error, - const char *reason); + const char *reason); /** Set a transport level setting, and push it to our peer */ static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, @@ -930,7 +930,7 @@ static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, In that case, use "reason" as the text for a new error. */ static void end_waiting_for_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_error *error, - const char *reason) { + const char *reason) { grpc_chttp2_stream_global *stream_global; while (grpc_chttp2_list_pop_closed_waiting_for_writing(&t->global, &stream_global)) { From e84d242ed4072246d6142b1a264bed2e19389c2d Mon Sep 17 00:00:00 2001 From: HuKeping Date: Tue, 9 Aug 2016 15:26:37 +0800 Subject: [PATCH 184/279] Use DBC case instead of SBC case Signed-off-by: Hu Keping --- doc/health-checking.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/health-checking.md b/doc/health-checking.md index 92512e942bd..7be8107b60f 100644 --- a/doc/health-checking.md +++ b/doc/health-checking.md @@ -58,7 +58,7 @@ a response must be sent back with an `OK` status and the status field should be set to `SERVING` or `NOT_SERVING` accordingly. If the service name is not registered, the server returns a `NOT_FOUND` GRPC status. -The server should use an empty string as the key for server’s +The server should use an empty string as the key for server's overall health status, so that a client not interested in a specific service can query the server's status with an empty request. The server can just do exact matching of the service name without support of any kind of wildcard matching. From 13fa3796936f8341e7a290c6ac0b5270558299a1 Mon Sep 17 00:00:00 2001 From: Stanislav Date: Tue, 9 Aug 2016 16:00:59 +0700 Subject: [PATCH 185/279] Update README.md --- examples/php/route_guide/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/php/route_guide/README.md b/examples/php/route_guide/README.md index 4e74a79f136..26f1704f122 100644 --- a/examples/php/route_guide/README.md +++ b/examples/php/route_guide/README.md @@ -1,6 +1,6 @@ #gRPC Basics: PHP sample code The files in this folder are the samples used in [gRPC Basics: PHP][], -a detailed tutorial for using gRPC in Ruby. +a detailed tutorial for using gRPC in PHP. [gRPC Basics: PHP]:http://www.grpc.io/docs/tutorials/basic/php.html From a6bdb30311383a49337529ebde7976ba9239dab9 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Tue, 9 Aug 2016 08:54:39 -0700 Subject: [PATCH 186/279] fix jenkins linux image in create script --- tools/gce/create_linux_worker.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/gce/create_linux_worker.sh b/tools/gce/create_linux_worker.sh index 8a2df40859b..7bf8b240818 100755 --- a/tools/gce/create_linux_worker.sh +++ b/tools/gce/create_linux_worker.sh @@ -43,8 +43,8 @@ gcloud compute instances create $INSTANCE_NAME \ --project="$CLOUD_PROJECT" \ --zone "$ZONE" \ --machine-type n1-standard-8 \ - --image-family=ubuntu-1510 \ - --image-project=ubuntu-os-cloud \ + --image=ubuntu-1510 \ + --image-project=grpc-testing \ --boot-disk-size 1000 echo 'Created GCE instance, waiting 60 seconds for it to come online.' From 58c0615c1dbde6b72358d4d6a07664bdaad303d7 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 9 Aug 2016 10:59:04 -0700 Subject: [PATCH 187/279] Extend the deadline of objc-examples-build to 30 minutes --- tools/run_tests/run_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 542415d9085..8be15dda4e4 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -706,7 +706,7 @@ class ObjCLanguage(object): shortname='objc-tests', environ=_FORCE_ENVIRON_FOR_WRAPPERS), self.config.job_spec(['src/objective-c/tests/build_example_test.sh'], - timeout_seconds=15*60, + timeout_seconds=30*60, shortname='objc-examples-build', environ=_FORCE_ENVIRON_FOR_WRAPPERS)] From 80db7f8c6e927527ce9d3bf8c79cf1175845ad90 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 9 Aug 2016 11:35:19 -0700 Subject: [PATCH 188/279] Make Node grpc-tools protoc automatically call the plugin --- src/node/tools/bin/protoc.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/node/tools/bin/protoc.js b/src/node/tools/bin/protoc.js index 53fc5dc4280..7f8356867aa 100755 --- a/src/node/tools/bin/protoc.js +++ b/src/node/tools/bin/protoc.js @@ -47,7 +47,11 @@ var exe_ext = process.platform === 'win32' ? '.exe' : ''; var protoc = path.resolve(__dirname, 'protoc' + exe_ext); -var child_process = execFile(protoc, process.argv.slice(2), function(error, stdout, stderr) { +var plugin = path.resolve(__dirname, 'grpc_node_plugin' + exe_ext); + +var args = ['--plugin=protoc-gen-grpc=' + plugin].concat(process.argv.slice(2)); + +var child_process = execFile(protoc, args, function(error, stdout, stderr) { if (error) { throw error; } From 6bfe7dadf71ce6637adef1adc990a653849f56c1 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Tue, 9 Aug 2016 11:40:05 -0700 Subject: [PATCH 189/279] add all runtime nodes back into testing packages --- src/csharp/Grpc.Examples.MathClient/project.json | 5 +++++ src/csharp/Grpc.Examples.MathServer/project.json | 5 +++++ src/csharp/Grpc.Examples/project.json | 3 ++- src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json | 5 +++++ src/csharp/Grpc.IntegrationTesting.StressClient/project.json | 5 +++++ .../csharp/Grpc.Examples.MathClient/project.json.template | 2 +- .../csharp/Grpc.Examples.MathServer/project.json.template | 2 +- templates/src/csharp/Grpc.Examples/project.json.template | 3 ++- .../Grpc.IntegrationTesting.QpsWorker/project.json.template | 2 +- .../project.json.template | 2 +- templates/src/csharp/build_options.include | 4 +--- 11 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/csharp/Grpc.Examples.MathClient/project.json b/src/csharp/Grpc.Examples.MathClient/project.json index 764a335ddfb..ad319478ab0 100644 --- a/src/csharp/Grpc.Examples.MathClient/project.json +++ b/src/csharp/Grpc.Examples.MathClient/project.json @@ -42,6 +42,11 @@ } } }, + "runtimes": { + "win7-x64": { }, + "debian.8-x64": { }, + "osx.10.11-x64": { } + }, "dependencies": { "Grpc.Examples": { diff --git a/src/csharp/Grpc.Examples.MathServer/project.json b/src/csharp/Grpc.Examples.MathServer/project.json index 764a335ddfb..ad319478ab0 100644 --- a/src/csharp/Grpc.Examples.MathServer/project.json +++ b/src/csharp/Grpc.Examples.MathServer/project.json @@ -42,6 +42,11 @@ } } }, + "runtimes": { + "win7-x64": { }, + "debian.8-x64": { }, + "osx.10.11-x64": { } + }, "dependencies": { "Grpc.Examples": { diff --git a/src/csharp/Grpc.Examples/project.json b/src/csharp/Grpc.Examples/project.json index 5329f390e4e..98bd5d852c4 100644 --- a/src/csharp/Grpc.Examples/project.json +++ b/src/csharp/Grpc.Examples/project.json @@ -20,11 +20,12 @@ "System.IO": "" } }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45" ], "dependencies": { + "Microsoft.NETCore.App": "1.0.0", "NETStandard.Library": "1.6.0" } } diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json index 9afcb306b40..287950720fe 100644 --- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json +++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json @@ -44,6 +44,11 @@ } } }, + "runtimes": { + "win7-x64": { }, + "debian.8-x64": { }, + "osx.10.11-x64": { } + }, "dependencies": { "Grpc.IntegrationTesting": { diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json index 9afcb306b40..287950720fe 100644 --- a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json +++ b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json @@ -44,6 +44,11 @@ } } }, + "runtimes": { + "win7-x64": { }, + "debian.8-x64": { }, + "osx.10.11-x64": { } + }, "dependencies": { "Grpc.IntegrationTesting": { diff --git a/templates/src/csharp/Grpc.Examples.MathClient/project.json.template b/templates/src/csharp/Grpc.Examples.MathClient/project.json.template index 51c5e85c66d..67151dbcfa8 100644 --- a/templates/src/csharp/Grpc.Examples.MathClient/project.json.template +++ b/templates/src/csharp/Grpc.Examples.MathClient/project.json.template @@ -1,7 +1,7 @@ %YAML 1.2 --- | { - <%include file="../build_options.include" args="executable=True,includeRuntimes=False"/> + <%include file="../build_options.include" args="executable=True"/> "dependencies": { "Grpc.Examples": { "target": "project" diff --git a/templates/src/csharp/Grpc.Examples.MathServer/project.json.template b/templates/src/csharp/Grpc.Examples.MathServer/project.json.template index 51c5e85c66d..67151dbcfa8 100644 --- a/templates/src/csharp/Grpc.Examples.MathServer/project.json.template +++ b/templates/src/csharp/Grpc.Examples.MathServer/project.json.template @@ -1,7 +1,7 @@ %YAML 1.2 --- | { - <%include file="../build_options.include" args="executable=True,includeRuntimes=False"/> + <%include file="../build_options.include" args="executable=True"/> "dependencies": { "Grpc.Examples": { "target": "project" diff --git a/templates/src/csharp/Grpc.Examples/project.json.template b/templates/src/csharp/Grpc.Examples/project.json.template index d5d63f658e4..117f842e01e 100644 --- a/templates/src/csharp/Grpc.Examples/project.json.template +++ b/templates/src/csharp/Grpc.Examples/project.json.template @@ -15,11 +15,12 @@ "System.IO": "" } }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45" ], "dependencies": { + "Microsoft.NETCore.App": "1.0.0", "NETStandard.Library": "1.6.0" } } diff --git a/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template index af1ee425096..93151f2b89e 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template @@ -1,7 +1,7 @@ %YAML 1.2 --- | { - <%include file="../build_options.include" args="executable=True,includeData=True,includeRuntimes=False"/> + <%include file="../build_options.include" args="executable=True,includeData=True"/> "dependencies": { "Grpc.IntegrationTesting": { "target": "project" diff --git a/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template index af1ee425096..93151f2b89e 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template @@ -1,7 +1,7 @@ %YAML 1.2 --- | { - <%include file="../build_options.include" args="executable=True,includeData=True,includeRuntimes=False"/> + <%include file="../build_options.include" args="executable=True,includeData=True"/> "dependencies": { "Grpc.IntegrationTesting": { "target": "project" diff --git a/templates/src/csharp/build_options.include b/templates/src/csharp/build_options.include index a200897e0f2..8597ae33675 100644 --- a/templates/src/csharp/build_options.include +++ b/templates/src/csharp/build_options.include @@ -1,4 +1,4 @@ -<%page args="executable=False,includeData=False,includeRuntimes=True"/>\ +<%page args="executable=False,includeData=False"/>\ "buildOptions": { % if executable: "emitEntryPoint": true @@ -52,10 +52,8 @@ } }, %endif - % if includeRuntimes: "runtimes": { "win7-x64": { }, "debian.8-x64": { }, "osx.10.11-x64": { } }, - % endif \ No newline at end of file From f07506438c012f1f466670f05284594ca6808a26 Mon Sep 17 00:00:00 2001 From: Makarand Dharmapurikar Date: Tue, 9 Aug 2016 14:25:08 -0700 Subject: [PATCH 190/279] Work in progress. Do not check in yet. --- .../cronet/transport/cronet_transport.c | 541 ++++++++++++------ 1 file changed, 359 insertions(+), 182 deletions(-) diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c index 694d346fc33..e8746b4e6e6 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.c +++ b/src/core/ext/transport/cronet/transport/cronet_transport.c @@ -51,6 +51,20 @@ #define GRPC_HEADER_SIZE_IN_BYTES 5 +#define CRONET_LOG(...) {if (1) gpr_log(__VA_ARGS__);} + +enum OP_RESULT { + ACTION_TAKEN_WITH_CALLBACK, + ACTION_TAKEN_NO_CALLBACK, + NO_ACTION_POSSIBLE +}; + +const char *OP_RESULT_STRING[] = { + "ACTION_TAKEN_WITH_CALLBACK", + "ACTION_TAKEN_NO_CALLBACK", + "NO_ACTION_POSSIBLE" +}; + enum OP_ID { OP_SEND_INITIAL_METADATA = 0, OP_SEND_MESSAGE, @@ -60,9 +74,29 @@ enum OP_ID { OP_RECV_TRAILING_METADATA, OP_CANCEL_ERROR, OP_ON_COMPLETE, + OP_FAILED, + OP_CANCELED, + OP_RECV_MESSAGE_AND_ON_COMPLETE, + OP_READ_REQ_MADE, OP_NUM_OPS }; +const char *op_id_string[] = { + "OP_SEND_INITIAL_METADATA", + "OP_SEND_MESSAGE", + "OP_SEND_TRAILING_METADATA", + "OP_RECV_MESSAGE", + "OP_RECV_INITIAL_METADATA", + "OP_RECV_TRAILING_METADATA", + "OP_CANCEL_ERROR", + "OP_ON_COMPLETE", + "OP_FAILED", + "OP_CANCELED", + "OP_RECV_MESSAGE_AND_ON_COMPLETE", + "OP_READ_REQ_MADE", + "OP_NUM_OPS" +}; + /* Cronet callbacks */ static void on_request_headers_sent(cronet_bidirectional_stream *); @@ -75,7 +109,7 @@ static void on_response_trailers_received(cronet_bidirectional_stream *, const cronet_bidirectional_stream_header_array *); static void on_succeeded(cronet_bidirectional_stream *); static void on_failed(cronet_bidirectional_stream *, int); -//static void on_canceled(cronet_bidirectional_stream *); +static void on_canceled(cronet_bidirectional_stream *); static cronet_bidirectional_stream_callback cronet_callbacks = { on_request_headers_sent, on_response_headers_received, @@ -84,7 +118,7 @@ static cronet_bidirectional_stream_callback cronet_callbacks = { on_response_trailers_received, on_succeeded, on_failed, - NULL //on_canceled + on_canceled }; // Cronet transport object @@ -121,30 +155,49 @@ struct write_state { char *write_buffer; }; -#define MAX_PENDING_OPS 10 +// maximum ops in a batch.. There is not much thinking behind this limit, except +// that it seems to be enough for most use cases. +#define MAX_PENDING_OPS 100 + +struct op_state { + bool state_op_done[OP_NUM_OPS]; + bool state_callback_received[OP_NUM_OPS]; + // data structure for storing data coming from server + struct read_state rs; + // data structure for storing data going to the server + struct write_state ws; +}; + +struct op_and_state { + grpc_transport_stream_op op; + struct op_state state; + bool done; + struct stream_obj *s; // Pointer back to the stream object +}; + struct op_storage { - grpc_transport_stream_op pending_ops[MAX_PENDING_OPS]; + struct op_and_state pending_ops[MAX_PENDING_OPS]; int wrptr; int rdptr; int num_pending_ops; }; struct stream_obj { + struct op_and_state *oas; grpc_transport_stream_op *curr_op; grpc_cronet_transport curr_ct; grpc_stream *curr_gs; cronet_bidirectional_stream *cbs; - // TODO (makdharma) : make a sub structure for tracking state - bool state_op_done[OP_NUM_OPS]; - bool state_callback_received[OP_NUM_OPS]; + // This holds the state that is at stream level (response and req metadata) + struct op_state state; - // Read state - struct read_state rs; - // Write state - struct write_state ws; + //struct op_state state; // OP storage struct op_storage storage; + + // Mutex to protect execute_curr_streaming_op + gpr_mu mu; }; typedef struct stream_obj stream_obj; @@ -152,123 +205,155 @@ typedef struct stream_obj stream_obj; cronet_bidirectional_stream_header_array header_array; // -static void execute_curr_stream_op(stream_obj *s); +static enum OP_RESULT execute_stream_op(struct op_and_state *oas); /************************************************************* Op Storage */ -static void add_pending_op(struct op_storage *storage, grpc_transport_stream_op *op) { +static void add_to_storage(struct stream_obj *s, grpc_transport_stream_op *op) { + struct op_storage *storage = &s->storage; GPR_ASSERT(storage->num_pending_ops < MAX_PENDING_OPS); storage->num_pending_ops++; - gpr_log(GPR_DEBUG, "adding new op @wrptr=%d. %d in the queue.", + CRONET_LOG(GPR_DEBUG, "adding new op @wrptr=%d. %d in the queue.", storage->wrptr, storage->num_pending_ops); - memcpy(&storage->pending_ops[storage->wrptr], op, sizeof(grpc_transport_stream_op)); + memcpy(&storage->pending_ops[storage->wrptr].op, op, sizeof(grpc_transport_stream_op)); + memset(&storage->pending_ops[storage->wrptr].state, 0, sizeof(storage->pending_ops[storage->wrptr].state)); + storage->pending_ops[storage->wrptr].done = false; + storage->pending_ops[storage->wrptr].s = s; storage->wrptr = (storage->wrptr + 1) % MAX_PENDING_OPS; } -static grpc_transport_stream_op *pop_pending_op(struct op_storage *storage) { - if (storage->num_pending_ops == 0) return NULL; - grpc_transport_stream_op *result = &storage->pending_ops[storage->rdptr]; - storage->rdptr = (storage->rdptr + 1) % MAX_PENDING_OPS; - storage->num_pending_ops--; - gpr_log(GPR_DEBUG, "popping op @rdptr=%d. %d more left in queue", - storage->rdptr, storage->num_pending_ops); - return result; +static void execute_from_storage(stream_obj *s) { + // Cycle through ops and try to take next action. Break when either + // an action with callback is taken, or no action is possible. + gpr_mu_lock(&s->mu); + for (int i = 0; i < s->storage.wrptr; ) { + CRONET_LOG(GPR_DEBUG, "calling execute_stream_op[%d]. done = %d", i, s->storage.pending_ops[i].done); + if (s->storage.pending_ops[i].done) { + i++; + continue; + } + enum OP_RESULT result = execute_stream_op(&s->storage.pending_ops[i]); + CRONET_LOG(GPR_DEBUG, "%s = execute_stream_op[%d]", OP_RESULT_STRING[result], i); + if (result == NO_ACTION_POSSIBLE) { + i++; + } else if (result == ACTION_TAKEN_WITH_CALLBACK) { + break; + } + } + gpr_mu_unlock(&s->mu); } + /************************************************************* Cronet Callback Ipmlementation */ static void on_failed(cronet_bidirectional_stream *stream, int net_error) { - gpr_log(GPR_DEBUG, "on_failed(%p, %d)", stream, net_error); + CRONET_LOG(GPR_DEBUG, "on_failed(%p, %d)", stream, net_error); + stream_obj *s = (stream_obj *)stream->annotation; + cronet_bidirectional_stream_destroy(s->cbs); + s->state.state_callback_received[OP_FAILED] = true; + s->cbs = NULL; + execute_from_storage(s); } -static void on_succeeded(cronet_bidirectional_stream *stream) { - gpr_log(GPR_DEBUG, "on_succeeded(%p)", stream); +static void on_canceled(cronet_bidirectional_stream *stream) { + CRONET_LOG(GPR_DEBUG, "on_canceled(%p)", stream); + stream_obj *s = (stream_obj *)stream->annotation; + cronet_bidirectional_stream_destroy(s->cbs); + s->state.state_callback_received[OP_CANCELED] = true; + s->cbs = NULL; + execute_from_storage(s); } +static void on_succeeded(cronet_bidirectional_stream *stream) { + CRONET_LOG(GPR_DEBUG, "on_succeeded(%p)", stream); + stream_obj *s = (stream_obj *)stream->annotation; + cronet_bidirectional_stream_destroy(s->cbs); + s->cbs = NULL; +} static void on_request_headers_sent(cronet_bidirectional_stream *stream) { - gpr_log(GPR_DEBUG, "W: on_request_headers_sent(%p)", stream); + CRONET_LOG(GPR_DEBUG, "W: on_request_headers_sent(%p)", stream); stream_obj *s = (stream_obj *)stream->annotation; - s->state_op_done[OP_SEND_INITIAL_METADATA] = true; - s->state_callback_received[OP_SEND_INITIAL_METADATA] = true; - execute_curr_stream_op(s); + s->state.state_op_done[OP_SEND_INITIAL_METADATA] = true; + s->state.state_callback_received[OP_SEND_INITIAL_METADATA] = true; + execute_from_storage(s); } static void on_response_headers_received( cronet_bidirectional_stream *stream, const cronet_bidirectional_stream_header_array *headers, const char *negotiated_protocol) { - gpr_log(GPR_DEBUG, "R: on_response_headers_received(%p, %p, %s)", stream, + CRONET_LOG(GPR_DEBUG, "R: on_response_headers_received(%p, %p, %s)", stream, headers, negotiated_protocol); - stream_obj *s = (stream_obj *)stream->annotation; - memset(&s->rs.initial_metadata, 0, sizeof(s->rs.initial_metadata)); - grpc_chttp2_incoming_metadata_buffer_init(&s->rs.initial_metadata); + memset(&s->state.rs.initial_metadata, 0, sizeof(s->state.rs.initial_metadata)); + grpc_chttp2_incoming_metadata_buffer_init(&s->state.rs.initial_metadata); unsigned int i = 0; for (i = 0; i < headers->count; i++) { grpc_chttp2_incoming_metadata_buffer_add( - &s->rs.initial_metadata, + &s->state.rs.initial_metadata, grpc_mdelem_from_metadata_strings( grpc_mdstr_from_string(headers->headers[i].key), grpc_mdstr_from_string(headers->headers[i].value))); } - s->state_callback_received[OP_RECV_INITIAL_METADATA] = true; - execute_curr_stream_op(s); + s->state.state_callback_received[OP_RECV_INITIAL_METADATA] = true; + execute_from_storage(s); } static void on_write_completed(cronet_bidirectional_stream *stream, const char *data) { - gpr_log(GPR_DEBUG, "W: on_write_completed(%p, %s)", stream, data); stream_obj *s = (stream_obj *)stream->annotation; - if (s->ws.write_buffer) { - gpr_free(s->ws.write_buffer); - s->ws.write_buffer = NULL; + CRONET_LOG(GPR_DEBUG, "W: on_write_completed(%p, %s)", stream, data); + if (s->state.ws.write_buffer) { + gpr_free(s->state.ws.write_buffer); + s->state.ws.write_buffer = NULL; } - s->state_callback_received[OP_SEND_MESSAGE] = true; - execute_curr_stream_op(s); + s->state.state_callback_received[OP_SEND_MESSAGE] = true; + execute_from_storage(s); } static void on_read_completed(cronet_bidirectional_stream *stream, char *data, int count) { stream_obj *s = (stream_obj *)stream->annotation; - gpr_log(GPR_DEBUG, "R: on_read_completed(%p, %p, %d)", stream, data, count); + CRONET_LOG(GPR_DEBUG, "R: on_read_completed(%p, %p, %d)", stream, data, count); if (count > 0) { - s->rs.received_bytes += count; - s->rs.remaining_bytes -= count; - if (s->rs.remaining_bytes > 0) { - gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_read"); - cronet_bidirectional_stream_read(s->cbs, s->rs.read_buffer + s->rs.received_bytes, s->rs.remaining_bytes); + s->state.rs.received_bytes += count; + s->state.rs.remaining_bytes -= count; + if (s->state.rs.remaining_bytes > 0) { + //CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_read"); + s->state.state_op_done[OP_READ_REQ_MADE] = true; // If at least one read request has been made + cronet_bidirectional_stream_read(s->cbs, s->state.rs.read_buffer + s->state.rs.received_bytes, s->state.rs.remaining_bytes); } else { - execute_curr_stream_op(s); + execute_from_storage(s); } - s->state_callback_received[OP_RECV_MESSAGE] = true; + s->state.state_callback_received[OP_RECV_MESSAGE] = true; } } static void on_response_trailers_received( cronet_bidirectional_stream *stream, const cronet_bidirectional_stream_header_array *trailers) { - gpr_log(GPR_DEBUG, "R: on_response_trailers_received(%p,%p)", stream, + CRONET_LOG(GPR_DEBUG, "R: on_response_trailers_received(%p,%p)", stream, trailers); stream_obj *s = (stream_obj *)stream->annotation; - memset(&s->rs.trailing_metadata, 0, sizeof(s->rs.trailing_metadata)); - s->rs.trailing_metadata_valid = false; - grpc_chttp2_incoming_metadata_buffer_init(&s->rs.trailing_metadata); + memset(&s->state.rs.trailing_metadata, 0, sizeof(s->state.rs.trailing_metadata)); + s->state.rs.trailing_metadata_valid = false; + grpc_chttp2_incoming_metadata_buffer_init(&s->state.rs.trailing_metadata); unsigned int i = 0; for (i = 0; i < trailers->count; i++) { - gpr_log(GPR_DEBUG, "trailer key=%s, value=%s", trailers->headers[i].key, + CRONET_LOG(GPR_DEBUG, "trailer key=%s, value=%s", trailers->headers[i].key, trailers->headers[i].value); grpc_chttp2_incoming_metadata_buffer_add( - &s->rs.trailing_metadata, grpc_mdelem_from_metadata_strings( + &s->state.rs.trailing_metadata, grpc_mdelem_from_metadata_strings( grpc_mdstr_from_string(trailers->headers[i].key), grpc_mdstr_from_string(trailers->headers[i].value))); - s->rs.trailing_metadata_valid = true; + s->state.rs.trailing_metadata_valid = true; } - s->state_callback_received[OP_RECV_TRAILING_METADATA] = true; - execute_curr_stream_op(s); + s->state.state_callback_received[OP_RECV_TRAILING_METADATA] = true; + execute_from_storage(s); } /************************************************************* @@ -295,10 +380,10 @@ static void create_grpc_frame(gpr_slice_buffer *write_slice_buffer, memcpy(p, GPR_SLICE_START_PTR(slice), length); } -static void enqueue_callback(grpc_closure *callback) { +static void enqueue_callback(grpc_closure *callback, grpc_error *error) { GPR_ASSERT(callback); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_exec_ctx_sched(&exec_ctx, callback, GRPC_ERROR_NONE, NULL); + grpc_exec_ctx_sched(&exec_ctx, callback, error, NULL); grpc_exec_ctx_finish(&exec_ctx); } @@ -342,6 +427,7 @@ static void convert_metadata_to_cronet_headers( gpr_asprintf(pp_url, "https://%s%s", host, value); continue; } + gpr_log(GPR_DEBUG, "header %s = %s", key, value); headers[num_headers].key = key; headers[num_headers].value = value; num_headers++; @@ -365,165 +451,252 @@ static int parse_grpc_header(const uint8_t *data) { /* Op Execution */ - -static bool op_can_be_run(stream_obj *s, enum OP_ID op_id) { - if (op_id == OP_SEND_INITIAL_METADATA) { +static bool op_can_be_run(grpc_transport_stream_op *curr_op, struct op_state *stream_state, struct op_state *op_state, enum OP_ID op_id) { + // We use op's own state for most state, except for metadata related callbacks, which + // are at the stream level. TODO: WTF does this comment mean? + bool result = true; + // When call is canceled, every op can be run + if (stream_state->state_op_done[OP_CANCEL_ERROR] || stream_state->state_callback_received[OP_FAILED]) { + if (op_id == OP_SEND_INITIAL_METADATA) result = false; + if (op_id == OP_SEND_MESSAGE) result = false; + if (op_id == OP_SEND_TRAILING_METADATA) result = false; + if (op_id == OP_CANCEL_ERROR) result = false; // already executed - if (s->state_op_done[OP_SEND_INITIAL_METADATA]) return false; - } - if (op_id == OP_RECV_INITIAL_METADATA) { + if (op_id == OP_RECV_INITIAL_METADATA && stream_state->state_op_done[OP_RECV_INITIAL_METADATA]) result = false; + if (op_id == OP_RECV_MESSAGE && stream_state->state_op_done[OP_RECV_MESSAGE]) result = false; + if (op_id == OP_RECV_TRAILING_METADATA && stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) result = false; + } else if (op_id == OP_SEND_INITIAL_METADATA) { + // already executed + if (stream_state->state_op_done[OP_SEND_INITIAL_METADATA]) result = false; + } else if (op_id == OP_RECV_INITIAL_METADATA) { // already executed - if (s->state_op_done[OP_RECV_INITIAL_METADATA]) return false; + if (stream_state->state_op_done[OP_RECV_INITIAL_METADATA]) result = false; // we haven't sent headers yet. - if (!s->state_callback_received[OP_SEND_INITIAL_METADATA]) return false; + else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) result = false; // we haven't received headers yet. - if (!s->state_callback_received[OP_RECV_INITIAL_METADATA]) return false; - } - if (op_id == OP_SEND_MESSAGE) { + else if (!stream_state->state_callback_received[OP_RECV_INITIAL_METADATA]) result = false; + } else if (op_id == OP_SEND_MESSAGE) { // already executed - if (s->state_op_done[OP_SEND_MESSAGE]) return false; - // we haven't received headers yet. - if (!s->state_callback_received[OP_RECV_INITIAL_METADATA]) return false; - } - if (op_id == OP_RECV_MESSAGE) { + if (stream_state->state_op_done[OP_SEND_MESSAGE]) result = false; + // we haven't sent headers yet. + else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) result = false; + } else if (op_id == OP_RECV_MESSAGE) { // already executed - if (s->state_op_done[OP_RECV_MESSAGE]) return false; + if (op_state->state_op_done[OP_RECV_MESSAGE]) result = false; // we haven't received headers yet. - if (!s->state_callback_received[OP_RECV_INITIAL_METADATA]) return false; - } - if (op_id == OP_RECV_TRAILING_METADATA) { + else if (!stream_state->state_callback_received[OP_RECV_INITIAL_METADATA]) result = false; + } else if (op_id == OP_RECV_TRAILING_METADATA) { // already executed - if (s->state_op_done[OP_RECV_TRAILING_METADATA]) return false; + if (stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) result = false; + // we have asked for but haven't received message yet. + else if (stream_state->state_op_done[OP_READ_REQ_MADE] && !stream_state->state_op_done[OP_RECV_MESSAGE]) result = false; // we haven't received trailers yet. - if (!s->state_callback_received[OP_RECV_TRAILING_METADATA]) return false; - } - if (op_id == OP_SEND_TRAILING_METADATA) { + else if (!stream_state->state_callback_received[OP_RECV_TRAILING_METADATA]) result = false; + } else if (op_id == OP_SEND_TRAILING_METADATA) { // already executed - if (s->state_op_done[OP_SEND_TRAILING_METADATA]) return false; + if (stream_state->state_op_done[OP_SEND_TRAILING_METADATA]) result = false; + // we haven't sent initial metadata yet + else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) result = false; // we haven't sent message yet - if (s->curr_op->send_message && !s->state_op_done[OP_SEND_MESSAGE]) return false; - } - - if (op_id == OP_ON_COMPLETE) { + else if (curr_op->send_message && !stream_state->state_op_done[OP_SEND_MESSAGE]) result = false; + // we haven't got on_write_completed for the send yet + else if (curr_op->send_message && !stream_state->state_callback_received[OP_SEND_MESSAGE]) result = false; + } else if (op_id == OP_CANCEL_ERROR) { // already executed - if (s->state_op_done[OP_ON_COMPLETE]) return false; + if (stream_state->state_op_done[OP_CANCEL_ERROR]) result = false; + } else if (op_id == OP_ON_COMPLETE) { + // already executed (note we're checking op specific state, not stream state) + if (op_state->state_op_done[OP_ON_COMPLETE]) result = false; // Check if every op that was asked for is done. - if (s->curr_op->send_initial_metadata && !s->state_op_done[OP_SEND_INITIAL_METADATA]) return false; - if (s->curr_op->send_message && !s->state_op_done[OP_SEND_MESSAGE]) return false; - if (s->curr_op->send_trailing_metadata && !s->state_op_done[OP_SEND_TRAILING_METADATA]) return false; - if (s->curr_op->recv_initial_metadata && !s->state_op_done[OP_RECV_INITIAL_METADATA]) return false; - if (s->curr_op->recv_message && !s->state_op_done[OP_RECV_MESSAGE]) return false; - if (s->curr_op->recv_trailing_metadata && !s->state_op_done[OP_RECV_TRAILING_METADATA]) return false; + else if (curr_op->send_initial_metadata && !stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) result = false; + else if (curr_op->send_message && !stream_state->state_op_done[OP_SEND_MESSAGE]) result = false; + else if (curr_op->send_trailing_metadata && !stream_state->state_op_done[OP_SEND_TRAILING_METADATA]) result = false; + else if (curr_op->recv_initial_metadata && !stream_state->state_op_done[OP_RECV_INITIAL_METADATA]) result = false; + else if (curr_op->recv_message && !stream_state->state_op_done[OP_RECV_MESSAGE]) result = false; + else if (curr_op->recv_trailing_metadata) { + // We aren't done with trailing metadata yet + if (!stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) result = false; + // We've asked for actual message in an earlier op, and it hasn't been delivered yet. + // (TODO: What happens when multiple messages are asked for? How do you know when last message arrived?) + else if (stream_state->state_op_done[OP_READ_REQ_MADE]) { + // If this op is not the one asking for read, (which means some earlier op has asked), and the + // read hasn't been delivered. + if(!curr_op->recv_message && !stream_state->state_op_done[OP_RECV_MESSAGE_AND_ON_COMPLETE]) result = false; + } + } + // We should see at least one on_write_completed for the trailers that we sent + else if (curr_op->send_trailing_metadata && !stream_state->state_callback_received[OP_SEND_MESSAGE]) result = false; } - return true; + CRONET_LOG(GPR_DEBUG, "op_can_be_run %s : %s", op_id_string[op_id], result? "YES":"NO"); + return result; } -static void execute_curr_stream_op(stream_obj *s) { - if (s->curr_op->send_initial_metadata && op_can_be_run(s, OP_SEND_INITIAL_METADATA)) { +static enum OP_RESULT execute_stream_op(struct op_and_state *oas) { + // TODO TODO : This can be called from network thread and main thread. add a mutex. + grpc_transport_stream_op *stream_op = &oas->op; + struct stream_obj *s = oas->s; + struct op_state *stream_state = &s->state; + //CRONET_LOG(GPR_DEBUG, "execute_stream_op"); + enum OP_RESULT result = NO_ACTION_POSSIBLE; + if (stream_op->send_initial_metadata && op_can_be_run(stream_op, stream_state, &oas->state, OP_SEND_INITIAL_METADATA)) { + CRONET_LOG(GPR_DEBUG, "running: %p OP_SEND_INITIAL_METADATA", oas); // This OP is the beginning. Reset various states - memset(&s->rs, 0, sizeof(s->rs)); - memset(&s->ws, 0, sizeof(s->ws)); - memset(s->state_op_done, 0, sizeof(s->state_op_done)); - memset(s->state_callback_received, 0, sizeof(s->state_callback_received)); + memset(&stream_state->rs, 0, sizeof(stream_state->rs)); + memset(&stream_state->ws, 0, sizeof(stream_state->ws)); + memset(stream_state->state_op_done, 0, sizeof(stream_state->state_op_done)); + memset(stream_state->state_callback_received, 0, sizeof(stream_state->state_callback_received)); // Start new cronet stream GPR_ASSERT(s->cbs == NULL); - gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_create"); + CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_create"); s->cbs = cronet_bidirectional_stream_create(s->curr_ct.engine, s->curr_gs, &cronet_callbacks); char *url; - convert_metadata_to_cronet_headers(s->curr_op->send_initial_metadata->list.head, + convert_metadata_to_cronet_headers(stream_op->send_initial_metadata->list.head, s->curr_ct.host, &url, &header_array.headers, &header_array.count); header_array.capacity = header_array.count; - gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_start"); + CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_start %s", url); cronet_bidirectional_stream_start(s->cbs, url, 0, "POST", &header_array, false); - s->state_op_done[OP_SEND_INITIAL_METADATA] = true; - } else if (s->curr_op->recv_initial_metadata && - op_can_be_run(s, OP_RECV_INITIAL_METADATA)) { - grpc_chttp2_incoming_metadata_buffer_publish(&s->rs.initial_metadata, - s->curr_op->recv_initial_metadata); - enqueue_callback(s->curr_op->recv_initial_metadata_ready); - s->state_op_done[OP_RECV_INITIAL_METADATA] = true; - // We are ready to execute send_message. - execute_curr_stream_op(s); - } else if (s->curr_op->send_message && op_can_be_run(s, OP_SEND_MESSAGE)) { + stream_state->state_op_done[OP_SEND_INITIAL_METADATA] = true; + result = ACTION_TAKEN_WITH_CALLBACK; + } else if (stream_op->recv_initial_metadata && + op_can_be_run(stream_op, stream_state, &oas->state, OP_RECV_INITIAL_METADATA)) { + CRONET_LOG(GPR_DEBUG, "running: %p OP_RECV_INITIAL_METADATA", oas); + if (!stream_state->state_op_done[OP_CANCEL_ERROR]) { + grpc_chttp2_incoming_metadata_buffer_publish(&oas->s->state.rs.initial_metadata, + stream_op->recv_initial_metadata); + enqueue_callback(stream_op->recv_initial_metadata_ready, GRPC_ERROR_NONE); + } else { + enqueue_callback(stream_op->recv_initial_metadata_ready, GRPC_ERROR_CANCELLED); + } + stream_state->state_op_done[OP_RECV_INITIAL_METADATA] = true; + result = ACTION_TAKEN_NO_CALLBACK; + } else if (stream_op->send_message && op_can_be_run(stream_op, stream_state, &oas->state, OP_SEND_MESSAGE)) { + CRONET_LOG(GPR_DEBUG, "running: %p OP_SEND_MESSAGE", oas); // TODO (makdharma): Make into a standalone function gpr_slice_buffer write_slice_buffer; gpr_slice slice; gpr_slice_buffer_init(&write_slice_buffer); - grpc_byte_stream_next(NULL, s->curr_op->send_message, &slice, - s->curr_op->send_message->length, NULL); + grpc_byte_stream_next(NULL, stream_op->send_message, &slice, + stream_op->send_message->length, NULL); // Check that compression flag is not ON. We don't support compression yet. // TODO (makdharma): add compression support - GPR_ASSERT(s->curr_op->send_message->flags == 0); + GPR_ASSERT(stream_op->send_message->flags == 0); gpr_slice_buffer_add(&write_slice_buffer, slice); GPR_ASSERT(write_slice_buffer.count == 1); // Empty request not handled yet if (write_slice_buffer.count > 0) { int write_buffer_size; - create_grpc_frame(&write_slice_buffer, &s->ws.write_buffer, &write_buffer_size); - gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_write (%p)", s->ws.write_buffer); - cronet_bidirectional_stream_write(s->cbs, s->ws.write_buffer, + create_grpc_frame(&write_slice_buffer, &stream_state->ws.write_buffer, &write_buffer_size); + CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_write (%p)", stream_state->ws.write_buffer); + stream_state->state_callback_received[OP_SEND_MESSAGE] = false; + cronet_bidirectional_stream_write(s->cbs, stream_state->ws.write_buffer, write_buffer_size, false); // TODO: What if this is not the last write? + result = ACTION_TAKEN_WITH_CALLBACK; } - s->state_op_done[OP_SEND_MESSAGE] = true; - } else if (s->curr_op->recv_message && op_can_be_run(s, OP_RECV_MESSAGE)) { - if (s->rs.length_field_received == false) { - if (s->rs.received_bytes == GRPC_HEADER_SIZE_IN_BYTES && s->rs.remaining_bytes == 0) { + stream_state->state_op_done[OP_SEND_MESSAGE] = true; + } else if (stream_op->recv_message && op_can_be_run(stream_op, stream_state, &oas->state, OP_RECV_MESSAGE)) { + CRONET_LOG(GPR_DEBUG, "running: %p OP_RECV_MESSAGE", oas); + if (stream_state->state_op_done[OP_CANCEL_ERROR]) { + enqueue_callback(stream_op->recv_message_ready, GRPC_ERROR_CANCELLED); + stream_state->state_op_done[OP_RECV_MESSAGE] = true; + } else if (stream_state->rs.length_field_received == false) { + if (stream_state->rs.received_bytes == GRPC_HEADER_SIZE_IN_BYTES && stream_state->rs.remaining_bytes == 0) { // Start a read operation for data - s->rs.length_field_received = true; - s->rs.length_field = s->rs.remaining_bytes = - parse_grpc_header((const uint8_t *)s->rs.read_buffer); - GPR_ASSERT(s->rs.length_field > 0); // Empty message? - gpr_log(GPR_DEBUG, "length field = %d", s->rs.length_field); - s->rs.read_buffer = gpr_malloc(s->rs.length_field); - GPR_ASSERT(s->rs.read_buffer); - s->rs.remaining_bytes = s->rs.length_field; - s->rs.received_bytes = 0; - gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_read"); - cronet_bidirectional_stream_read(s->cbs, s->rs.read_buffer, - s->rs.remaining_bytes); - } else if (s->rs.remaining_bytes == 0) { + stream_state->rs.length_field_received = true; + stream_state->rs.length_field = stream_state->rs.remaining_bytes = + parse_grpc_header((const uint8_t *)stream_state->rs.read_buffer); + CRONET_LOG(GPR_DEBUG, "length field = %d", stream_state->rs.length_field); + if (stream_state->rs.length_field > 0) { + stream_state->rs.read_buffer = gpr_malloc(stream_state->rs.length_field); + GPR_ASSERT(stream_state->rs.read_buffer); + stream_state->rs.remaining_bytes = stream_state->rs.length_field; + stream_state->rs.received_bytes = 0; + CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_read"); + stream_state->state_op_done[OP_READ_REQ_MADE] = true; // If at least one read request has been made + cronet_bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer, + stream_state->rs.remaining_bytes); + result = ACTION_TAKEN_WITH_CALLBACK; + } else { + stream_state->rs.remaining_bytes = 0; + CRONET_LOG(GPR_DEBUG, "read operation complete. Empty response."); + gpr_slice_buffer_init(&stream_state->rs.read_slice_buffer); + grpc_slice_buffer_stream_init(&stream_state->rs.sbs, &stream_state->rs.read_slice_buffer, 0); + *((grpc_byte_buffer **)stream_op->recv_message) = (grpc_byte_buffer *)&stream_state->rs.sbs; + enqueue_callback(stream_op->recv_message_ready, GRPC_ERROR_NONE); + stream_state->state_op_done[OP_RECV_MESSAGE] = true; + oas->state.state_op_done[OP_RECV_MESSAGE] = true; // Also set per op state. + result = ACTION_TAKEN_NO_CALLBACK; + } + } else if (stream_state->rs.remaining_bytes == 0) { // Start a read operation for first 5 bytes (GRPC header) - s->rs.read_buffer = s->rs.grpc_header_bytes; - s->rs.remaining_bytes = GRPC_HEADER_SIZE_IN_BYTES; - s->rs.received_bytes = 0; - gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_read"); - cronet_bidirectional_stream_read(s->cbs, s->rs.read_buffer, - s->rs.remaining_bytes); + stream_state->rs.read_buffer = stream_state->rs.grpc_header_bytes; + stream_state->rs.remaining_bytes = GRPC_HEADER_SIZE_IN_BYTES; + stream_state->rs.received_bytes = 0; + CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_read"); + stream_state->state_op_done[OP_READ_REQ_MADE] = true; // If at least one read request has been made + cronet_bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer, + stream_state->rs.remaining_bytes); } - } else if (s->rs.remaining_bytes == 0) { - gpr_log(GPR_DEBUG, "read operation complete"); - gpr_slice read_data_slice = gpr_slice_malloc((uint32_t)s->rs.length_field); + result = ACTION_TAKEN_WITH_CALLBACK; + } else if (stream_state->rs.remaining_bytes == 0) { + CRONET_LOG(GPR_DEBUG, "read operation complete"); + gpr_slice read_data_slice = gpr_slice_malloc((uint32_t)stream_state->rs.length_field); uint8_t *dst_p = GPR_SLICE_START_PTR(read_data_slice); - memcpy(dst_p, s->rs.read_buffer, (size_t)s->rs.length_field); - gpr_slice_buffer_init(&s->rs.read_slice_buffer); - gpr_slice_buffer_add(&s->rs.read_slice_buffer, read_data_slice); - grpc_slice_buffer_stream_init(&s->rs.sbs, &s->rs.read_slice_buffer, 0); - *((grpc_byte_buffer **)s->curr_op->recv_message) = (grpc_byte_buffer *)&s->rs.sbs; - enqueue_callback(s->curr_op->recv_message_ready); - s->state_op_done[OP_RECV_MESSAGE] = true; - execute_curr_stream_op(s); + memcpy(dst_p, stream_state->rs.read_buffer, (size_t)stream_state->rs.length_field); + gpr_slice_buffer_init(&stream_state->rs.read_slice_buffer); + gpr_slice_buffer_add(&stream_state->rs.read_slice_buffer, read_data_slice); + grpc_slice_buffer_stream_init(&stream_state->rs.sbs, &stream_state->rs.read_slice_buffer, 0); + *((grpc_byte_buffer **)stream_op->recv_message) = (grpc_byte_buffer *)&stream_state->rs.sbs; + enqueue_callback(stream_op->recv_message_ready, GRPC_ERROR_NONE); + stream_state->state_op_done[OP_RECV_MESSAGE] = true; + oas->state.state_op_done[OP_RECV_MESSAGE] = true; // Also set per op state. + // Clear read state of the stream, so next read op (if it were to come) will work + stream_state->rs.received_bytes = stream_state->rs.remaining_bytes = stream_state->rs.length_field_received = 0; + result = ACTION_TAKEN_NO_CALLBACK; } - } else if (s->curr_op->recv_trailing_metadata && - op_can_be_run(s, OP_RECV_TRAILING_METADATA)) { - if (s->rs.trailing_metadata_valid) { + } else if (stream_op->recv_trailing_metadata && + op_can_be_run(stream_op, stream_state, &oas->state, OP_RECV_TRAILING_METADATA)) { + CRONET_LOG(GPR_DEBUG, "running: %p OP_RECV_TRAILING_METADATA", oas); + if (oas->s->state.rs.trailing_metadata_valid) { grpc_chttp2_incoming_metadata_buffer_publish( - &s->rs.trailing_metadata, s->curr_op->recv_trailing_metadata); - s->rs.trailing_metadata_valid = false; + &oas->s->state.rs.trailing_metadata, stream_op->recv_trailing_metadata); + stream_state->rs.trailing_metadata_valid = false; } - s->state_op_done[OP_RECV_TRAILING_METADATA] = true; - execute_curr_stream_op(s); - } else if (s->curr_op->send_trailing_metadata && - op_can_be_run(s, OP_SEND_TRAILING_METADATA)) { - - gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_write (0)"); + stream_state->state_op_done[OP_RECV_TRAILING_METADATA] = true; + result = ACTION_TAKEN_NO_CALLBACK; + } else if (stream_op->send_trailing_metadata && op_can_be_run(stream_op, stream_state, &oas->state, OP_SEND_TRAILING_METADATA)) { + CRONET_LOG(GPR_DEBUG, "running: %p OP_SEND_TRAILING_METADATA", oas); + CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_write (0)"); + stream_state->state_callback_received[OP_SEND_MESSAGE] = false; cronet_bidirectional_stream_write(s->cbs, "", 0, true); - s->state_op_done[OP_SEND_TRAILING_METADATA] = true; - } else if (op_can_be_run(s, OP_ON_COMPLETE)) { + stream_state->state_op_done[OP_SEND_TRAILING_METADATA] = true; + result = ACTION_TAKEN_WITH_CALLBACK; + } else if (stream_op->cancel_error && op_can_be_run(stream_op, stream_state, &oas->state, OP_CANCEL_ERROR)) { + CRONET_LOG(GPR_DEBUG, "running: %p OP_CANCEL_ERROR", oas); + CRONET_LOG(GPR_DEBUG, "W: cronet_bidirectional_stream_cancel(%p)", s->cbs); + // Cancel might have come before creation of stream + if (s->cbs) { + cronet_bidirectional_stream_cancel(s->cbs); + } + stream_state->state_op_done[OP_CANCEL_ERROR] = true; + result = ACTION_TAKEN_WITH_CALLBACK; + } else if (stream_op->on_complete && op_can_be_run(stream_op, stream_state, &oas->state, OP_ON_COMPLETE)) { // All ops are complete. Call the on_complete callback - enqueue_callback(s->curr_op->on_complete); - s->state_op_done[OP_ON_COMPLETE] = true; - cronet_bidirectional_stream_destroy(s->cbs); - s->cbs = NULL; + CRONET_LOG(GPR_DEBUG, "running: %p OP_ON_COMPLETE", oas); + //CRONET_LOG(GPR_DEBUG, "calling on_complete"); + enqueue_callback(stream_op->on_complete, GRPC_ERROR_NONE); + // Instead of setting stream state, use the op state as on_complete is on per op basis + oas->state.state_op_done[OP_ON_COMPLETE] = true; + oas->done = true; // Mark this op as completed + // reset any send or receive message state. + stream_state->state_callback_received[OP_SEND_MESSAGE] = false; + stream_state->state_op_done[OP_SEND_MESSAGE] = false; + result = ACTION_TAKEN_NO_CALLBACK; + // If this is the on_complete callback being called for a received message - make a note + if (stream_op->recv_message) stream_state->state_op_done[OP_RECV_MESSAGE_AND_ON_COMPLETE] = true; + } else { + //CRONET_LOG(GPR_DEBUG, "No op ready to run"); + result = NO_ACTION_POSSIBLE; } + return result; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -533,7 +706,14 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, const void *server_data) { stream_obj *s = (stream_obj *)gs; memset(&s->storage, 0, sizeof(s->storage)); + memset(&s->state, 0, sizeof(s->state)); s->curr_op = NULL; + s->cbs = NULL; + memset(&s->state.rs, 0, sizeof(s->state.rs)); + memset(&s->state.ws, 0, sizeof(s->state.ws)); + memset(s->state.state_op_done, 0, sizeof(s->state.state_op_done)); + memset(s->state.state_callback_received, 0, sizeof(s->state.state_callback_received)); + gpr_mu_init(&s->mu); return 0; } @@ -546,15 +726,12 @@ static void set_pollset_set_do_nothing(grpc_exec_ctx *exec_ctx, static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_stream *gs, grpc_transport_stream_op *op) { - gpr_log(GPR_DEBUG, "perform_stream_op"); + CRONET_LOG(GPR_DEBUG, "perform_stream_op"); stream_obj *s = (stream_obj *)gs; - memcpy(&s->curr_ct, gt, sizeof(grpc_cronet_transport)); - add_pending_op(&s->storage, op); - if (s->curr_op == NULL) { - s->curr_op = pop_pending_op(&s->storage); - } s->curr_gs = gs; - execute_curr_stream_op(s); + memcpy(&s->curr_ct, gt, sizeof(grpc_cronet_transport)); + add_to_storage(s, op); + execute_from_storage(s); } static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, From 15eba13927e1c5e3eff416a22bf53bff20e07c77 Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Tue, 9 Aug 2016 15:20:48 -0700 Subject: [PATCH 191/279] Improved some docstrings for grpc_call creation --- include/grpc/grpc.h | 8 +++++--- src/core/ext/lb_policy/grpclb/grpclb.c | 3 +++ src/core/lib/surface/channel.h | 8 ++++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index 6f7a67b715e..4ca018edb39 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -170,8 +170,9 @@ GRPCAPI void grpc_channel_watch_connectivity_state( completions are sent to 'completion_queue'. 'method' and 'host' need only live through the invocation of this function. If parent_call is non-NULL, it must be a server-side call. It will be used - to propagate properties from the server call to this new client call. - */ + to propagate properties from the server call to this new client call, + depending on the value of \a propagation_mask (see propagation_bits.h for + possible values). */ GRPCAPI grpc_call *grpc_channel_create_call( grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, grpc_completion_queue *completion_queue, const char *method, @@ -187,7 +188,8 @@ GRPCAPI void *grpc_channel_register_call(grpc_channel *channel, const char *method, const char *host, void *reserved); -/** Create a call given a handle returned from grpc_channel_register_call */ +/** Create a call given a handle returned from grpc_channel_register_call. + \sa grpc_channel_create_call. */ GRPCAPI grpc_call *grpc_channel_create_registered_call( grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, grpc_completion_queue *completion_queue, void *registered_call_handle, diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c index dec25efe616..af913d8a9df 100644 --- a/src/core/ext/lb_policy/grpclb/grpclb.c +++ b/src/core/ext/lb_policy/grpclb/grpclb.c @@ -767,6 +767,9 @@ static lb_client_data *lb_client_data_create(glb_lb_policy *glb_policy) { lb_client->deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(3, GPR_TIMESPAN)); + /* Note the following LB call progresses every time there's activity in \a + * glb_policy->base.interested_parties, which is comprised of the polling + * entities passed to glb_pick(). */ lb_client->lb_call = grpc_channel_create_pollset_set_call( glb_policy->lb_channel, NULL, GRPC_PROPAGATE_DEFAULTS, glb_policy->base.interested_parties, "/BalanceLoad", diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h index 7eff7b88836..4c629743462 100644 --- a/src/core/lib/surface/channel.h +++ b/src/core/lib/surface/channel.h @@ -42,6 +42,14 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target, grpc_channel_stack_type channel_stack_type, grpc_transport *optional_transport); +/** Create a call given a grpc_channel, in order to call \a method. + Progress is tied to activity on \a pollset_set. The returned call object is + meant to be used with \a grpc_call_start_batch_and_execute, which relies on + callbacks to signal completions. \a method and \a host need + only live through the invocation of this function. If \a parent_call is + non-NULL, it must be a server-side call. It will be used to propagate + properties from the server call to this new client call, depending on the + value of \a propagation_mask (see propagation_bits.h for possible values) */ grpc_call *grpc_channel_create_pollset_set_call( grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, grpc_pollset_set *pollset_set, const char *method, const char *host, From 260a0025d25a8ae204b0065d6ed508aa2f78cb41 Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Tue, 9 Aug 2016 16:57:32 -0700 Subject: [PATCH 192/279] fix c++ readme and tutorial --- examples/cpp/README.md | 31 ++-- examples/cpp/cpptutorial.md | 337 ++++++++++++++++++++++++------------ 2 files changed, 243 insertions(+), 125 deletions(-) diff --git a/examples/cpp/README.md b/examples/cpp/README.md index 3fa7ad4c784..783935cd53d 100644 --- a/examples/cpp/README.md +++ b/examples/cpp/README.md @@ -2,26 +2,14 @@ ## Installation -To install gRPC on your system, follow the instructions to build from source [here](../../INSTALL.md). This also installs the protocol buffer compiler `protoc` (if you don't have it already), and the C++ gRPC plugin for `protoc`. +To install gRPC on your system, follow the instructions to build from source +[here](../../INSTALL.md). This also installs the protocol buffer compiler +`protoc` (if you don't have it already), and the C++ gRPC plugin for `protoc`. ## Hello C++ gRPC! -Here's how to build and run the C++ implementation of the [Hello World](../protos/helloworld.proto) example used in [Getting started](..). - -The example code for this and our other examples lives in the `examples` -directory. Clone this repository to your local machine by running the -following command: - - -```sh -$ git clone -b $(curl -L http://grpc.io/release) https://github.com/grpc/grpc -``` - -Change your current directory to examples/cpp/helloworld - -```sh -$ cd examples/cpp/helloworld/ -``` +Here's how to build and run the C++ implementation of the [Hello +World](../protos/helloworld.proto) example used in [Getting started](..). ### Client and server implementations @@ -31,18 +19,25 @@ The server implementation is at [greeter_server.cc](helloworld/greeter_server.cc ### Try it! Build client and server: + ```sh $ make ``` + Run the server, which will listen on port 50051: + ```sh $ ./greeter_server ``` + Run the client (in a different terminal): + ```sh $ ./greeter_client ``` -If things go smoothly, you will see the "Greeter received: Hello world" in the client side output. + +If things go smoothly, you will see the "Greeter received: Hello world" in the +client side output. ## Tutorial diff --git a/examples/cpp/cpptutorial.md b/examples/cpp/cpptutorial.md index 80fef07192e..de7e4b26365 100644 --- a/examples/cpp/cpptutorial.md +++ b/examples/cpp/cpptutorial.md @@ -1,58 +1,77 @@ #gRPC Basics: C++ -This tutorial provides a basic C++ programmer's introduction to working with gRPC. By walking through this example you'll learn how to: +This tutorial provides a basic C++ programmer's introduction to working with +gRPC. By walking through this example you'll learn how to: -- Define a service in a .proto file. +- Define a service in a `.proto` file. - Generate server and client code using the protocol buffer compiler. - Use the C++ gRPC API to write a simple client and server for your service. -It assumes that you have read the [Getting started](..) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release: you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. - -This isn't a comprehensive guide to using gRPC in C++: more reference documentation is coming soon. +It assumes that you are familiar with +[protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). +Note that the example in this tutorial uses the proto3 version of the protocol +buffers language, which is currently in alpha release: you can find out more in +the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) +and see the [release notes](https://github.com/google/protobuf/releases) for the +new version in the protocol buffers Github repository. ## Why use gRPC? -Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. +Our example is a simple route mapping application that lets clients get +information about features on their route, create a summary of their route, and +exchange route information such as traffic updates with the server and other +clients. -With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. +With gRPC we can define our service once in a `.proto` file and implement clients +and servers in any of gRPC's supported languages, which in turn can be run in +environments ranging from servers inside Google to your own tablet - all the +complexity of communication between different languages and environments is +handled for you by gRPC. We also get all the advantages of working with protocol +buffers, including efficient serialization, a simple IDL, and easy interface +updating. ## Example code and setup -The example code for our tutorial is in [examples/cpp/route_guide](route_guide). To download the example, clone this repository by running the following command: -```shell -$ git clone -b $(curl -L http://grpc.io/release) https://github.com/grpc/grpc -``` - -Then change your current directory to `examples/cpp/route_guide`: -```shell -$ cd examples/cpp/route_guide -``` - -You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [gRPC in 3 minutes](README.md). - +The example code for our tutorial is in [examples/cpp/route_guide](route_guide). +You also should have the relevant tools installed to generate the server and +client interface code - if you don't already, follow the setup instructions in +[INSTALL.md](../../INSTALL.md). ## Defining the service -Our first step (as you'll know from [Getting started](..) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`examples/protos/route_guide.proto`](../protos/route_guide.proto). +Our first step is to define the gRPC *service* and the method *request* and +*response* types using +[protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). +You can see the complete `.proto` file in +[`examples/protos/route_guide.proto`](../protos/route_guide.proto). -To define a service, you specify a named `service` in your .proto file: +To define a service, you specify a named `service` in your `.proto` file: -``` +```protobuf service RouteGuide { ... } ``` -Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: +Then you define `rpc` methods inside your service definition, specifying their +request and response types. gRPC lets you define four kinds of service method, +all of which are used in the `RouteGuide` service: -- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. -``` +- A *simple RPC* where the client sends a request to the server using the stub + and waits for a response to come back, just like a normal function call. + +```protobuf // Obtains the feature at a given position. rpc GetFeature(Point) returns (Feature) {} ``` -- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. -``` +- A *server-side streaming RPC* where the client sends a request to the server + and gets a stream to read a sequence of messages back. The client reads from + the returned stream until there are no more messages. As you can see in our + example, you specify a server-side streaming method by placing the `stream` + keyword before the *response* type. + +```protobuf // Obtains the Features available within the given Rectangle. Results are // streamed rather than returned at once (e.g. in a response message with a // repeated field), as the rectangle may cover a large area and contain a @@ -60,22 +79,38 @@ Then you define `rpc` methods inside your service definition, specifying their r rpc ListFeatures(Rectangle) returns (stream Feature) {} ``` -- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a client-side streaming method by placing the `stream` keyword before the *request* type. -``` +- A *client-side streaming RPC* where the client writes a sequence of messages + and sends them to the server, again using a provided stream. Once the client + has finished writing the messages, it waits for the server to read them all + and return its response. You specify a client-side streaming method by placing + the `stream` keyword before the *request* type. + +```protobuf // Accepts a stream of Points on a route being traversed, returning a // RouteSummary when traversal is completed. rpc RecordRoute(stream Point) returns (RouteSummary) {} ``` -- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. -``` +- A *bidirectional streaming RPC* where both sides send a sequence of messages + using a read-write stream. The two streams operate independently, so clients + and servers can read and write in whatever order they like: for example, the + server could wait to receive all the client messages before writing its + responses, or it could alternately read a message then write a message, or + some other combination of reads and writes. The order of messages in each + stream is preserved. You specify this type of method by placing the `stream` + keyword before both the request and the response. + +```protobuf // Accepts a stream of RouteNotes sent while a route is being traversed, // while receiving other RouteNotes (e.g. from other users). rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} ``` -Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: -``` +Our `.proto` file also contains protocol buffer message type definitions for all +the request and response types used in our service methods - for example, here's +the `Point` message type: + +```protobuf // Points are represented as latitude-longitude pairs in the E7 representation // (degrees multiplied by 10**7 and rounded to the nearest integer). // Latitudes should be in the range +/- 90 degrees and longitude should be in @@ -86,12 +121,16 @@ message Point { } ``` - ## Generating client and server code -Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C++ plugin. +Next we need to generate the gRPC client and server interfaces from our `.proto` +service definition. We do this using the protocol buffer compiler `protoc` with +a special gRPC C++ plugin. -For simplicity, we've provided a [makefile](route_guide/Makefile) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've installed protoc and followed the gRPC code [installation instructions](../../INSTALL.md) first): +For simplicity, we've provided a [makefile](route_guide/Makefile) that runs +`protoc` for you with the appropriate plugin, input, and output (if you want to +run this yourself, make sure you've installed protoc and followed the gRPC code +[installation instructions](../../INSTALL.md) first): ```shell $ make route_guide.grpc.pb.cc route_guide.pb.cc @@ -107,39 +146,58 @@ $ protoc -I ../../protos --cpp_out=. ../../protos/route_guide.proto Running this command generates the following files in your current directory: - `route_guide.pb.h`, the header which declares your generated message classes - `route_guide.pb.cc`, which contains the implementation of your message classes -- `route_guide.grpc.pb.h`, the header which declares your generated service classes -- `route_guide.grpc.pb.cc`, which contains the implementation of your service classes +- `route_guide.grpc.pb.h`, the header which declares your generated service + classes +- `route_guide.grpc.pb.cc`, which contains the implementation of your service + classes These contain: -- All the protocol buffer code to populate, serialize, and retrieve our request and response message types +- All the protocol buffer code to populate, serialize, and retrieve our request + and response message types - A class called `RouteGuide` that contains - - a remote interface type (or *stub*) for clients to call with the methods defined in the `RouteGuide` service. - - two abstract interfaces for servers to implement, also with the methods defined in the `RouteGuide` service. + - a remote interface type (or *stub*) for clients to call with the methods + defined in the `RouteGuide` service. + - two abstract interfaces for servers to implement, also with the methods + defined in the `RouteGuide` service. ## Creating the server -First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). +First let's look at how we create a `RouteGuide` server. If you're only +interested in creating gRPC clients, you can skip this section and go straight +to [Creating the client](#client) (though you might find it interesting +anyway!). There are two parts to making our `RouteGuide` service do its job: -- Implementing the service interface generated from our service definition: doing the actual "work" of our service. -- Running a gRPC server to listen for requests from clients and return the service responses. +- Implementing the service interface generated from our service definition: + doing the actual "work" of our service. +- Running a gRPC server to listen for requests from clients and return the + service responses. -You can find our example `RouteGuide` server in [route_guide/route_guide_server.cc](route_guide/route_guide_server.cc). Let's take a closer look at how it works. +You can find our example `RouteGuide` server in +[route_guide/route_guide_server.cc](route_guide/route_guide_server.cc). Let's +take a closer look at how it works. ### Implementing RouteGuide -As you can see, our server has a `RouteGuideImpl` class that implements the generated `RouteGuide::Service` interface: +As you can see, our server has a `RouteGuideImpl` class that implements the +generated `RouteGuide::Service` interface: ```cpp class RouteGuideImpl final : public RouteGuide::Service { ... } ``` -In this case we're implementing the *synchronous* version of `RouteGuide`, which provides our default gRPC server behaviour. It's also possible to implement an asynchronous interface, `RouteGuide::AsyncService`, which allows you to further customize your server's threading behaviour, though we won't look at this in this tutorial. +In this case we're implementing the *synchronous* version of `RouteGuide`, which +provides our default gRPC server behaviour. It's also possible to implement an +asynchronous interface, `RouteGuide::AsyncService`, which allows you to further +customize your server's threading behaviour, though we won't look at this in +this tutorial. -`RouteGuideImpl` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. +`RouteGuideImpl` implements all our service methods. Let's look at the simplest +type first, `GetFeature`, which just gets a `Point` from the client and returns +the corresponding feature information from its database in a `Feature`. ```cpp Status GetFeature(ServerContext* context, const Point* point, @@ -150,34 +208,52 @@ In this case we're implementing the *synchronous* version of `RouteGuide`, which } ``` -The method is passed a context object for the RPC, the client's `Point` protocol buffer request, and a `Feature` protocol buffer to fill in with the response information. In the method we populate the `Feature` with the appropriate information, and then `return` with an `OK` status to tell gRPC that we've finished dealing with the RPC and that the `Feature` can be returned to the client. +The method is passed a context object for the RPC, the client's `Point` protocol +buffer request, and a `Feature` protocol buffer to fill in with the response +information. In the method we populate the `Feature` with the appropriate +information, and then `return` with an `OK` status to tell gRPC that we've +finished dealing with the RPC and that the `Feature` can be returned to the +client. -Now let's look at something a bit more complicated - a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. +Now let's look at something a bit more complicated - a streaming RPC. +`ListFeatures` is a server-side streaming RPC, so we need to send back multiple +`Feature`s to our client. ```cpp - Status ListFeatures(ServerContext* context, const Rectangle* rectangle, - ServerWriter* writer) override { - auto lo = rectangle->lo(); - auto hi = rectangle->hi(); - long left = std::min(lo.longitude(), hi.longitude()); - long right = std::max(lo.longitude(), hi.longitude()); - long top = std::max(lo.latitude(), hi.latitude()); - long bottom = std::min(lo.latitude(), hi.latitude()); - for (const Feature& f : feature_list_) { - if (f.location().longitude() >= left && - f.location().longitude() <= right && - f.location().latitude() >= bottom && - f.location().latitude() <= top) { - writer->Write(f); - } +Status ListFeatures(ServerContext* context, const Rectangle* rectangle, + ServerWriter* writer) override { + auto lo = rectangle->lo(); + auto hi = rectangle->hi(); + long left = std::min(lo.longitude(), hi.longitude()); + long right = std::max(lo.longitude(), hi.longitude()); + long top = std::max(lo.latitude(), hi.latitude()); + long bottom = std::min(lo.latitude(), hi.latitude()); + for (const Feature& f : feature_list_) { + if (f.location().longitude() >= left && + f.location().longitude() <= right && + f.location().latitude() >= bottom && + f.location().latitude() <= top) { + writer->Write(f); } - return Status::OK; } + return Status::OK; +} ``` -As you can see, instead of getting simple request and response objects in our method parameters, this time we get a request object (the `Rectangle` in which our client wants to find `Feature`s) and a special `ServerWriter` object. In the method, we populate as many `Feature` objects as we need to return, writing them to the `ServerWriter` using its `Write()` method. Finally, as in our simple RPC, we `return Status::OK` to tell gRPC that we've finished writing responses. +As you can see, instead of getting simple request and response objects in our +method parameters, this time we get a request object (the `Rectangle` in which +our client wants to find `Feature`s) and a special `ServerWriter` object. In the +method, we populate as many `Feature` objects as we need to return, writing them +to the `ServerWriter` using its `Write()` method. Finally, as in our simple RPC, +we `return Status::OK` to tell gRPC that we've finished writing responses. -If you look at the client-side streaming method `RecordRoute` you'll see it's quite similar, except this time we get a `ServerReader` instead of a request object and a single response. We use the `ServerReader`s `Read()` method to repeatedly read in our client's requests to a request object (in this case a `Point`) until there are no more messages: the server needs to check the return value of `Read()` after each call. If `true`, the stream is still good and it can continue reading; if `false` the message stream has ended. +If you look at the client-side streaming method `RecordRoute` you'll see it's +quite similar, except this time we get a `ServerReader` instead of a request +object and a single response. We use the `ServerReader`s `Read()` method to +repeatedly read in our client's requests to a request object (in this case a +`Point`) until there are no more messages: the server needs to check the return +value of `Read()` after each call. If `true`, the stream is still good and it +can continue reading; if `false` the message stream has ended. ```cpp while (stream->Read(&point)) { @@ -205,11 +281,18 @@ Finally, let's look at our bidirectional streaming RPC `RouteChat()`. } ``` -This time we get a `ServerReaderWriter` that can be used to read *and* write messages. The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. +This time we get a `ServerReaderWriter` that can be used to read *and* write +messages. The syntax for reading and writing here is exactly the same as for our +client-streaming and server-streaming methods. Although each side will always +get the other's messages in the order they were written, both the client and +server can read and write in any order — the streams operate completely +independently. ### Starting the server -Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: +Once we've implemented all our methods, we also need to start up a gRPC server +so that clients can actually use our service. The following snippet shows how we +do this for our `RouteGuide` service: ```cpp void RunServer(const std::string& db_path) { @@ -227,44 +310,55 @@ void RunServer(const std::string& db_path) { As you can see, we build and start our server using a `ServerBuilder`. To do this, we: 1. Create an instance of our service implementation class `RouteGuideImpl`. -2. Create an instance of the factory `ServerBuilder` class. -3. Specify the address and port we want to use to listen for client requests using the builder's `AddListeningPort()` method. -4. Register our service implementation with the builder. -5. Call `BuildAndStart()` on the builder to create and start an RPC server for our service. -5. Call `Wait()` on the server to do a blocking wait until process is killed or `Shutdown()` is called. +1. Create an instance of the factory `ServerBuilder` class. +1. Specify the address and port we want to use to listen for client requests + using the builder's `AddListeningPort()` method. +1. Register our service implementation with the builder. +1. Call `BuildAndStart()` on the builder to create and start an RPC server for + our service. +1. Call `Wait()` on the server to do a blocking wait until process is killed or + `Shutdown()` is called. ## Creating the client -In this section, we'll look at creating a C++ client for our `RouteGuide` service. You can see our complete example client code in [route_guide/route_guide_client.cc](route_guide/route_guide_client.cc). +In this section, we'll look at creating a C++ client for our `RouteGuide` +service. You can see our complete example client code in +[route_guide/route_guide_client.cc](route_guide/route_guide_client.cc). ### Creating a stub To call service methods, we first need to create a *stub*. -First we need to create a gRPC *channel* for our stub, specifying the server address and port we want to connect to without SSL: +First we need to create a gRPC *channel* for our stub, specifying the server +address and port we want to connect to without SSL: ```cpp grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()); ``` -Now we can use the channel to create our stub using the `NewStub` method provided in the `RouteGuide` class we generated from our .proto. +Now we can use the channel to create our stub using the `NewStub` method +provided in the `RouteGuide` class we generated from our `.proto`. ```cpp - public: - RouteGuideClient(std::shared_ptr channel, const std::string& db) - : stub_(RouteGuide::NewStub(channel)) { - ... - } +public: + RouteGuideClient(std::shared_ptr channel, const std::string& db) + : stub_(RouteGuide::NewStub(channel)) { + ... + } ``` ### Calling service methods -Now let's look at how we call our service methods. Note that in this tutorial we're calling the *blocking/synchronous* versions of each method: this means that the RPC call waits for the server to respond, and will either return a response or raise an exception. +Now let's look at how we call our service methods. Note that in this tutorial +we're calling the *blocking/synchronous* versions of each method: this means +that the RPC call waits for the server to respond, and will either return a +response or raise an exception. #### Simple RPC -Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local method. +Calling the simple RPC `GetFeature` is nearly as straightforward as calling a +local method. ```cpp Point point; @@ -281,33 +375,53 @@ Calling the simple RPC `GetFeature` is nearly as straightforward as calling a lo } ``` -As you can see, we create and populate a request protocol buffer object (in our case `Point`), and create a response protocol buffer object for the server to fill in. We also create a `ClientContext` object for our call - you can optionally set RPC configuration values on this object, such as deadlines, though for now we'll use the default settings. Note that you cannot reuse this object between calls. Finally, we call the method on the stub, passing it the context, request, and response. If the method returns `OK`, then we can read the response information from the server from our response object. +As you can see, we create and populate a request protocol buffer object (in our +case `Point`), and create a response protocol buffer object for the server to +fill in. We also create a `ClientContext` object for our call - you can +optionally set RPC configuration values on this object, such as deadlines, +though for now we'll use the default settings. Note that you cannot reuse this +object between calls. Finally, we call the method on the stub, passing it the +context, request, and response. If the method returns `OK`, then we can read the +response information from the server from our response object. ```cpp - std::cout << "Found feature called " << feature->name() << " at " - << feature->location().latitude()/kCoordFactor_ << ", " - << feature->location().longitude()/kCoordFactor_ << std::endl; +std::cout << "Found feature called " << feature->name() << " at " + << feature->location().latitude()/kCoordFactor_ << ", " + << feature->location().longitude()/kCoordFactor_ << std::endl; ``` #### Streaming RPCs -Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s: +Now let's look at our streaming methods. If you've already read [Creating the +server](#server) some of this may look very familiar - streaming RPCs are +implemented in a similar way on both sides. Here's where we call the server-side +streaming method `ListFeatures`, which returns a stream of geographical +`Feature`s: ```cpp - std::unique_ptr > reader( - stub_->ListFeatures(&context, rect)); - while (reader->Read(&feature)) { - std::cout << "Found feature called " - << feature.name() << " at " - << feature.location().latitude()/kCoordFactor_ << ", " - << feature.location().longitude()/kCoordFactor_ << std::endl; - } - Status status = reader->Finish(); +std::unique_ptr > reader( + stub_->ListFeatures(&context, rect)); +while (reader->Read(&feature)) { + std::cout << "Found feature called " + << feature.name() << " at " + << feature.location().latitude()/kCoordFactor_ << ", " + << feature.location().longitude()/kCoordFactor_ << std::endl; +} +Status status = reader->Finish(); ``` -Instead of passing the method a context, request, and response, we pass it a context and request and get a `ClientReader` object back. The client can use the `ClientReader` to read the server's responses. We use the `ClientReader`s `Read()` method to repeatedly read in the server's responses to a response protocol buffer object (in this case a `Feature`) until there are no more messages: the client needs to check the return value of `Read()` after each call. If `true`, the stream is still good and it can continue reading; if `false` the message stream has ended. Finally, we call `Finish()` on the stream to complete the call and get our RPC status. +Instead of passing the method a context, request, and response, we pass it a +context and request and get a `ClientReader` object back. The client can use the +`ClientReader` to read the server's responses. We use the `ClientReader`s +`Read()` method to repeatedly read in the server's responses to a response +protocol buffer object (in this case a `Feature`) until there are no more +messages: the client needs to check the return value of `Read()` after each +call. If `true`, the stream is still good and it can continue reading; if +`false` the message stream has ended. Finally, we call `Finish()` on the stream +to complete the call and get our RPC status. -The client-side streaming method `RecordRoute` is similar, except there we pass the method a context and response object and get back a `ClientWriter`. +The client-side streaming method `RecordRoute` is similar, except there we pass +the method a context and response object and get back a `ClientWriter`. ```cpp std::unique_ptr > writer( @@ -337,16 +451,26 @@ The client-side streaming method `RecordRoute` is similar, except there we pass } ``` -Once we've finished writing our client's requests to the stream using `Write()`, we need to call `WritesDone()` on the stream to let gRPC know that we've finished writing, then `Finish()` to complete the call and get our RPC status. If the status is `OK`, our response object that we initially passed to `RecordRoute()` will be populated with the server's response. +Once we've finished writing our client's requests to the stream using `Write()`, +we need to call `WritesDone()` on the stream to let gRPC know that we've +finished writing, then `Finish()` to complete the call and get our RPC status. +If the status is `OK`, our response object that we initially passed to +`RecordRoute()` will be populated with the server's response. -Finally, let's look at our bidirectional streaming RPC `RouteChat()`. In this case, we just pass a context to the method and get back a `ClientReaderWriter`, which we can use to both write and read messages. +Finally, let's look at our bidirectional streaming RPC `RouteChat()`. In this +case, we just pass a context to the method and get back a `ClientReaderWriter`, +which we can use to both write and read messages. ```cpp - std::shared_ptr > stream( - stub_->RouteChat(&context)); +std::shared_ptr > stream( + stub_->RouteChat(&context)); ``` -The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. +The syntax for reading and writing here is exactly the same as for our +client-streaming and server-streaming methods. Although each side will always +get the other's messages in the order they were written, both the client and +server can read and write in any order — the streams operate completely +independently. ## Try it out! @@ -362,4 +486,3 @@ Run the client (in a different terminal): ```shell $ ./route_guide_client ``` - From 2fd19a6f4d98af4faf11839479f5546bdb3552a7 Mon Sep 17 00:00:00 2001 From: Nathaniel Manista Date: Wed, 10 Aug 2016 02:03:07 +0000 Subject: [PATCH 193/279] Upgrade one forgotten example code site to GA API This should have been included in 46585e23f14b0463c4b7a0d04d72d712. --- examples/python/route_guide/route_guide_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/python/route_guide/route_guide_server.py b/examples/python/route_guide/route_guide_server.py index 4e780a70a19..3ffe6784768 100644 --- a/examples/python/route_guide/route_guide_server.py +++ b/examples/python/route_guide/route_guide_server.py @@ -68,7 +68,7 @@ def get_distance(start, end): R = 6371000; # metres return R * c; -class RouteGuideServicer(route_guide_pb2.BetaRouteGuideServicer): +class RouteGuideServicer(route_guide_pb2.RouteGuideServicer): """Provides methods that implement functionality of route guide server.""" def __init__(self): From 5d8d661b9579469d7e5bd026dd4b35bc848c558d Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Tue, 9 Aug 2016 19:50:27 -0700 Subject: [PATCH 194/279] Removed duplicated dependency for grpclb --- build.yaml | 2 -- tools/run_tests/sources_and_headers.json | 2 -- 2 files changed, 4 deletions(-) diff --git a/build.yaml b/build.yaml index a079ec80a87..6ca2e9ebac9 100644 --- a/build.yaml +++ b/build.yaml @@ -825,7 +825,6 @@ libs: - grpc_lb_policy_grpclb - grpc_lb_policy_pick_first - grpc_lb_policy_round_robin - - grpc_lb_policy_grpclb - grpc_resolver_dns_native - grpc_resolver_sockaddr - grpc_load_reporting @@ -924,7 +923,6 @@ libs: - grpc_lb_policy_grpclb - grpc_lb_policy_pick_first - grpc_lb_policy_round_robin - - grpc_lb_policy_grpclb - census generate_plugin_registry: true secure: false diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 189f516e300..4071eba94d1 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -4233,7 +4233,6 @@ "gpr", "grpc_base", "grpc_lb_policy_grpclb", - "grpc_lb_policy_grpclb", "grpc_lb_policy_pick_first", "grpc_lb_policy_round_robin", "grpc_load_reporting", @@ -4329,7 +4328,6 @@ "gpr", "grpc_base", "grpc_lb_policy_grpclb", - "grpc_lb_policy_grpclb", "grpc_lb_policy_pick_first", "grpc_lb_policy_round_robin", "grpc_load_reporting", From 0068bdb65a1b96c143189170811d004aa8bf0cd2 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Mon, 8 Aug 2016 20:17:51 -0700 Subject: [PATCH 195/279] php7: fix ubuntu compile error --- src/php/ext/grpc/php7_wrapper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/ext/grpc/php7_wrapper.h b/src/php/ext/grpc/php7_wrapper.h index fd8d35636f0..0d40e825073 100644 --- a/src/php/ext/grpc/php7_wrapper.h +++ b/src/php/ext/grpc/php7_wrapper.h @@ -143,7 +143,7 @@ static inline int php_grpc_zend_hash_find(HashTable *ht, char *key, int len, #define PHP_GRPC_RETURN_STRING(val, dup) RETURN_STRING(val) #define PHP_GRPC_MAKE_STD_ZVAL(pzv) \ - zval _stack_zval_##pzv; \ + static zval _stack_zval_##pzv; \ pzv = &(_stack_zval_##pzv) #define PHP_GRPC_DELREF(zv) From 83b34c2285d104ab60a40e6ad88cc32c5815e7f7 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Tue, 9 Aug 2016 12:04:49 -0700 Subject: [PATCH 196/279] php: use emalloc to replicate MAKE_STD_ZVAL --- src/php/ext/grpc/php7_wrapper.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/php/ext/grpc/php7_wrapper.h b/src/php/ext/grpc/php7_wrapper.h index 0d40e825073..1d7824113fa 100644 --- a/src/php/ext/grpc/php7_wrapper.h +++ b/src/php/ext/grpc/php7_wrapper.h @@ -143,8 +143,7 @@ static inline int php_grpc_zend_hash_find(HashTable *ht, char *key, int len, #define PHP_GRPC_RETURN_STRING(val, dup) RETURN_STRING(val) #define PHP_GRPC_MAKE_STD_ZVAL(pzv) \ - static zval _stack_zval_##pzv; \ - pzv = &(_stack_zval_##pzv) + pzv = (zval *)emalloc(sizeof(zval)); #define PHP_GRPC_DELREF(zv) #define PHP_GRPC_WRAP_OBJECT_START(name) \ From 7e8efc3ba8038ddafcf9018404c499540b44c471 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Tue, 9 Aug 2016 21:47:46 -0700 Subject: [PATCH 197/279] php: update package.xml --- package.xml | 19 +++++++++++++++++-- templates/package.xml.template | 19 +++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/package.xml b/package.xml index 65764e88889..1bf57f28cc8 100644 --- a/package.xml +++ b/package.xml @@ -10,7 +10,7 @@ grpc-packages@google.com yes - 2016-07-28 + 2016-08-09 1.0.0 @@ -22,7 +22,7 @@ BSD -- PHP7 Support continued, reduce code duplication #7543 +- Fixed Ubuntu compile error #7571, #7642 @@ -1131,5 +1131,20 @@ Update to wrap gRPC C Core version 0.10.0 - PHP7 Support continued, reduce code duplication #7543 + + + 1.0.0RC4 + 1.0.0RC4 + + + stable + stable + + 2016-08-09 + BSD + +- Fixed Ubuntu compile error #7571, #7642 + + diff --git a/templates/package.xml.template b/templates/package.xml.template index 87b10389598..43d3aa2a584 100644 --- a/templates/package.xml.template +++ b/templates/package.xml.template @@ -12,7 +12,7 @@ grpc-packages@google.com yes - 2016-07-28 + 2016-08-09 ${settings.php_version.php()} @@ -24,7 +24,7 @@ BSD - - PHP7 Support continued, reduce code duplication #7543 + - Fixed Ubuntu compile error #7571, #7642 @@ -249,5 +249,20 @@ - PHP7 Support continued, reduce code duplication #7543 + + + 1.0.0RC4 + 1.0.0RC4 + + + stable + stable + + 2016-08-09 + BSD + + - Fixed Ubuntu compile error #7571, #7642 + + From f789facafd66a4f1d789d5062f1dd17c0142c006 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Tue, 9 Aug 2016 22:01:17 -0700 Subject: [PATCH 198/279] minor text change --- examples/php/route_guide/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/php/route_guide/README.md b/examples/php/route_guide/README.md index 4e74a79f136..26f1704f122 100644 --- a/examples/php/route_guide/README.md +++ b/examples/php/route_guide/README.md @@ -1,6 +1,6 @@ #gRPC Basics: PHP sample code The files in this folder are the samples used in [gRPC Basics: PHP][], -a detailed tutorial for using gRPC in Ruby. +a detailed tutorial for using gRPC in PHP. [gRPC Basics: PHP]:http://www.grpc.io/docs/tutorials/basic/php.html From 5312815ff212e6d4bbea1f1f6264b1295ca0106c Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Tue, 9 Aug 2016 09:40:16 -0700 Subject: [PATCH 199/279] add netcore portability package dependency --- examples/csharp/helloworld-from-cli/Greeter/project.json | 3 +++ examples/csharp/helloworld-from-cli/GreeterClient/project.json | 3 +++ examples/csharp/helloworld-from-cli/GreeterServer/project.json | 3 +++ 3 files changed, 9 insertions(+) diff --git a/examples/csharp/helloworld-from-cli/Greeter/project.json b/examples/csharp/helloworld-from-cli/Greeter/project.json index e06854d1226..87749418100 100644 --- a/examples/csharp/helloworld-from-cli/Greeter/project.json +++ b/examples/csharp/helloworld-from-cli/Greeter/project.json @@ -13,6 +13,9 @@ "frameworkAssemblies": { "System.Runtime": "", "System.IO": "" + }, + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1" } } } diff --git a/examples/csharp/helloworld-from-cli/GreeterClient/project.json b/examples/csharp/helloworld-from-cli/GreeterClient/project.json index dc72a30eb81..c2bf694cd86 100644 --- a/examples/csharp/helloworld-from-cli/GreeterClient/project.json +++ b/examples/csharp/helloworld-from-cli/GreeterClient/project.json @@ -17,6 +17,9 @@ "frameworkAssemblies": { "System.Runtime": "", "System.IO": "" + }, + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1" } } } diff --git a/examples/csharp/helloworld-from-cli/GreeterServer/project.json b/examples/csharp/helloworld-from-cli/GreeterServer/project.json index 4bf201bef38..29a10670f43 100644 --- a/examples/csharp/helloworld-from-cli/GreeterServer/project.json +++ b/examples/csharp/helloworld-from-cli/GreeterServer/project.json @@ -17,6 +17,9 @@ "frameworkAssemblies": { "System.Runtime": "", "System.IO": "" + }, + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1" } } } From 4ce458339a556fe4890e66a2672a3414ad4647ef Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Wed, 10 Aug 2016 12:38:03 -0700 Subject: [PATCH 200/279] Remove warning about protobuf 3.0.0+ from the Makefile --- Makefile | 29 ----------------------------- templates/Makefile.template | 29 ----------------------------- 2 files changed, 58 deletions(-) diff --git a/Makefile b/Makefile index ad2ff32d419..e75dc3c2ea3 100644 --- a/Makefile +++ b/Makefile @@ -767,13 +767,6 @@ ifeq ($(MAKECMDGOALS),clean) NO_DEPS = true endif -INSTALL_OK = false -ifeq ($(HAS_VALID_PROTOC),true) -ifeq ($(HAS_SYSTEM_PROTOBUF_VERIFY),true) -INSTALL_OK = true -endif -endif - .SECONDARY = %.pb.h %.pb.cc PROTOC_PLUGINS = $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(BINDIR)/$(CONFIG)/grpc_csharp_plugin $(BINDIR)/$(CONFIG)/grpc_node_plugin $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin $(BINDIR)/$(CONFIG)/grpc_python_plugin $(BINDIR)/$(CONFIG)/grpc_ruby_plugin @@ -2285,28 +2278,6 @@ install-certs: etc/roots.pem $(Q) $(INSTALL) -d $(prefix)/share/grpc $(Q) $(INSTALL) etc/roots.pem $(prefix)/share/grpc/roots.pem -verify-install: -ifeq ($(INSTALL_OK),true) - @echo "Your system looks ready to go." - @echo -else - @echo "Warning: it looks like protoc 3.0.0+ isn't installed on your system," - @echo "which means that you won't be able to compile .proto files for use" - @echo "with gRPC." - @echo - @echo "If you are just using pre-compiled protocol buffers, or you otherwise" - @echo "have no need to compile .proto files, you can ignore this." - @echo - @echo "If you do need protobuf for some reason, you can download and install" - @echo "it from:" - @echo - @echo " https://github.com/google/protobuf/releases" - @echo - @echo "Once you've done so, you can re-run this check by doing:" - @echo - @echo " make verify-install" -endif - clean: $(E) "[CLEAN] Cleaning build directories." $(Q) $(RM) -rf $(OBJDIR) $(LIBDIR) $(BINDIR) $(GENDIR) cache.mk diff --git a/templates/Makefile.template b/templates/Makefile.template index 0cbd8bfdd55..bfa99d66d28 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -655,13 +655,6 @@ NO_DEPS = true endif - INSTALL_OK = false - ifeq ($(HAS_VALID_PROTOC),true) - ifeq ($(HAS_SYSTEM_PROTOBUF_VERIFY),true) - INSTALL_OK = true - endif - endif - .SECONDARY = %.pb.h %.pb.cc PROTOC_PLUGINS =\ @@ -1279,28 +1272,6 @@ $(Q) $(INSTALL) -d $(prefix)/share/grpc $(Q) $(INSTALL) etc/roots.pem $(prefix)/share/grpc/roots.pem - verify-install: - ifeq ($(INSTALL_OK),true) - @echo "Your system looks ready to go." - @echo - else - @echo "Warning: it looks like protoc 3.0.0+ isn't installed on your system," - @echo "which means that you won't be able to compile .proto files for use" - @echo "with gRPC." - @echo - @echo "If you are just using pre-compiled protocol buffers, or you otherwise" - @echo "have no need to compile .proto files, you can ignore this." - @echo - @echo "If you do need protobuf for some reason, you can download and install" - @echo "it from:" - @echo - @echo " https://github.com/google/protobuf/releases" - @echo - @echo "Once you've done so, you can re-run this check by doing:" - @echo - @echo " make verify-install" - endif - clean: $(E) "[CLEAN] Cleaning build directories." $(Q) $(RM) -rf $(OBJDIR) $(LIBDIR) $(BINDIR) $(GENDIR) cache.mk From a3c5535c64445ed77acbadde627851b6a417790a Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Wed, 10 Aug 2016 13:41:31 -0700 Subject: [PATCH 201/279] Remove use of verify-install target in Makefile --- Makefile | 2 +- templates/Makefile.template | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index e75dc3c2ea3..f5de4d129ca 100644 --- a/Makefile +++ b/Makefile @@ -2095,7 +2095,7 @@ $(OBJDIR)/$(CONFIG)/%.o : %.cc $(Q) mkdir -p `dirname $@` $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $< -install: install_c install_cxx install-plugins install-certs verify-install +install: install_c install_cxx install-plugins install-certs install_c: install-headers_c install-static_c install-shared_c diff --git a/templates/Makefile.template b/templates/Makefile.template index bfa99d66d28..6f768af31e0 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -1154,7 +1154,7 @@ $(Q) mkdir -p `dirname $@` $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $< - install: install_c install_cxx install-plugins install-certs verify-install + install: install_c install_cxx install-plugins install-certs install_c: install-headers_c install-static_c install-shared_c From 198f8b01946ac107700958ac6c2ea11ed523f2a5 Mon Sep 17 00:00:00 2001 From: Makarand Dharmapurikar Date: Wed, 10 Aug 2016 13:44:13 -0700 Subject: [PATCH 202/279] more fixes --- .../cronet/transport/cronet_transport.c | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c index e8746b4e6e6..dc6a780edaf 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.c +++ b/src/core/ext/transport/cronet/transport/cronet_transport.c @@ -75,6 +75,7 @@ enum OP_ID { OP_CANCEL_ERROR, OP_ON_COMPLETE, OP_FAILED, + OP_SUCCEEDED, OP_CANCELED, OP_RECV_MESSAGE_AND_ON_COMPLETE, OP_READ_REQ_MADE, @@ -91,6 +92,7 @@ const char *op_id_string[] = { "OP_CANCEL_ERROR", "OP_ON_COMPLETE", "OP_FAILED", + "OP_SUCCEEDED", "OP_CANCELED", "OP_RECV_MESSAGE_AND_ON_COMPLETE", "OP_READ_REQ_MADE", @@ -189,6 +191,8 @@ struct stream_obj { grpc_stream *curr_gs; cronet_bidirectional_stream *cbs; + // Used for executing callbacks for ops + grpc_exec_ctx exec_ctx; // This holds the state that is at stream level (response and req metadata) struct op_state state; @@ -227,7 +231,10 @@ static void add_to_storage(struct stream_obj *s, grpc_transport_stream_op *op) { static void execute_from_storage(stream_obj *s) { // Cycle through ops and try to take next action. Break when either // an action with callback is taken, or no action is possible. - gpr_mu_lock(&s->mu); + // This can be executed from the Cronet network thread via cronet callback + // or on the application supplied thread via the perform_stream_op function. + if (1) {//gpr_mu_lock(&s->mu) == 0) { + gpr_mu_lock(&s->mu); for (int i = 0; i < s->storage.wrptr; ) { CRONET_LOG(GPR_DEBUG, "calling execute_stream_op[%d]. done = %d", i, s->storage.pending_ops[i].done); if (s->storage.pending_ops[i].done) { @@ -242,7 +249,9 @@ static void execute_from_storage(stream_obj *s) { break; } } - gpr_mu_unlock(&s->mu); + gpr_mu_unlock(&s->mu); + } + grpc_exec_ctx_finish(&s->exec_ctx); } @@ -271,7 +280,9 @@ static void on_succeeded(cronet_bidirectional_stream *stream) { CRONET_LOG(GPR_DEBUG, "on_succeeded(%p)", stream); stream_obj *s = (stream_obj *)stream->annotation; cronet_bidirectional_stream_destroy(s->cbs); + s->state.state_callback_received[OP_FAILED] = true; s->cbs = NULL; + execute_from_storage(s); } static void on_request_headers_sent(cronet_bidirectional_stream *stream) { @@ -380,13 +391,6 @@ static void create_grpc_frame(gpr_slice_buffer *write_slice_buffer, memcpy(p, GPR_SLICE_START_PTR(slice), length); } -static void enqueue_callback(grpc_closure *callback, grpc_error *error) { - GPR_ASSERT(callback); - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_exec_ctx_sched(&exec_ctx, callback, error, NULL); - grpc_exec_ctx_finish(&exec_ctx); -} - static void convert_metadata_to_cronet_headers( grpc_linked_mdelem *head, const char *host, @@ -498,9 +502,10 @@ static bool op_can_be_run(grpc_transport_stream_op *curr_op, struct op_state *st // we haven't sent initial metadata yet else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) result = false; // we haven't sent message yet + // TODO: Streaming Write case is a problem. What if there is an outstanding write (2nd, 3rd,..) present. else if (curr_op->send_message && !stream_state->state_op_done[OP_SEND_MESSAGE]) result = false; // we haven't got on_write_completed for the send yet - else if (curr_op->send_message && !stream_state->state_callback_received[OP_SEND_MESSAGE]) result = false; + else if (stream_state->state_op_done[OP_SEND_MESSAGE] && !stream_state->state_callback_received[OP_SEND_MESSAGE]) result = false; } else if (op_id == OP_CANCEL_ERROR) { // already executed if (stream_state->state_op_done[OP_CANCEL_ERROR]) result = false; @@ -510,10 +515,12 @@ static bool op_can_be_run(grpc_transport_stream_op *curr_op, struct op_state *st // Check if every op that was asked for is done. else if (curr_op->send_initial_metadata && !stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) result = false; else if (curr_op->send_message && !stream_state->state_op_done[OP_SEND_MESSAGE]) result = false; + else if (curr_op->send_message && !stream_state->state_callback_received[OP_SEND_MESSAGE]) result = false; else if (curr_op->send_trailing_metadata && !stream_state->state_op_done[OP_SEND_TRAILING_METADATA]) result = false; else if (curr_op->recv_initial_metadata && !stream_state->state_op_done[OP_RECV_INITIAL_METADATA]) result = false; else if (curr_op->recv_message && !stream_state->state_op_done[OP_RECV_MESSAGE]) result = false; else if (curr_op->recv_trailing_metadata) { + //if (!stream_state->state_op_done[OP_SUCCEEDED]) result = false; gpr_log(GPR_DEBUG, "HACK!!"); // We aren't done with trailing metadata yet if (!stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) result = false; // We've asked for actual message in an earlier op, and it hasn't been delivered yet. @@ -521,7 +528,7 @@ static bool op_can_be_run(grpc_transport_stream_op *curr_op, struct op_state *st else if (stream_state->state_op_done[OP_READ_REQ_MADE]) { // If this op is not the one asking for read, (which means some earlier op has asked), and the // read hasn't been delivered. - if(!curr_op->recv_message && !stream_state->state_op_done[OP_RECV_MESSAGE_AND_ON_COMPLETE]) result = false; + if(!curr_op->recv_message && !stream_state->state_op_done[OP_SUCCEEDED]) result = false; } } // We should see at least one on_write_completed for the trailers that we sent @@ -563,9 +570,9 @@ static enum OP_RESULT execute_stream_op(struct op_and_state *oas) { if (!stream_state->state_op_done[OP_CANCEL_ERROR]) { grpc_chttp2_incoming_metadata_buffer_publish(&oas->s->state.rs.initial_metadata, stream_op->recv_initial_metadata); - enqueue_callback(stream_op->recv_initial_metadata_ready, GRPC_ERROR_NONE); + grpc_exec_ctx_sched(&s->exec_ctx, stream_op->recv_initial_metadata_ready, GRPC_ERROR_NONE, NULL); } else { - enqueue_callback(stream_op->recv_initial_metadata_ready, GRPC_ERROR_CANCELLED); + grpc_exec_ctx_sched(&s->exec_ctx, stream_op->recv_initial_metadata_ready, GRPC_ERROR_CANCELLED, NULL); } stream_state->state_op_done[OP_RECV_INITIAL_METADATA] = true; result = ACTION_TAKEN_NO_CALLBACK; @@ -595,7 +602,7 @@ static enum OP_RESULT execute_stream_op(struct op_and_state *oas) { } else if (stream_op->recv_message && op_can_be_run(stream_op, stream_state, &oas->state, OP_RECV_MESSAGE)) { CRONET_LOG(GPR_DEBUG, "running: %p OP_RECV_MESSAGE", oas); if (stream_state->state_op_done[OP_CANCEL_ERROR]) { - enqueue_callback(stream_op->recv_message_ready, GRPC_ERROR_CANCELLED); + grpc_exec_ctx_sched(&s->exec_ctx, stream_op->recv_message_ready, GRPC_ERROR_CANCELLED, NULL); stream_state->state_op_done[OP_RECV_MESSAGE] = true; } else if (stream_state->rs.length_field_received == false) { if (stream_state->rs.received_bytes == GRPC_HEADER_SIZE_IN_BYTES && stream_state->rs.remaining_bytes == 0) { @@ -620,7 +627,7 @@ static enum OP_RESULT execute_stream_op(struct op_and_state *oas) { gpr_slice_buffer_init(&stream_state->rs.read_slice_buffer); grpc_slice_buffer_stream_init(&stream_state->rs.sbs, &stream_state->rs.read_slice_buffer, 0); *((grpc_byte_buffer **)stream_op->recv_message) = (grpc_byte_buffer *)&stream_state->rs.sbs; - enqueue_callback(stream_op->recv_message_ready, GRPC_ERROR_NONE); + grpc_exec_ctx_sched(&s->exec_ctx, stream_op->recv_message_ready, GRPC_ERROR_NONE, NULL); stream_state->state_op_done[OP_RECV_MESSAGE] = true; oas->state.state_op_done[OP_RECV_MESSAGE] = true; // Also set per op state. result = ACTION_TAKEN_NO_CALLBACK; @@ -645,7 +652,7 @@ static enum OP_RESULT execute_stream_op(struct op_and_state *oas) { gpr_slice_buffer_add(&stream_state->rs.read_slice_buffer, read_data_slice); grpc_slice_buffer_stream_init(&stream_state->rs.sbs, &stream_state->rs.read_slice_buffer, 0); *((grpc_byte_buffer **)stream_op->recv_message) = (grpc_byte_buffer *)&stream_state->rs.sbs; - enqueue_callback(stream_op->recv_message_ready, GRPC_ERROR_NONE); + grpc_exec_ctx_sched(&s->exec_ctx, stream_op->recv_message_ready, GRPC_ERROR_NONE, NULL); stream_state->state_op_done[OP_RECV_MESSAGE] = true; oas->state.state_op_done[OP_RECV_MESSAGE] = true; // Also set per op state. // Clear read state of the stream, so next read op (if it were to come) will work @@ -682,7 +689,7 @@ static enum OP_RESULT execute_stream_op(struct op_and_state *oas) { // All ops are complete. Call the on_complete callback CRONET_LOG(GPR_DEBUG, "running: %p OP_ON_COMPLETE", oas); //CRONET_LOG(GPR_DEBUG, "calling on_complete"); - enqueue_callback(stream_op->on_complete, GRPC_ERROR_NONE); + grpc_exec_ctx_sched(&s->exec_ctx, stream_op->on_complete, GRPC_ERROR_NONE, NULL); // Instead of setting stream state, use the op state as on_complete is on per op basis oas->state.state_op_done[OP_ON_COMPLETE] = true; oas->done = true; // Mark this op as completed @@ -714,6 +721,7 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, memset(s->state.state_op_done, 0, sizeof(s->state.state_op_done)); memset(s->state.state_callback_received, 0, sizeof(s->state.state_callback_received)); gpr_mu_init(&s->mu); + s->exec_ctx = *exec_ctx; return 0; } From 35da822b442a60d5e9d0711cc046f9c578d63ad9 Mon Sep 17 00:00:00 2001 From: Makarand Dharmapurikar Date: Wed, 10 Aug 2016 14:53:40 -0700 Subject: [PATCH 203/279] WIP --- src/core/ext/transport/cronet/transport/cronet_transport.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c index dc6a780edaf..7e65def4de1 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.c +++ b/src/core/ext/transport/cronet/transport/cronet_transport.c @@ -280,7 +280,7 @@ static void on_succeeded(cronet_bidirectional_stream *stream) { CRONET_LOG(GPR_DEBUG, "on_succeeded(%p)", stream); stream_obj *s = (stream_obj *)stream->annotation; cronet_bidirectional_stream_destroy(s->cbs); - s->state.state_callback_received[OP_FAILED] = true; + s->state.state_callback_received[OP_SUCCEEDED] = true; s->cbs = NULL; execute_from_storage(s); } @@ -480,8 +480,8 @@ static bool op_can_be_run(grpc_transport_stream_op *curr_op, struct op_state *st // we haven't received headers yet. else if (!stream_state->state_callback_received[OP_RECV_INITIAL_METADATA]) result = false; } else if (op_id == OP_SEND_MESSAGE) { - // already executed - if (stream_state->state_op_done[OP_SEND_MESSAGE]) result = false; + // already executed (note we're checking op specific state, not stream state) + if (op_state->state_op_done[OP_SEND_MESSAGE]) result = false; // we haven't sent headers yet. else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) result = false; } else if (op_id == OP_RECV_MESSAGE) { @@ -599,6 +599,7 @@ static enum OP_RESULT execute_stream_op(struct op_and_state *oas) { result = ACTION_TAKEN_WITH_CALLBACK; } stream_state->state_op_done[OP_SEND_MESSAGE] = true; + oas->state.state_op_done[OP_SEND_MESSAGE] = true; } else if (stream_op->recv_message && op_can_be_run(stream_op, stream_state, &oas->state, OP_RECV_MESSAGE)) { CRONET_LOG(GPR_DEBUG, "running: %p OP_RECV_MESSAGE", oas); if (stream_state->state_op_done[OP_CANCEL_ERROR]) { From feef8081c1b700cd640d57496ef27901841c312e Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 10 Aug 2016 15:39:16 -0700 Subject: [PATCH 204/279] update original helloworld README --- examples/csharp/helloworld/README.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/examples/csharp/helloworld/README.md b/examples/csharp/helloworld/README.md index d13c9ac9db4..71840ad48bf 100644 --- a/examples/csharp/helloworld/README.md +++ b/examples/csharp/helloworld/README.md @@ -13,7 +13,7 @@ PREREQUISITES ------------- - Windows: .NET Framework 4.5+, Visual Studio 2013 or 2015 -- Linux: Mono 4+, MonoDevelop 5.9+ (with NuGet add-in installed) +- Linux: Mono 4+, MonoDevelop 5.9+ - Mac OS X: Xamarin Studio 5.9+ BUILD @@ -21,7 +21,20 @@ BUILD - Open solution `Greeter.sln` with Visual Studio, Monodevelop (on Linux) or Xamarin Studio (on Mac OS X) -- Build the solution (this will automatically download NuGet dependencies) +# Using Visual Studio + +* Build the solution (this will automatically download NuGet dependencies) + +# Using Monodevelop or Xamarin Studio + +The nuget add-in available for Xamarin Studio and Monodevelop IDEs is too old to +download all of the nuget dependencies of gRPC. One alternative to is to use the dotnet command line tools instead (see [helloworld-from-cli]). + +Using these IDEs, a workaround is as follows: +* Obtain a nuget executable for your platform and update it with + `nuget update -self`. +* Navigate to this directory and run `nuget restore`. +* Now that packages have been restored into their proper package folder, build the solution from your IDE. Try it! ------- @@ -49,5 +62,6 @@ Tutorial You can find a more detailed tutorial in [gRPC Basics: C#][] +[helloworld-from-cli]:../helloworld-from-cli/README.md [helloworld.proto]:../../protos/helloworld.proto [gRPC Basics: C#]:http://www.grpc.io/docs/tutorials/basic/csharp.html From f66a37b63aed77732c8d7d253af89296a23bb72e Mon Sep 17 00:00:00 2001 From: Makarand Dharmapurikar Date: Wed, 10 Aug 2016 17:47:25 -0700 Subject: [PATCH 205/279] WIP --- .../cronet/transport/cronet_transport.c | 597 +++++++++++------- 1 file changed, 356 insertions(+), 241 deletions(-) diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c index 7e65def4de1..1d756039809 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.c +++ b/src/core/ext/transport/cronet/transport/cronet_transport.c @@ -50,8 +50,17 @@ #include "third_party/objective_c/Cronet/cronet_c_for_grpc.h" #define GRPC_HEADER_SIZE_IN_BYTES 5 +// maximum ops in a batch. There is not much thinking behind this limit, except +// that it seems to be enough for most use cases. +#define MAX_PENDING_OPS 100 + +#define CRONET_LOG(...) \ + { \ + if (grpc_cronet_trace) gpr_log(__VA_ARGS__); \ + } -#define CRONET_LOG(...) {if (1) gpr_log(__VA_ARGS__);} +// TODO (makdharma): Hook up into the wider tracing mechanism +int grpc_cronet_trace = 1; enum OP_RESULT { ACTION_TAKEN_WITH_CALLBACK, @@ -59,11 +68,10 @@ enum OP_RESULT { NO_ACTION_POSSIBLE }; -const char *OP_RESULT_STRING[] = { - "ACTION_TAKEN_WITH_CALLBACK", - "ACTION_TAKEN_NO_CALLBACK", - "NO_ACTION_POSSIBLE" -}; +// Used for printing debug +const char *op_result_string[] = {"ACTION_TAKEN_WITH_CALLBACK", + "ACTION_TAKEN_NO_CALLBACK", + "NO_ACTION_POSSIBLE"}; enum OP_ID { OP_SEND_INITIAL_METADATA = 0, @@ -82,32 +90,31 @@ enum OP_ID { OP_NUM_OPS }; -const char *op_id_string[] = { - "OP_SEND_INITIAL_METADATA", - "OP_SEND_MESSAGE", - "OP_SEND_TRAILING_METADATA", - "OP_RECV_MESSAGE", - "OP_RECV_INITIAL_METADATA", - "OP_RECV_TRAILING_METADATA", - "OP_CANCEL_ERROR", - "OP_ON_COMPLETE", - "OP_FAILED", - "OP_SUCCEEDED", - "OP_CANCELED", - "OP_RECV_MESSAGE_AND_ON_COMPLETE", - "OP_READ_REQ_MADE", - "OP_NUM_OPS" -}; +const char *op_id_string[] = {"OP_SEND_INITIAL_METADATA", + "OP_SEND_MESSAGE", + "OP_SEND_TRAILING_METADATA", + "OP_RECV_MESSAGE", + "OP_RECV_INITIAL_METADATA", + "OP_RECV_TRAILING_METADATA", + "OP_CANCEL_ERROR", + "OP_ON_COMPLETE", + "OP_FAILED", + "OP_SUCCEEDED", + "OP_CANCELED", + "OP_RECV_MESSAGE_AND_ON_COMPLETE", + "OP_READ_REQ_MADE", + "OP_NUM_OPS"}; /* Cronet callbacks */ static void on_request_headers_sent(cronet_bidirectional_stream *); -static void on_response_headers_received(cronet_bidirectional_stream *, - const cronet_bidirectional_stream_header_array *, - const char *); +static void on_response_headers_received( + cronet_bidirectional_stream *, + const cronet_bidirectional_stream_header_array *, const char *); static void on_write_completed(cronet_bidirectional_stream *, const char *); static void on_read_completed(cronet_bidirectional_stream *, char *, int); -static void on_response_trailers_received(cronet_bidirectional_stream *, +static void on_response_trailers_received( + cronet_bidirectional_stream *, const cronet_bidirectional_stream_header_array *); static void on_succeeded(cronet_bidirectional_stream *); static void on_failed(cronet_bidirectional_stream *, int); @@ -120,8 +127,7 @@ static cronet_bidirectional_stream_callback cronet_callbacks = { on_response_trailers_received, on_succeeded, on_failed, - on_canceled -}; + on_canceled}; // Cronet transport object struct grpc_cronet_transport { @@ -132,7 +138,7 @@ struct grpc_cronet_transport { typedef struct grpc_cronet_transport grpc_cronet_transport; struct read_state { - // vars to store data coming from cronet + /* vars to store data coming from server */ char *read_buffer; bool length_field_received; int received_bytes; @@ -141,15 +147,15 @@ struct read_state { char grpc_header_bytes[GRPC_HEADER_SIZE_IN_BYTES]; char *payload_field; - // vars for holding data destined for the application + /* vars for holding data destined for the application */ struct grpc_slice_buffer_stream sbs; gpr_slice_buffer read_slice_buffer; - // vars for trailing metadata + /* vars for trailing metadata */ grpc_chttp2_incoming_metadata_buffer trailing_metadata; bool trailing_metadata_valid; - // vars for initial metadata + /* vars for initial metadata */ grpc_chttp2_incoming_metadata_buffer initial_metadata; }; @@ -157,16 +163,13 @@ struct write_state { char *write_buffer; }; -// maximum ops in a batch.. There is not much thinking behind this limit, except -// that it seems to be enough for most use cases. -#define MAX_PENDING_OPS 100 - +/* track state of one stream op */ struct op_state { bool state_op_done[OP_NUM_OPS]; bool state_callback_received[OP_NUM_OPS]; - // data structure for storing data coming from server + /* data structure for storing data coming from server */ struct read_state rs; - // data structure for storing data going to the server + /* data structure for storing data going to the server */ struct write_state ws; }; @@ -174,7 +177,7 @@ struct op_and_state { grpc_transport_stream_op op; struct op_state state; bool done; - struct stream_obj *s; // Pointer back to the stream object + struct stream_obj *s; /* Pointer back to the stream object */ }; struct op_storage { @@ -190,73 +193,74 @@ struct stream_obj { grpc_cronet_transport curr_ct; grpc_stream *curr_gs; cronet_bidirectional_stream *cbs; + cronet_bidirectional_stream_header_array header_array; - // Used for executing callbacks for ops + /* Used for executing callbacks for ops */ grpc_exec_ctx exec_ctx; - // This holds the state that is at stream level (response and req metadata) + /* Stream level state. Some state will be tracked both at stream and stream_op + * level */ struct op_state state; - //struct op_state state; - // OP storage + /* OP storage */ struct op_storage storage; - // Mutex to protect execute_curr_streaming_op + /* Mutex to protect storage */ gpr_mu mu; }; typedef struct stream_obj stream_obj; -/* Globals */ -cronet_bidirectional_stream_header_array header_array; - -// static enum OP_RESULT execute_stream_op(struct op_and_state *oas); -/************************************************************* - Op Storage +/* + Add a new stream op to op storage. */ - static void add_to_storage(struct stream_obj *s, grpc_transport_stream_op *op) { + gpr_mu_lock(&s->mu); struct op_storage *storage = &s->storage; GPR_ASSERT(storage->num_pending_ops < MAX_PENDING_OPS); storage->num_pending_ops++; CRONET_LOG(GPR_DEBUG, "adding new op @wrptr=%d. %d in the queue.", - storage->wrptr, storage->num_pending_ops); - memcpy(&storage->pending_ops[storage->wrptr].op, op, sizeof(grpc_transport_stream_op)); - memset(&storage->pending_ops[storage->wrptr].state, 0, sizeof(storage->pending_ops[storage->wrptr].state)); + storage->wrptr, storage->num_pending_ops); + memcpy(&storage->pending_ops[storage->wrptr].op, op, + sizeof(grpc_transport_stream_op)); + memset(&storage->pending_ops[storage->wrptr].state, 0, + sizeof(storage->pending_ops[storage->wrptr].state)); storage->pending_ops[storage->wrptr].done = false; storage->pending_ops[storage->wrptr].s = s; - storage->wrptr = (storage->wrptr + 1) % MAX_PENDING_OPS; + storage->wrptr = (storage->wrptr + 1) % MAX_PENDING_OPS; + gpr_mu_unlock(&s->mu); } +/* + Cycle through ops and try to take next action. Break when either + an action with callback is taken, or no action is possible. + This can be executed from the Cronet network thread via cronet callback + or on the application supplied thread via the perform_stream_op function. +*/ static void execute_from_storage(stream_obj *s) { - // Cycle through ops and try to take next action. Break when either - // an action with callback is taken, or no action is possible. - // This can be executed from the Cronet network thread via cronet callback - // or on the application supplied thread via the perform_stream_op function. - if (1) {//gpr_mu_lock(&s->mu) == 0) { - gpr_mu_lock(&s->mu); - for (int i = 0; i < s->storage.wrptr; ) { - CRONET_LOG(GPR_DEBUG, "calling execute_stream_op[%d]. done = %d", i, s->storage.pending_ops[i].done); - if (s->storage.pending_ops[i].done) { - i++; - continue; - } - enum OP_RESULT result = execute_stream_op(&s->storage.pending_ops[i]); - CRONET_LOG(GPR_DEBUG, "%s = execute_stream_op[%d]", OP_RESULT_STRING[result], i); - if (result == NO_ACTION_POSSIBLE) { - i++; - } else if (result == ACTION_TAKEN_WITH_CALLBACK) { - break; - } + gpr_mu_lock(&s->mu); + for (int i = 0; i < s->storage.wrptr;) { + CRONET_LOG(GPR_DEBUG, "calling execute_stream_op[%d]. done = %d", i, + s->storage.pending_ops[i].done); + if (s->storage.pending_ops[i].done) { + i++; + continue; + } + enum OP_RESULT result = execute_stream_op(&s->storage.pending_ops[i]); + CRONET_LOG(GPR_DEBUG, "%s = execute_stream_op[%d]", + op_result_string[result], i); + if (result == NO_ACTION_POSSIBLE) { + i++; + } else if (result == ACTION_TAKEN_WITH_CALLBACK) { + break; } - gpr_mu_unlock(&s->mu); } + gpr_mu_unlock(&s->mu); grpc_exec_ctx_finish(&s->exec_ctx); } - -/************************************************************* -Cronet Callback Ipmlementation +/* + Cronet callback */ static void on_failed(cronet_bidirectional_stream *stream, int net_error) { CRONET_LOG(GPR_DEBUG, "on_failed(%p, %d)", stream, net_error); @@ -267,6 +271,9 @@ static void on_failed(cronet_bidirectional_stream *stream, int net_error) { execute_from_storage(s); } +/* + Cronet callback +*/ static void on_canceled(cronet_bidirectional_stream *stream) { CRONET_LOG(GPR_DEBUG, "on_canceled(%p)", stream); stream_obj *s = (stream_obj *)stream->annotation; @@ -276,6 +283,9 @@ static void on_canceled(cronet_bidirectional_stream *stream) { execute_from_storage(s); } +/* + Cronet callback +*/ static void on_succeeded(cronet_bidirectional_stream *stream) { CRONET_LOG(GPR_DEBUG, "on_succeeded(%p)", stream); stream_obj *s = (stream_obj *)stream->annotation; @@ -285,22 +295,33 @@ static void on_succeeded(cronet_bidirectional_stream *stream) { execute_from_storage(s); } +/* + Cronet callback +*/ static void on_request_headers_sent(cronet_bidirectional_stream *stream) { CRONET_LOG(GPR_DEBUG, "W: on_request_headers_sent(%p)", stream); stream_obj *s = (stream_obj *)stream->annotation; s->state.state_op_done[OP_SEND_INITIAL_METADATA] = true; s->state.state_callback_received[OP_SEND_INITIAL_METADATA] = true; + /* Free the memory allocated for headers */ + if (s->header_array.headers) { + gpr_free(s->header_array.headers); + } execute_from_storage(s); } +/* + Cronet callback +*/ static void on_response_headers_received( cronet_bidirectional_stream *stream, const cronet_bidirectional_stream_header_array *headers, const char *negotiated_protocol) { CRONET_LOG(GPR_DEBUG, "R: on_response_headers_received(%p, %p, %s)", stream, - headers, negotiated_protocol); + headers, negotiated_protocol); stream_obj *s = (stream_obj *)stream->annotation; - memset(&s->state.rs.initial_metadata, 0, sizeof(s->state.rs.initial_metadata)); + memset(&s->state.rs.initial_metadata, 0, + sizeof(s->state.rs.initial_metadata)); grpc_chttp2_incoming_metadata_buffer_init(&s->state.rs.initial_metadata); unsigned int i = 0; for (i = 0; i < headers->count; i++) { @@ -314,6 +335,9 @@ static void on_response_headers_received( execute_from_storage(s); } +/* + Cronet callback +*/ static void on_write_completed(cronet_bidirectional_stream *stream, const char *data) { stream_obj *s = (stream_obj *)stream->annotation; @@ -326,17 +350,23 @@ static void on_write_completed(cronet_bidirectional_stream *stream, execute_from_storage(s); } +/* + Cronet callback +*/ static void on_read_completed(cronet_bidirectional_stream *stream, char *data, int count) { stream_obj *s = (stream_obj *)stream->annotation; - CRONET_LOG(GPR_DEBUG, "R: on_read_completed(%p, %p, %d)", stream, data, count); + CRONET_LOG(GPR_DEBUG, "R: on_read_completed(%p, %p, %d)", stream, data, + count); if (count > 0) { s->state.rs.received_bytes += count; s->state.rs.remaining_bytes -= count; if (s->state.rs.remaining_bytes > 0) { - //CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_read"); - s->state.state_op_done[OP_READ_REQ_MADE] = true; // If at least one read request has been made - cronet_bidirectional_stream_read(s->cbs, s->state.rs.read_buffer + s->state.rs.received_bytes, s->state.rs.remaining_bytes); + CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_read"); + s->state.state_op_done[OP_READ_REQ_MADE] = true; + cronet_bidirectional_stream_read( + s->cbs, s->state.rs.read_buffer + s->state.rs.received_bytes, + s->state.rs.remaining_bytes); } else { execute_from_storage(s); } @@ -344,76 +374,82 @@ static void on_read_completed(cronet_bidirectional_stream *stream, char *data, } } +/* + Cronet callback +*/ static void on_response_trailers_received( cronet_bidirectional_stream *stream, const cronet_bidirectional_stream_header_array *trailers) { CRONET_LOG(GPR_DEBUG, "R: on_response_trailers_received(%p,%p)", stream, - trailers); + trailers); stream_obj *s = (stream_obj *)stream->annotation; - memset(&s->state.rs.trailing_metadata, 0, sizeof(s->state.rs.trailing_metadata)); + memset(&s->state.rs.trailing_metadata, 0, + sizeof(s->state.rs.trailing_metadata)); s->state.rs.trailing_metadata_valid = false; grpc_chttp2_incoming_metadata_buffer_init(&s->state.rs.trailing_metadata); unsigned int i = 0; for (i = 0; i < trailers->count; i++) { CRONET_LOG(GPR_DEBUG, "trailer key=%s, value=%s", trailers->headers[i].key, - trailers->headers[i].value); + trailers->headers[i].value); grpc_chttp2_incoming_metadata_buffer_add( - &s->state.rs.trailing_metadata, grpc_mdelem_from_metadata_strings( - grpc_mdstr_from_string(trailers->headers[i].key), - grpc_mdstr_from_string(trailers->headers[i].value))); + &s->state.rs.trailing_metadata, + grpc_mdelem_from_metadata_strings( + grpc_mdstr_from_string(trailers->headers[i].key), + grpc_mdstr_from_string(trailers->headers[i].value))); s->state.rs.trailing_metadata_valid = true; } s->state.state_callback_received[OP_RECV_TRAILING_METADATA] = true; execute_from_storage(s); } -/************************************************************* -Utility functions. Can be in their own file +/* + Utility function that takes the data from s->write_slice_buffer and assembles + into a contiguous byte stream with 5 byte gRPC header prepended. */ -// This function takes the data from s->write_slice_buffer and assembles into -// a contiguous byte stream with 5 byte gRPC header prepended. static void create_grpc_frame(gpr_slice_buffer *write_slice_buffer, - char **pp_write_buffer, int *p_write_buffer_size) { + char **pp_write_buffer, + int *p_write_buffer_size) { gpr_slice slice = gpr_slice_buffer_take_first(write_slice_buffer); size_t length = GPR_SLICE_LENGTH(slice); - // TODO (makdharma): FREE THIS!! HACK! *p_write_buffer_size = (int)length + GRPC_HEADER_SIZE_IN_BYTES; + /* This is freed in the on_write_completed callback */ char *write_buffer = gpr_malloc(length + GRPC_HEADER_SIZE_IN_BYTES); *pp_write_buffer = write_buffer; uint8_t *p = (uint8_t *)write_buffer; - // Append 5 byte header + /* Append 5 byte header */ *p++ = 0; *p++ = (uint8_t)(length >> 24); *p++ = (uint8_t)(length >> 16); *p++ = (uint8_t)(length >> 8); *p++ = (uint8_t)(length); - // append actual data + /* append actual data */ memcpy(p, GPR_SLICE_START_PTR(slice), length); } +/* + Convert metadata in a format that Cronet can consume +*/ static void convert_metadata_to_cronet_headers( - grpc_linked_mdelem *head, - const char *host, - char **pp_url, - cronet_bidirectional_stream_header **pp_headers, - size_t *p_num_headers) { + grpc_linked_mdelem *head, const char *host, char **pp_url, + cronet_bidirectional_stream_header **pp_headers, size_t *p_num_headers) { grpc_linked_mdelem *curr = head; - // Walk the linked list and get number of header fields + /* Walk the linked list and get number of header fields */ uint32_t num_headers_available = 0; while (curr != NULL) { curr = curr->next; num_headers_available++; } - // Allocate enough memory. TODO (makdharma): FREE MEMORY! HACK HACK - cronet_bidirectional_stream_header *headers = - (cronet_bidirectional_stream_header *)gpr_malloc( - sizeof(cronet_bidirectional_stream_header) * num_headers_available); + /* Allocate enough memory. It is freed in the on_request_headers_sent callback + */ + cronet_bidirectional_stream_header *headers = + (cronet_bidirectional_stream_header *)gpr_malloc( + sizeof(cronet_bidirectional_stream_header) * num_headers_available); *pp_headers = headers; - // Walk the linked list again, this time copying the header fields. - // s->num_headers - // can be less than num_headers_available, as some headers are not used for - // cronet + /* Walk the linked list again, this time copying the header fields. + s->num_headers can be less than num_headers_available, as some headers + are not used for cronet + */ curr = head; int num_headers = 0; while (num_headers < num_headers_available) { @@ -423,15 +459,15 @@ static void convert_metadata_to_cronet_headers( const char *value = grpc_mdstr_as_c_string(mdelem->value); if (strcmp(key, ":scheme") == 0 || strcmp(key, ":method") == 0 || strcmp(key, ":authority") == 0) { - // Cronet populates these fields on its own. + /* Cronet populates these fields on its own */ continue; } if (strcmp(key, ":path") == 0) { - // Create URL by appending :path value to the hostname + /* Create URL by appending :path value to the hostname */ gpr_asprintf(pp_url, "https://%s%s", host, value); continue; } - gpr_log(GPR_DEBUG, "header %s = %s", key, value); + CRONET_LOG(GPR_DEBUG, "header %s = %s", key, value); headers[num_headers].key = key; headers[num_headers].value = value; num_headers++; @@ -453,261 +489,342 @@ static int parse_grpc_header(const uint8_t *data) { } /* -Op Execution + Op Execution: Decide if one of the actions contained in the stream op can be + executed. This is the heart of the state machine. */ -static bool op_can_be_run(grpc_transport_stream_op *curr_op, struct op_state *stream_state, struct op_state *op_state, enum OP_ID op_id) { - // We use op's own state for most state, except for metadata related callbacks, which - // are at the stream level. TODO: WTF does this comment mean? +static bool op_can_be_run(grpc_transport_stream_op *curr_op, + struct op_state *stream_state, + struct op_state *op_state, enum OP_ID op_id) { bool result = true; - // When call is canceled, every op can be run - if (stream_state->state_op_done[OP_CANCEL_ERROR] || stream_state->state_callback_received[OP_FAILED]) { + /* When call is canceled, every op can be run, except under following + conditions + */ + if (stream_state->state_op_done[OP_CANCEL_ERROR] || + stream_state->state_callback_received[OP_FAILED]) { if (op_id == OP_SEND_INITIAL_METADATA) result = false; if (op_id == OP_SEND_MESSAGE) result = false; if (op_id == OP_SEND_TRAILING_METADATA) result = false; if (op_id == OP_CANCEL_ERROR) result = false; - // already executed - if (op_id == OP_RECV_INITIAL_METADATA && stream_state->state_op_done[OP_RECV_INITIAL_METADATA]) result = false; - if (op_id == OP_RECV_MESSAGE && stream_state->state_op_done[OP_RECV_MESSAGE]) result = false; - if (op_id == OP_RECV_TRAILING_METADATA && stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) result = false; + /* already executed */ + if (op_id == OP_RECV_INITIAL_METADATA && + stream_state->state_op_done[OP_RECV_INITIAL_METADATA]) + result = false; + if (op_id == OP_RECV_MESSAGE && + stream_state->state_op_done[OP_RECV_MESSAGE]) + result = false; + if (op_id == OP_RECV_TRAILING_METADATA && + stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) + result = false; } else if (op_id == OP_SEND_INITIAL_METADATA) { - // already executed + /* already executed */ if (stream_state->state_op_done[OP_SEND_INITIAL_METADATA]) result = false; } else if (op_id == OP_RECV_INITIAL_METADATA) { - // already executed + /* already executed */ if (stream_state->state_op_done[OP_RECV_INITIAL_METADATA]) result = false; - // we haven't sent headers yet. - else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) result = false; - // we haven't received headers yet. - else if (!stream_state->state_callback_received[OP_RECV_INITIAL_METADATA]) result = false; + /* we haven't sent headers yet. */ + else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) + result = false; + /* we haven't received headers yet. */ + else if (!stream_state->state_callback_received[OP_RECV_INITIAL_METADATA]) + result = false; } else if (op_id == OP_SEND_MESSAGE) { - // already executed (note we're checking op specific state, not stream state) + /* already executed (note we're checking op specific state, not stream + state) */ if (op_state->state_op_done[OP_SEND_MESSAGE]) result = false; - // we haven't sent headers yet. - else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) result = false; + /* we haven't sent headers yet. */ + else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) + result = false; } else if (op_id == OP_RECV_MESSAGE) { - // already executed + /* already executed */ if (op_state->state_op_done[OP_RECV_MESSAGE]) result = false; - // we haven't received headers yet. - else if (!stream_state->state_callback_received[OP_RECV_INITIAL_METADATA]) result = false; + /* we haven't received headers yet. */ + else if (!stream_state->state_callback_received[OP_RECV_INITIAL_METADATA]) + result = false; } else if (op_id == OP_RECV_TRAILING_METADATA) { - // already executed + /* already executed */ if (stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) result = false; - // we have asked for but haven't received message yet. - else if (stream_state->state_op_done[OP_READ_REQ_MADE] && !stream_state->state_op_done[OP_RECV_MESSAGE]) result = false; - // we haven't received trailers yet. - else if (!stream_state->state_callback_received[OP_RECV_TRAILING_METADATA]) result = false; + /* we have asked for but haven't received message yet. */ + else if (stream_state->state_op_done[OP_READ_REQ_MADE] && + !stream_state->state_op_done[OP_RECV_MESSAGE]) + result = false; + /* we haven't received trailers yet. */ + else if (!stream_state->state_callback_received[OP_RECV_TRAILING_METADATA]) + result = false; } else if (op_id == OP_SEND_TRAILING_METADATA) { - // already executed + /* already executed */ if (stream_state->state_op_done[OP_SEND_TRAILING_METADATA]) result = false; - // we haven't sent initial metadata yet - else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) result = false; - // we haven't sent message yet - // TODO: Streaming Write case is a problem. What if there is an outstanding write (2nd, 3rd,..) present. - else if (curr_op->send_message && !stream_state->state_op_done[OP_SEND_MESSAGE]) result = false; - // we haven't got on_write_completed for the send yet - else if (stream_state->state_op_done[OP_SEND_MESSAGE] && !stream_state->state_callback_received[OP_SEND_MESSAGE]) result = false; + /* we haven't sent initial metadata yet */ + else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) + result = false; + /* we haven't sent message yet */ + else if (curr_op->send_message && + !stream_state->state_op_done[OP_SEND_MESSAGE]) + result = false; + /* we haven't got on_write_completed for the send yet */ + else if (stream_state->state_op_done[OP_SEND_MESSAGE] && + !stream_state->state_callback_received[OP_SEND_MESSAGE]) + result = false; } else if (op_id == OP_CANCEL_ERROR) { - // already executed + /* already executed */ if (stream_state->state_op_done[OP_CANCEL_ERROR]) result = false; } else if (op_id == OP_ON_COMPLETE) { - // already executed (note we're checking op specific state, not stream state) + /* already executed (note we're checking op specific state, not stream + state) */ if (op_state->state_op_done[OP_ON_COMPLETE]) result = false; - // Check if every op that was asked for is done. - else if (curr_op->send_initial_metadata && !stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) result = false; - else if (curr_op->send_message && !stream_state->state_op_done[OP_SEND_MESSAGE]) result = false; - else if (curr_op->send_message && !stream_state->state_callback_received[OP_SEND_MESSAGE]) result = false; - else if (curr_op->send_trailing_metadata && !stream_state->state_op_done[OP_SEND_TRAILING_METADATA]) result = false; - else if (curr_op->recv_initial_metadata && !stream_state->state_op_done[OP_RECV_INITIAL_METADATA]) result = false; - else if (curr_op->recv_message && !stream_state->state_op_done[OP_RECV_MESSAGE]) result = false; + /* Check if every op that was asked for is done. */ + else if (curr_op->send_initial_metadata && + !stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) + result = false; + else if (curr_op->send_message && + !stream_state->state_op_done[OP_SEND_MESSAGE]) + result = false; + else if (curr_op->send_message && + !stream_state->state_callback_received[OP_SEND_MESSAGE]) + result = false; + else if (curr_op->send_trailing_metadata && + !stream_state->state_op_done[OP_SEND_TRAILING_METADATA]) + result = false; + else if (curr_op->recv_initial_metadata && + !stream_state->state_op_done[OP_RECV_INITIAL_METADATA]) + result = false; + else if (curr_op->recv_message && + !stream_state->state_op_done[OP_RECV_MESSAGE]) + result = false; else if (curr_op->recv_trailing_metadata) { - //if (!stream_state->state_op_done[OP_SUCCEEDED]) result = false; gpr_log(GPR_DEBUG, "HACK!!"); - // We aren't done with trailing metadata yet - if (!stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) result = false; - // We've asked for actual message in an earlier op, and it hasn't been delivered yet. - // (TODO: What happens when multiple messages are asked for? How do you know when last message arrived?) + /* We aren't done with trailing metadata yet */ + if (!stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) + result = false; + /* We've asked for actual message in an earlier op, and it hasn't been + delivered yet. */ else if (stream_state->state_op_done[OP_READ_REQ_MADE]) { - // If this op is not the one asking for read, (which means some earlier op has asked), and the - // read hasn't been delivered. - if(!curr_op->recv_message && !stream_state->state_op_done[OP_SUCCEEDED]) result = false; + /* If this op is not the one asking for read, (which means some earlier + op has asked), and the read hasn't been delivered. */ + if (!curr_op->recv_message && + !stream_state->state_op_done[OP_SUCCEEDED]) + result = false; } } - // We should see at least one on_write_completed for the trailers that we sent - else if (curr_op->send_trailing_metadata && !stream_state->state_callback_received[OP_SEND_MESSAGE]) result = false; + /* We should see at least one on_write_completed for the trailers that we + sent */ + else if (curr_op->send_trailing_metadata && + !stream_state->state_callback_received[OP_SEND_MESSAGE]) + result = false; } - CRONET_LOG(GPR_DEBUG, "op_can_be_run %s : %s", op_id_string[op_id], result? "YES":"NO"); + CRONET_LOG(GPR_DEBUG, "op_can_be_run %s : %s", op_id_string[op_id], + result ? "YES" : "NO"); return result; } static enum OP_RESULT execute_stream_op(struct op_and_state *oas) { - // TODO TODO : This can be called from network thread and main thread. add a mutex. grpc_transport_stream_op *stream_op = &oas->op; struct stream_obj *s = oas->s; struct op_state *stream_state = &s->state; - //CRONET_LOG(GPR_DEBUG, "execute_stream_op"); enum OP_RESULT result = NO_ACTION_POSSIBLE; - if (stream_op->send_initial_metadata && op_can_be_run(stream_op, stream_state, &oas->state, OP_SEND_INITIAL_METADATA)) { + if (stream_op->send_initial_metadata && + op_can_be_run(stream_op, stream_state, &oas->state, + OP_SEND_INITIAL_METADATA)) { CRONET_LOG(GPR_DEBUG, "running: %p OP_SEND_INITIAL_METADATA", oas); - // This OP is the beginning. Reset various states + /* This OP is the beginning. Reset various states */ memset(&stream_state->rs, 0, sizeof(stream_state->rs)); memset(&stream_state->ws, 0, sizeof(stream_state->ws)); memset(stream_state->state_op_done, 0, sizeof(stream_state->state_op_done)); - memset(stream_state->state_callback_received, 0, sizeof(stream_state->state_callback_received)); - // Start new cronet stream + memset(stream_state->state_callback_received, 0, + sizeof(stream_state->state_callback_received)); + /* Start new cronet stream. It is destroyed in on_succeeded, on_canceled, + * on_failed */ GPR_ASSERT(s->cbs == NULL); CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_create"); - s->cbs = cronet_bidirectional_stream_create(s->curr_ct.engine, s->curr_gs, &cronet_callbacks); + s->cbs = cronet_bidirectional_stream_create(s->curr_ct.engine, s->curr_gs, + &cronet_callbacks); char *url; - convert_metadata_to_cronet_headers(stream_op->send_initial_metadata->list.head, - s->curr_ct.host, &url, &header_array.headers, &header_array.count); - header_array.capacity = header_array.count; + convert_metadata_to_cronet_headers( + stream_op->send_initial_metadata->list.head, s->curr_ct.host, &url, + &s->header_array.headers, &s->header_array.count); + s->header_array.capacity = s->header_array.count; CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_start %s", url); - cronet_bidirectional_stream_start(s->cbs, url, 0, "POST", &header_array, false); + cronet_bidirectional_stream_start(s->cbs, url, 0, "POST", &s->header_array, + false); stream_state->state_op_done[OP_SEND_INITIAL_METADATA] = true; result = ACTION_TAKEN_WITH_CALLBACK; } else if (stream_op->recv_initial_metadata && - op_can_be_run(stream_op, stream_state, &oas->state, OP_RECV_INITIAL_METADATA)) { + op_can_be_run(stream_op, stream_state, &oas->state, + OP_RECV_INITIAL_METADATA)) { CRONET_LOG(GPR_DEBUG, "running: %p OP_RECV_INITIAL_METADATA", oas); if (!stream_state->state_op_done[OP_CANCEL_ERROR]) { - grpc_chttp2_incoming_metadata_buffer_publish(&oas->s->state.rs.initial_metadata, - stream_op->recv_initial_metadata); - grpc_exec_ctx_sched(&s->exec_ctx, stream_op->recv_initial_metadata_ready, GRPC_ERROR_NONE, NULL); + grpc_chttp2_incoming_metadata_buffer_publish( + &oas->s->state.rs.initial_metadata, stream_op->recv_initial_metadata); + grpc_exec_ctx_sched(&s->exec_ctx, stream_op->recv_initial_metadata_ready, + GRPC_ERROR_NONE, NULL); } else { - grpc_exec_ctx_sched(&s->exec_ctx, stream_op->recv_initial_metadata_ready, GRPC_ERROR_CANCELLED, NULL); + grpc_exec_ctx_sched(&s->exec_ctx, stream_op->recv_initial_metadata_ready, + GRPC_ERROR_CANCELLED, NULL); } stream_state->state_op_done[OP_RECV_INITIAL_METADATA] = true; result = ACTION_TAKEN_NO_CALLBACK; - } else if (stream_op->send_message && op_can_be_run(stream_op, stream_state, &oas->state, OP_SEND_MESSAGE)) { + } else if (stream_op->send_message && + op_can_be_run(stream_op, stream_state, &oas->state, + OP_SEND_MESSAGE)) { CRONET_LOG(GPR_DEBUG, "running: %p OP_SEND_MESSAGE", oas); - // TODO (makdharma): Make into a standalone function gpr_slice_buffer write_slice_buffer; gpr_slice slice; gpr_slice_buffer_init(&write_slice_buffer); grpc_byte_stream_next(NULL, stream_op->send_message, &slice, stream_op->send_message->length, NULL); - // Check that compression flag is not ON. We don't support compression yet. - // TODO (makdharma): add compression support + /* Check that compression flag is OFF. We don't support compression yet. */ GPR_ASSERT(stream_op->send_message->flags == 0); gpr_slice_buffer_add(&write_slice_buffer, slice); - GPR_ASSERT(write_slice_buffer.count == 1); // Empty request not handled yet + GPR_ASSERT(write_slice_buffer.count == + 1); /* Empty request not handled yet */ if (write_slice_buffer.count > 0) { int write_buffer_size; - create_grpc_frame(&write_slice_buffer, &stream_state->ws.write_buffer, &write_buffer_size); - CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_write (%p)", stream_state->ws.write_buffer); + create_grpc_frame(&write_slice_buffer, &stream_state->ws.write_buffer, + &write_buffer_size); + CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_write (%p)", + stream_state->ws.write_buffer); stream_state->state_callback_received[OP_SEND_MESSAGE] = false; cronet_bidirectional_stream_write(s->cbs, stream_state->ws.write_buffer, - write_buffer_size, false); // TODO: What if this is not the last write? + write_buffer_size, false); result = ACTION_TAKEN_WITH_CALLBACK; } stream_state->state_op_done[OP_SEND_MESSAGE] = true; oas->state.state_op_done[OP_SEND_MESSAGE] = true; - } else if (stream_op->recv_message && op_can_be_run(stream_op, stream_state, &oas->state, OP_RECV_MESSAGE)) { + } else if (stream_op->recv_message && + op_can_be_run(stream_op, stream_state, &oas->state, + OP_RECV_MESSAGE)) { CRONET_LOG(GPR_DEBUG, "running: %p OP_RECV_MESSAGE", oas); if (stream_state->state_op_done[OP_CANCEL_ERROR]) { - grpc_exec_ctx_sched(&s->exec_ctx, stream_op->recv_message_ready, GRPC_ERROR_CANCELLED, NULL); + grpc_exec_ctx_sched(&s->exec_ctx, stream_op->recv_message_ready, + GRPC_ERROR_CANCELLED, NULL); stream_state->state_op_done[OP_RECV_MESSAGE] = true; } else if (stream_state->rs.length_field_received == false) { - if (stream_state->rs.received_bytes == GRPC_HEADER_SIZE_IN_BYTES && stream_state->rs.remaining_bytes == 0) { - // Start a read operation for data + if (stream_state->rs.received_bytes == GRPC_HEADER_SIZE_IN_BYTES && + stream_state->rs.remaining_bytes == 0) { + /* Start a read operation for data */ stream_state->rs.length_field_received = true; stream_state->rs.length_field = stream_state->rs.remaining_bytes = - parse_grpc_header((const uint8_t *)stream_state->rs.read_buffer); - CRONET_LOG(GPR_DEBUG, "length field = %d", stream_state->rs.length_field); + parse_grpc_header((const uint8_t *)stream_state->rs.read_buffer); + CRONET_LOG(GPR_DEBUG, "length field = %d", + stream_state->rs.length_field); if (stream_state->rs.length_field > 0) { - stream_state->rs.read_buffer = gpr_malloc(stream_state->rs.length_field); + stream_state->rs.read_buffer = + gpr_malloc(stream_state->rs.length_field); GPR_ASSERT(stream_state->rs.read_buffer); stream_state->rs.remaining_bytes = stream_state->rs.length_field; stream_state->rs.received_bytes = 0; CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_read"); - stream_state->state_op_done[OP_READ_REQ_MADE] = true; // If at least one read request has been made + stream_state->state_op_done[OP_READ_REQ_MADE] = + true; /* Indicates that at least one read request has been made */ cronet_bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer, - stream_state->rs.remaining_bytes); + stream_state->rs.remaining_bytes); result = ACTION_TAKEN_WITH_CALLBACK; } else { stream_state->rs.remaining_bytes = 0; CRONET_LOG(GPR_DEBUG, "read operation complete. Empty response."); gpr_slice_buffer_init(&stream_state->rs.read_slice_buffer); - grpc_slice_buffer_stream_init(&stream_state->rs.sbs, &stream_state->rs.read_slice_buffer, 0); - *((grpc_byte_buffer **)stream_op->recv_message) = (grpc_byte_buffer *)&stream_state->rs.sbs; - grpc_exec_ctx_sched(&s->exec_ctx, stream_op->recv_message_ready, GRPC_ERROR_NONE, NULL); + grpc_slice_buffer_stream_init(&stream_state->rs.sbs, + &stream_state->rs.read_slice_buffer, 0); + *((grpc_byte_buffer **)stream_op->recv_message) = + (grpc_byte_buffer *)&stream_state->rs.sbs; + grpc_exec_ctx_sched(&s->exec_ctx, stream_op->recv_message_ready, + GRPC_ERROR_NONE, NULL); stream_state->state_op_done[OP_RECV_MESSAGE] = true; - oas->state.state_op_done[OP_RECV_MESSAGE] = true; // Also set per op state. + oas->state.state_op_done[OP_RECV_MESSAGE] = true; result = ACTION_TAKEN_NO_CALLBACK; } } else if (stream_state->rs.remaining_bytes == 0) { - // Start a read operation for first 5 bytes (GRPC header) + /* Start a read operation for first 5 bytes (GRPC header) */ stream_state->rs.read_buffer = stream_state->rs.grpc_header_bytes; stream_state->rs.remaining_bytes = GRPC_HEADER_SIZE_IN_BYTES; stream_state->rs.received_bytes = 0; CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_read"); - stream_state->state_op_done[OP_READ_REQ_MADE] = true; // If at least one read request has been made + stream_state->state_op_done[OP_READ_REQ_MADE] = + true; /* Indicates that at least one read request has been made */ cronet_bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer, stream_state->rs.remaining_bytes); } result = ACTION_TAKEN_WITH_CALLBACK; } else if (stream_state->rs.remaining_bytes == 0) { CRONET_LOG(GPR_DEBUG, "read operation complete"); - gpr_slice read_data_slice = gpr_slice_malloc((uint32_t)stream_state->rs.length_field); + gpr_slice read_data_slice = + gpr_slice_malloc((uint32_t)stream_state->rs.length_field); uint8_t *dst_p = GPR_SLICE_START_PTR(read_data_slice); - memcpy(dst_p, stream_state->rs.read_buffer, (size_t)stream_state->rs.length_field); + memcpy(dst_p, stream_state->rs.read_buffer, + (size_t)stream_state->rs.length_field); gpr_slice_buffer_init(&stream_state->rs.read_slice_buffer); - gpr_slice_buffer_add(&stream_state->rs.read_slice_buffer, read_data_slice); - grpc_slice_buffer_stream_init(&stream_state->rs.sbs, &stream_state->rs.read_slice_buffer, 0); - *((grpc_byte_buffer **)stream_op->recv_message) = (grpc_byte_buffer *)&stream_state->rs.sbs; - grpc_exec_ctx_sched(&s->exec_ctx, stream_op->recv_message_ready, GRPC_ERROR_NONE, NULL); + gpr_slice_buffer_add(&stream_state->rs.read_slice_buffer, + read_data_slice); + grpc_slice_buffer_stream_init(&stream_state->rs.sbs, + &stream_state->rs.read_slice_buffer, 0); + *((grpc_byte_buffer **)stream_op->recv_message) = + (grpc_byte_buffer *)&stream_state->rs.sbs; + grpc_exec_ctx_sched(&s->exec_ctx, stream_op->recv_message_ready, + GRPC_ERROR_NONE, NULL); stream_state->state_op_done[OP_RECV_MESSAGE] = true; - oas->state.state_op_done[OP_RECV_MESSAGE] = true; // Also set per op state. - // Clear read state of the stream, so next read op (if it were to come) will work - stream_state->rs.received_bytes = stream_state->rs.remaining_bytes = stream_state->rs.length_field_received = 0; + oas->state.state_op_done[OP_RECV_MESSAGE] = true; + /* Clear read state of the stream, so next read op (if it were to come) + * will work */ + stream_state->rs.received_bytes = stream_state->rs.remaining_bytes = + stream_state->rs.length_field_received = 0; result = ACTION_TAKEN_NO_CALLBACK; } } else if (stream_op->recv_trailing_metadata && - op_can_be_run(stream_op, stream_state, &oas->state, OP_RECV_TRAILING_METADATA)) { + op_can_be_run(stream_op, stream_state, &oas->state, + OP_RECV_TRAILING_METADATA)) { CRONET_LOG(GPR_DEBUG, "running: %p OP_RECV_TRAILING_METADATA", oas); if (oas->s->state.rs.trailing_metadata_valid) { grpc_chttp2_incoming_metadata_buffer_publish( - &oas->s->state.rs.trailing_metadata, stream_op->recv_trailing_metadata); + &oas->s->state.rs.trailing_metadata, + stream_op->recv_trailing_metadata); stream_state->rs.trailing_metadata_valid = false; } stream_state->state_op_done[OP_RECV_TRAILING_METADATA] = true; result = ACTION_TAKEN_NO_CALLBACK; - } else if (stream_op->send_trailing_metadata && op_can_be_run(stream_op, stream_state, &oas->state, OP_SEND_TRAILING_METADATA)) { + } else if (stream_op->send_trailing_metadata && + op_can_be_run(stream_op, stream_state, &oas->state, + OP_SEND_TRAILING_METADATA)) { CRONET_LOG(GPR_DEBUG, "running: %p OP_SEND_TRAILING_METADATA", oas); CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_write (0)"); stream_state->state_callback_received[OP_SEND_MESSAGE] = false; cronet_bidirectional_stream_write(s->cbs, "", 0, true); stream_state->state_op_done[OP_SEND_TRAILING_METADATA] = true; result = ACTION_TAKEN_WITH_CALLBACK; - } else if (stream_op->cancel_error && op_can_be_run(stream_op, stream_state, &oas->state, OP_CANCEL_ERROR)) { + } else if (stream_op->cancel_error && + op_can_be_run(stream_op, stream_state, &oas->state, + OP_CANCEL_ERROR)) { CRONET_LOG(GPR_DEBUG, "running: %p OP_CANCEL_ERROR", oas); CRONET_LOG(GPR_DEBUG, "W: cronet_bidirectional_stream_cancel(%p)", s->cbs); - // Cancel might have come before creation of stream if (s->cbs) { cronet_bidirectional_stream_cancel(s->cbs); } stream_state->state_op_done[OP_CANCEL_ERROR] = true; result = ACTION_TAKEN_WITH_CALLBACK; - } else if (stream_op->on_complete && op_can_be_run(stream_op, stream_state, &oas->state, OP_ON_COMPLETE)) { - // All ops are complete. Call the on_complete callback + } else if (stream_op->on_complete && + op_can_be_run(stream_op, stream_state, &oas->state, + OP_ON_COMPLETE)) { + /* All actions in this stream_op are complete. Call the on_complete callback + */ CRONET_LOG(GPR_DEBUG, "running: %p OP_ON_COMPLETE", oas); - //CRONET_LOG(GPR_DEBUG, "calling on_complete"); - grpc_exec_ctx_sched(&s->exec_ctx, stream_op->on_complete, GRPC_ERROR_NONE, NULL); - // Instead of setting stream state, use the op state as on_complete is on per op basis + grpc_exec_ctx_sched(&s->exec_ctx, stream_op->on_complete, GRPC_ERROR_NONE, + NULL); oas->state.state_op_done[OP_ON_COMPLETE] = true; - oas->done = true; // Mark this op as completed - // reset any send or receive message state. + oas->done = true; + /* reset any send or receive message state. */ stream_state->state_callback_received[OP_SEND_MESSAGE] = false; stream_state->state_op_done[OP_SEND_MESSAGE] = false; result = ACTION_TAKEN_NO_CALLBACK; - // If this is the on_complete callback being called for a received message - make a note - if (stream_op->recv_message) stream_state->state_op_done[OP_RECV_MESSAGE_AND_ON_COMPLETE] = true; + /* If this is the on_complete callback being called for a received message - + make a note */ + if (stream_op->recv_message) + stream_state->state_op_done[OP_RECV_MESSAGE_AND_ON_COMPLETE] = true; } else { - //CRONET_LOG(GPR_DEBUG, "No op ready to run"); result = NO_ACTION_POSSIBLE; } return result; } -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + Functions used by upper layers to access transport functionality. +*/ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_stream *gs, grpc_stream_refcount *refcount, @@ -720,7 +837,8 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, memset(&s->state.rs, 0, sizeof(s->state.rs)); memset(&s->state.ws, 0, sizeof(s->state.ws)); memset(s->state.state_op_done, 0, sizeof(s->state.state_op_done)); - memset(s->state.state_callback_received, 0, sizeof(s->state.state_callback_received)); + memset(s->state.state_callback_received, 0, + sizeof(s->state.state_callback_received)); gpr_mu_init(&s->mu); s->exec_ctx = *exec_ctx; return 0; @@ -744,19 +862,16 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, } static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, - grpc_stream *gs, void *and_free_memory) { -} + grpc_stream *gs, void *and_free_memory) {} -static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { -} +static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) {} static char *get_peer(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { return NULL; } static void perform_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, - grpc_transport_op *op) { -} + grpc_transport_op *op) {} const grpc_transport_vtable grpc_cronet_vtable = {sizeof(stream_obj), "cronet_http", From 5450f05e0c789ea48ec90483a8520062b8d828c0 Mon Sep 17 00:00:00 2001 From: Nathaniel Manista Date: Thu, 11 Aug 2016 02:24:46 +0000 Subject: [PATCH 206/279] Migrate distrib, interop, and stress to GA API --- .../tests/interop/_insecure_interop_test.py | 14 +- .../tests/interop/_secure_interop_test.py | 24 +- .../grpcio_tests/tests/interop/client.py | 56 ++-- .../grpcio_tests/tests/interop/methods.py | 270 +++++++++--------- .../grpcio_tests/tests/interop/server.py | 12 +- .../grpcio_tests/tests/stress/client.py | 21 +- .../tests/stress/metrics_server.py | 2 +- test/distrib/python/distribtest.py | 4 +- 8 files changed, 200 insertions(+), 203 deletions(-) diff --git a/src/python/grpcio_tests/tests/interop/_insecure_interop_test.py b/src/python/grpcio_tests/tests/interop/_insecure_interop_test.py index c753d6faf05..936c895bd2e 100644 --- a/src/python/grpcio_tests/tests/interop/_insecure_interop_test.py +++ b/src/python/grpcio_tests/tests/interop/_insecure_interop_test.py @@ -29,9 +29,10 @@ """Insecure client-server interoperability as a unit test.""" +from concurrent import futures import unittest -from grpc.beta import implementations +import grpc from src.proto.grpc.testing import test_pb2 from tests.interop import _interop_test_case @@ -44,14 +45,13 @@ class InsecureInteropTest( unittest.TestCase): def setUp(self): - self.server = test_pb2.beta_create_TestService_server(methods.TestService()) + self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + test_pb2.add_TestServiceServicer_to_server( + methods.TestService(), self.server) port = self.server.add_insecure_port('[::]:0') self.server.start() - self.stub = test_pb2.beta_create_TestService_stub( - implementations.insecure_channel('localhost', port)) - - def tearDown(self): - self.server.stop(0) + self.stub = test_pb2.TestServiceStub( + grpc.insecure_channel('localhost:{}'.format(port))) if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/interop/_secure_interop_test.py b/src/python/grpcio_tests/tests/interop/_secure_interop_test.py index cb09f54a347..eaca553e1b8 100644 --- a/src/python/grpcio_tests/tests/interop/_secure_interop_test.py +++ b/src/python/grpcio_tests/tests/interop/_secure_interop_test.py @@ -29,17 +29,16 @@ """Secure client-server interoperability as a unit test.""" +from concurrent import futures import unittest -from grpc.beta import implementations +import grpc from src.proto.grpc.testing import test_pb2 from tests.interop import _interop_test_case from tests.interop import methods from tests.interop import resources -from tests.unit.beta import test_utilities - _SERVER_HOST_OVERRIDE = 'foo.test.google.fr' @@ -48,19 +47,18 @@ class SecureInteropTest( unittest.TestCase): def setUp(self): - self.server = test_pb2.beta_create_TestService_server(methods.TestService()) + self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + test_pb2.add_TestServiceServicer_to_server( + methods.TestService(), self.server) port = self.server.add_secure_port( - '[::]:0', implementations.ssl_server_credentials( + '[::]:0', grpc.ssl_server_credentials( [(resources.private_key(), resources.certificate_chain())])) self.server.start() - self.stub = test_pb2.beta_create_TestService_stub( - test_utilities.not_really_secure_channel( - 'localhost', port, implementations.ssl_channel_credentials( - resources.test_root_certificates()), - _SERVER_HOST_OVERRIDE)) - - def tearDown(self): - self.server.stop(0) + self.stub = test_pb2.TestServiceStub( + grpc.secure_channel( + 'localhost:{}'.format(port), + grpc.ssl_channel_credentials(resources.test_root_certificates()), + (('grpc.ssl_target_name_override', _SERVER_HOST_OVERRIDE,),))) if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/interop/client.py b/src/python/grpcio_tests/tests/interop/client.py index 8aa1ce30c1a..9d61d189759 100644 --- a/src/python/grpcio_tests/tests/interop/client.py +++ b/src/python/grpcio_tests/tests/interop/client.py @@ -32,14 +32,12 @@ import argparse from oauth2client import client as oauth2client_client +import grpc from grpc.beta import implementations from src.proto.grpc.testing import test_pb2 from tests.interop import methods from tests.interop import resources -from tests.unit.beta import test_utilities - -_ONE_DAY_IN_SECONDS = 60 * 60 * 24 def _args(): @@ -66,41 +64,49 @@ def _args(): return parser.parse_args() +def _application_default_credentials(): + return oauth2client_client.GoogleCredentials.get_application_default() + + def _stub(args): + target = '{}:{}'.format(args.server_host, args.server_port) if args.test_case == 'oauth2_auth_token': - creds = oauth2client_client.GoogleCredentials.get_application_default() - scoped_creds = creds.create_scoped([args.oauth_scope]) - access_token = scoped_creds.get_access_token().access_token - call_creds = implementations.access_token_call_credentials(access_token) + google_credentials = _application_default_credentials() + scoped_credentials = google_credentials.create_scoped([args.oauth_scope]) + access_token = scoped_credentials.get_access_token().access_token + call_credentials = grpc.access_token_call_credentials(access_token) elif args.test_case == 'compute_engine_creds': - creds = oauth2client_client.GoogleCredentials.get_application_default() - scoped_creds = creds.create_scoped([args.oauth_scope]) - call_creds = implementations.google_call_credentials(scoped_creds) + google_credentials = _application_default_credentials() + scoped_credentials = google_credentials.create_scoped([args.oauth_scope]) + # TODO(https://github.com/grpc/grpc/issues/6799): Eliminate this last + # remaining use of the Beta API. + call_credentials = implementations.google_call_credentials( + scoped_credentials) elif args.test_case == 'jwt_token_creds': - creds = oauth2client_client.GoogleCredentials.get_application_default() - call_creds = implementations.google_call_credentials(creds) + google_credentials = _application_default_credentials() + # TODO(https://github.com/grpc/grpc/issues/6799): Eliminate this last + # remaining use of the Beta API. + call_credentials = implementations.google_call_credentials( + google_credentials) else: - call_creds = None + call_credentials = None if args.use_tls: if args.use_test_ca: root_certificates = resources.test_root_certificates() else: root_certificates = None # will load default roots. - channel_creds = implementations.ssl_channel_credentials(root_certificates) - if call_creds is not None: - channel_creds = implementations.composite_channel_credentials( - channel_creds, call_creds) + channel_credentials = grpc.ssl_channel_credentials(root_certificates) + if call_credentials is not None: + channel_credentials = grpc.composite_channel_credentials( + channel_credentials, call_credentials) - channel = test_utilities.not_really_secure_channel( - args.server_host, args.server_port, channel_creds, - args.server_host_override) - stub = test_pb2.beta_create_TestService_stub(channel) + channel = grpc.secure_channel( + target, channel_credentials, + (('grpc.ssl_target_name_override', args.server_host_override,),)) else: - channel = implementations.insecure_channel( - args.server_host, args.server_port) - stub = test_pb2.beta_create_TestService_stub(channel) - return stub + channel = grpc.insecure_channel(target) + return test_pb2.TestServiceStub(channel) def _test_case_from_arg(test_case_arg): diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py index 97e6c9e27ef..7edd75c56c9 100644 --- a/src/python/grpcio_tests/tests/interop/methods.py +++ b/src/python/grpcio_tests/tests/interop/methods.py @@ -29,8 +29,6 @@ """Implementations of interoperability test methods.""" -from __future__ import print_function - import enum import json import os @@ -41,26 +39,21 @@ from oauth2client import client as oauth2client_client import grpc from grpc.beta import implementations -from grpc.beta import interfaces -from grpc.framework.common import cardinality -from grpc.framework.interfaces.face import face from src.proto.grpc.testing import empty_pb2 from src.proto.grpc.testing import messages_pb2 from src.proto.grpc.testing import test_pb2 -_TIMEOUT = 7 - -class TestService(test_pb2.BetaTestServiceServicer): +class TestService(test_pb2.TestServiceServicer): def EmptyCall(self, request, context): return empty_pb2.Empty() def UnaryCall(self, request, context): if request.HasField('response_status'): - context.code(request.response_status.code) - context.details(request.response_status.message) + context.set_code(request.response_status.code) + context.set_details(request.response_status.message) return messages_pb2.SimpleResponse( payload=messages_pb2.Payload( type=messages_pb2.COMPRESSABLE, @@ -68,8 +61,8 @@ class TestService(test_pb2.BetaTestServiceServicer): def StreamingOutputCall(self, request, context): if request.HasField('response_status'): - context.code(request.response_status.code) - context.details(request.response_status.message) + context.set_code(request.response_status.code) + context.set_details(request.response_status.message) for response_parameters in request.response_parameters: yield messages_pb2.StreamingOutputCallResponse( payload=messages_pb2.Payload( @@ -79,7 +72,7 @@ class TestService(test_pb2.BetaTestServiceServicer): def StreamingInputCall(self, request_iterator, context): aggregate_size = 0 for request in request_iterator: - if request.payload and request.payload.body: + if request.payload is not None and request.payload.body: aggregate_size += len(request.payload.body) return messages_pb2.StreamingInputCallResponse( aggregated_payload_size=aggregate_size) @@ -87,8 +80,8 @@ class TestService(test_pb2.BetaTestServiceServicer): def FullDuplexCall(self, request_iterator, context): for request in request_iterator: if request.HasField('response_status'): - context.code(request.response_status.code) - context.details(request.response_status.message) + context.set_code(request.response_status.code) + context.set_details(request.response_status.message) for response_parameters in request.response_parameters: yield messages_pb2.StreamingOutputCallResponse( payload=messages_pb2.Payload( @@ -101,83 +94,80 @@ class TestService(test_pb2.BetaTestServiceServicer): return self.FullDuplexCall(request_iterator, context) -def _large_unary_common_behavior(stub, fill_username, fill_oauth_scope, - protocol_options=None): - with stub: - request = messages_pb2.SimpleRequest( - response_type=messages_pb2.COMPRESSABLE, response_size=314159, - payload=messages_pb2.Payload(body=b'\x00' * 271828), - fill_username=fill_username, fill_oauth_scope=fill_oauth_scope) - response_future = stub.UnaryCall.future(request, _TIMEOUT, - protocol_options=protocol_options) - response = response_future.result() - if response.payload.type is not messages_pb2.COMPRESSABLE: - raise ValueError( - 'response payload type is "%s"!' % type(response.payload.type)) - if len(response.payload.body) != 314159: - raise ValueError( - 'response body of incorrect size %d!' % len(response.payload.body)) +def _large_unary_common_behavior( + stub, fill_username, fill_oauth_scope, call_credentials): + request = messages_pb2.SimpleRequest( + response_type=messages_pb2.COMPRESSABLE, response_size=314159, + payload=messages_pb2.Payload(body=b'\x00' * 271828), + fill_username=fill_username, fill_oauth_scope=fill_oauth_scope) + response_future = stub.UnaryCall.future( + request, credentials=call_credentials) + response = response_future.result() + if response.payload.type is not messages_pb2.COMPRESSABLE: + raise ValueError( + 'response payload type is "%s"!' % type(response.payload.type)) + elif len(response.payload.body) != 314159: + raise ValueError( + 'response body of incorrect size %d!' % len(response.payload.body)) + else: return response def _empty_unary(stub): - with stub: - response = stub.EmptyCall(empty_pb2.Empty(), _TIMEOUT) - if not isinstance(response, empty_pb2.Empty): - raise TypeError( - 'response is of type "%s", not empty_pb2.Empty!', type(response)) + response = stub.EmptyCall(empty_pb2.Empty()) + if not isinstance(response, empty_pb2.Empty): + raise TypeError( + 'response is of type "%s", not empty_pb2.Empty!', type(response)) def _large_unary(stub): - _large_unary_common_behavior(stub, False, False) + _large_unary_common_behavior(stub, False, False, None) def _client_streaming(stub): - with stub: - payload_body_sizes = (27182, 8, 1828, 45904) - payloads = ( - messages_pb2.Payload(body=b'\x00' * size) - for size in payload_body_sizes) - requests = ( - messages_pb2.StreamingInputCallRequest(payload=payload) - for payload in payloads) - response = stub.StreamingInputCall(requests, _TIMEOUT) - if response.aggregated_payload_size != 74922: - raise ValueError( - 'incorrect size %d!' % response.aggregated_payload_size) + payload_body_sizes = (27182, 8, 1828, 45904,) + payloads = ( + messages_pb2.Payload(body=b'\x00' * size) + for size in payload_body_sizes) + requests = ( + messages_pb2.StreamingInputCallRequest(payload=payload) + for payload in payloads) + response = stub.StreamingInputCall(requests) + if response.aggregated_payload_size != 74922: + raise ValueError( + 'incorrect size %d!' % response.aggregated_payload_size) def _server_streaming(stub): - sizes = (31415, 9, 2653, 58979) - - with stub: - request = messages_pb2.StreamingOutputCallRequest( - response_type=messages_pb2.COMPRESSABLE, - response_parameters=( - messages_pb2.ResponseParameters(size=sizes[0]), - messages_pb2.ResponseParameters(size=sizes[1]), - messages_pb2.ResponseParameters(size=sizes[2]), - messages_pb2.ResponseParameters(size=sizes[3]), - )) - response_iterator = stub.StreamingOutputCall(request, _TIMEOUT) - for index, response in enumerate(response_iterator): - if response.payload.type != messages_pb2.COMPRESSABLE: - raise ValueError( - 'response body of invalid type %s!' % response.payload.type) - if len(response.payload.body) != sizes[index]: - raise ValueError( - 'response body of invalid size %d!' % len(response.payload.body)) + sizes = (31415, 9, 2653, 58979,) + + request = messages_pb2.StreamingOutputCallRequest( + response_type=messages_pb2.COMPRESSABLE, + response_parameters=( + messages_pb2.ResponseParameters(size=sizes[0]), + messages_pb2.ResponseParameters(size=sizes[1]), + messages_pb2.ResponseParameters(size=sizes[2]), + messages_pb2.ResponseParameters(size=sizes[3]), + ) + ) + response_iterator = stub.StreamingOutputCall(request) + for index, response in enumerate(response_iterator): + if response.payload.type != messages_pb2.COMPRESSABLE: + raise ValueError( + 'response body of invalid type %s!' % response.payload.type) + elif len(response.payload.body) != sizes[index]: + raise ValueError( + 'response body of invalid size %d!' % len(response.payload.body)) def _cancel_after_begin(stub): - with stub: - sizes = (27182, 8, 1828, 45904) - payloads = [messages_pb2.Payload(body=b'\x00' * size) for size in sizes] - requests = [messages_pb2.StreamingInputCallRequest(payload=payload) - for payload in payloads] - responses = stub.StreamingInputCall.future(requests, _TIMEOUT) - responses.cancel() - if not responses.cancelled(): - raise ValueError('expected call to be cancelled') + sizes = (27182, 8, 1828, 45904,) + payloads = (messages_pb2.Payload(body=b'\x00' * size) for size in sizes) + requests = (messages_pb2.StreamingInputCallRequest(payload=payload) + for payload in payloads) + response_future = stub.StreamingInputCall.future(requests) + response_future.cancel() + if not response_future.cancelled(): + raise ValueError('expected call to be cancelled') class _Pipe(object): @@ -220,18 +210,17 @@ class _Pipe(object): def _ping_pong(stub): - request_response_sizes = (31415, 9, 2653, 58979) - request_payload_sizes = (27182, 8, 1828, 45904) + request_response_sizes = (31415, 9, 2653, 58979,) + request_payload_sizes = (27182, 8, 1828, 45904,) - with stub, _Pipe() as pipe: - response_iterator = stub.FullDuplexCall(pipe, _TIMEOUT) - print('Starting ping-pong with response iterator %s' % response_iterator) + with _Pipe() as pipe: + response_iterator = stub.FullDuplexCall(pipe) for response_size, payload_size in zip( request_response_sizes, request_payload_sizes): request = messages_pb2.StreamingOutputCallRequest( response_type=messages_pb2.COMPRESSABLE, - response_parameters=(messages_pb2.ResponseParameters( - size=response_size),), + response_parameters=( + messages_pb2.ResponseParameters(size=response_size),), payload=messages_pb2.Payload(body=b'\x00' * payload_size)) pipe.add(request) response = next(response_iterator) @@ -244,17 +233,17 @@ def _ping_pong(stub): def _cancel_after_first_response(stub): - request_response_sizes = (31415, 9, 2653, 58979) - request_payload_sizes = (27182, 8, 1828, 45904) - with stub, _Pipe() as pipe: - response_iterator = stub.FullDuplexCall(pipe, _TIMEOUT) + request_response_sizes = (31415, 9, 2653, 58979,) + request_payload_sizes = (27182, 8, 1828, 45904,) + with _Pipe() as pipe: + response_iterator = stub.FullDuplexCall(pipe) response_size = request_response_sizes[0] payload_size = request_payload_sizes[0] request = messages_pb2.StreamingOutputCallRequest( response_type=messages_pb2.COMPRESSABLE, - response_parameters=(messages_pb2.ResponseParameters( - size=response_size),), + response_parameters=( + messages_pb2.ResponseParameters(size=response_size),), payload=messages_pb2.Payload(body=b'\x00' * payload_size)) pipe.add(request) response = next(response_iterator) @@ -264,16 +253,17 @@ def _cancel_after_first_response(stub): try: next(response_iterator) - except Exception: - pass + except grpc.RpcError as rpc_error: + if rpc_error.code() is not grpc.StatusCode.CANCELLED: + raise else: raise ValueError('expected call to be cancelled') def _timeout_on_sleeping_server(stub): request_payload_size = 27182 - with stub, _Pipe() as pipe: - response_iterator = stub.FullDuplexCall(pipe, 0.001) + with _Pipe() as pipe: + response_iterator = stub.FullDuplexCall(pipe, timeout=0.001) request = messages_pb2.StreamingOutputCallRequest( response_type=messages_pb2.COMPRESSABLE, @@ -282,15 +272,16 @@ def _timeout_on_sleeping_server(stub): time.sleep(0.1) try: next(response_iterator) - except face.ExpirationError: - pass + except grpc.RpcError as rpc_error: + if rpc_error.code() is not grpc.StatusCode.DEADLINE_EXCEEDED: + raise else: raise ValueError('expected call to exceed deadline') def _empty_stream(stub): - with stub, _Pipe() as pipe: - response_iterator = stub.FullDuplexCall(pipe, _TIMEOUT) + with _Pipe() as pipe: + response_iterator = stub.FullDuplexCall(pipe) pipe.close() try: next(response_iterator) @@ -300,65 +291,64 @@ def _empty_stream(stub): def _status_code_and_message(stub): - with stub: - message = 'test status message' - code = 2 - status = grpc.StatusCode.UNKNOWN # code = 2 - request = messages_pb2.SimpleRequest( - response_type=messages_pb2.COMPRESSABLE, - response_size=1, - payload=messages_pb2.Payload(body=b'\x00'), - response_status=messages_pb2.EchoStatus(code=code, message=message) - ) - response_future = stub.UnaryCall.future(request, _TIMEOUT) - if response_future.code() != status: - raise ValueError( - 'expected code %s, got %s' % (status, response_future.code())) - if response_future.details() != message: - raise ValueError( - 'expected message %s, got %s' % (message, response_future.details())) - - request = messages_pb2.StreamingOutputCallRequest( - response_type=messages_pb2.COMPRESSABLE, - response_parameters=( - messages_pb2.ResponseParameters(size=1),), - response_status=messages_pb2.EchoStatus(code=code, message=message)) - response_iterator = stub.StreamingOutputCall(request, _TIMEOUT) - if response_future.code() != status: - raise ValueError( - 'expected code %s, got %s' % (status, response_iterator.code())) - if response_future.details() != message: - raise ValueError( - 'expected message %s, got %s' % (message, response_iterator.details())) + message = 'test status message' + code = 2 + status = grpc.StatusCode.UNKNOWN # code = 2 + request = messages_pb2.SimpleRequest( + response_type=messages_pb2.COMPRESSABLE, + response_size=1, + payload=messages_pb2.Payload(body=b'\x00'), + response_status=messages_pb2.EchoStatus(code=code, message=message) + ) + response_future = stub.UnaryCall.future(request) + if response_future.code() != status: + raise ValueError( + 'expected code %s, got %s' % (status, response_future.code())) + elif response_future.details() != message: + raise ValueError( + 'expected message %s, got %s' % (message, response_future.details())) + + request = messages_pb2.StreamingOutputCallRequest( + response_type=messages_pb2.COMPRESSABLE, + response_parameters=( + messages_pb2.ResponseParameters(size=1),), + response_status=messages_pb2.EchoStatus(code=code, message=message)) + response_iterator = stub.StreamingOutputCall(request) + if response_future.code() != status: + raise ValueError( + 'expected code %s, got %s' % (status, response_iterator.code())) + elif response_future.details() != message: + raise ValueError( + 'expected message %s, got %s' % (message, response_iterator.details())) def _compute_engine_creds(stub, args): - response = _large_unary_common_behavior(stub, True, True) + response = _large_unary_common_behavior(stub, True, True, None) if args.default_service_account != response.username: raise ValueError( - 'expected username %s, got %s' % (args.default_service_account, - response.username)) + 'expected username %s, got %s' % ( + args.default_service_account, response.username)) def _oauth2_auth_token(stub, args): json_key_filename = os.environ[ oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS] wanted_email = json.load(open(json_key_filename, 'rb'))['client_email'] - response = _large_unary_common_behavior(stub, True, True) + response = _large_unary_common_behavior(stub, True, True, None) if wanted_email != response.username: raise ValueError( 'expected username %s, got %s' % (wanted_email, response.username)) if args.oauth_scope.find(response.oauth_scope) == -1: raise ValueError( - 'expected to find oauth scope "%s" in received "%s"' % - (response.oauth_scope, args.oauth_scope)) + 'expected to find oauth scope "{}" in received "{}"'.format( + response.oauth_scope, args.oauth_scope)) def _jwt_token_creds(stub, args): json_key_filename = os.environ[ oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS] wanted_email = json.load(open(json_key_filename, 'rb'))['client_email'] - response = _large_unary_common_behavior(stub, True, False) + response = _large_unary_common_behavior(stub, True, False, None) if wanted_email != response.username: raise ValueError( 'expected username %s, got %s' % (wanted_email, response.username)) @@ -370,11 +360,11 @@ def _per_rpc_creds(stub, args): wanted_email = json.load(open(json_key_filename, 'rb'))['client_email'] credentials = oauth2client_client.GoogleCredentials.get_application_default() scoped_credentials = credentials.create_scoped([args.oauth_scope]) - call_creds = implementations.google_call_credentials(scoped_credentials) - options = interfaces.grpc_call_options(disable_compression=False, - credentials=call_creds) - response = _large_unary_common_behavior(stub, True, False, - protocol_options=options) + # TODO(https://github.com/grpc/grpc/issues/6799): Eliminate this last + # remaining use of the Beta API. + call_credentials = implementations.google_call_credentials( + scoped_credentials) + response = _large_unary_common_behavior(stub, True, False, call_credentials) if wanted_email != response.username: raise ValueError( 'expected username %s, got %s' % (wanted_email, response.username)) diff --git a/src/python/grpcio_tests/tests/interop/server.py b/src/python/grpcio_tests/tests/interop/server.py index ab2c3c708f4..1ae83bc57d0 100644 --- a/src/python/grpcio_tests/tests/interop/server.py +++ b/src/python/grpcio_tests/tests/interop/server.py @@ -30,10 +30,11 @@ """The Python implementation of the GRPC interoperability test server.""" import argparse +from concurrent import futures import logging import time -from grpc.beta import implementations +import grpc from src.proto.grpc.testing import test_pb2 from tests.interop import methods @@ -51,12 +52,13 @@ def serve(): default=False, type=resources.parse_bool) args = parser.parse_args() - server = test_pb2.beta_create_TestService_server(methods.TestService()) + server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + test_pb2.add_TestServiceServicer_to_server(methods.TestService(), server) if args.use_tls: private_key = resources.private_key() certificate_chain = resources.certificate_chain() - credentials = implementations.ssl_server_credentials( - [(private_key, certificate_chain)]) + credentials = grpc.ssl_server_credentials( + ((private_key, certificate_chain),)) server.add_secure_port('[::]:{}'.format(args.port), credentials) else: server.add_insecure_port('[::]:{}'.format(args.port)) @@ -68,7 +70,7 @@ def serve(): time.sleep(_ONE_DAY_IN_SECONDS) except BaseException as e: logging.info('Caught exception "%s"; stopping server...', e) - server.stop(0) + server.stop(None) logging.info('Server stopped; exiting.') if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/stress/client.py b/src/python/grpcio_tests/tests/stress/client.py index 0de2532cd88..975f33b4c16 100644 --- a/src/python/grpcio_tests/tests/stress/client.py +++ b/src/python/grpcio_tests/tests/stress/client.py @@ -30,9 +30,10 @@ """Entry point for running stress tests.""" import argparse +from concurrent import futures import threading -from grpc.beta import implementations +import grpc from six.moves import queue from src.proto.grpc.testing import metrics_pb2 from src.proto.grpc.testing import test_pb2 @@ -92,24 +93,24 @@ def _parse_weighted_test_cases(test_case_args): def run_test(args): test_cases = _parse_weighted_test_cases(args.test_cases) - test_servers = args.server_addresses.split(',') + test_server_targets = args.server_addresses.split(',') # Propagate any client exceptions with a queue exception_queue = queue.Queue() stop_event = threading.Event() hist = histogram.Histogram(1, 1) runners = [] - server = metrics_pb2.beta_create_MetricsService_server( - metrics_server.MetricsServer(hist)) + server = grpc.server(futures.ThreadPoolExecutor(max_workers=25)) + metrics_pb2.add_MetricsServiceServicer_to_server( + metrics_server.MetricsServer(hist), server) server.add_insecure_port('[::]:{}'.format(args.metrics_port)) server.start() - for test_server in test_servers: - host, port = test_server.split(':', 1) + for test_server_target in test_server_targets: for _ in xrange(args.num_channels_per_server): - channel = implementations.insecure_channel(host, int(port)) + channel = grpc.insecure_channel(test_server_target) for _ in xrange(args.num_stubs_per_channel): - stub = test_pb2.beta_create_TestService_stub(channel) + stub = test_pb2.TestServiceStub(channel) runner = test_runner.TestRunner(stub, test_cases, hist, exception_queue, stop_event) runners.append(runner) @@ -128,8 +129,8 @@ def run_test(args): stop_event.set() for runner in runners: runner.join() - runner = None - server.stop(0) + runner = None + server.stop(None) if __name__ == '__main__': run_test(_args()) diff --git a/src/python/grpcio_tests/tests/stress/metrics_server.py b/src/python/grpcio_tests/tests/stress/metrics_server.py index b994e4643e5..33dd1d6f2ad 100644 --- a/src/python/grpcio_tests/tests/stress/metrics_server.py +++ b/src/python/grpcio_tests/tests/stress/metrics_server.py @@ -36,7 +36,7 @@ from src.proto.grpc.testing import metrics_pb2 GAUGE_NAME = 'python_overall_qps' -class MetricsServer(metrics_pb2.BetaMetricsServiceServicer): +class MetricsServer(metrics_pb2.MetricsServiceServicer): def __init__(self, histogram): self._start_time = time.time() diff --git a/test/distrib/python/distribtest.py b/test/distrib/python/distribtest.py index dc206881409..0125ee6a567 100644 --- a/test/distrib/python/distribtest.py +++ b/test/distrib/python/distribtest.py @@ -27,10 +27,10 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from grpc.beta import implementations +import grpc # This code doesn't do much but makes sure the native extension is loaded # which is what we are testing here. -channel = implementations.insecure_channel('localhost', 1000) +channel = grpc.insecure_channel('localhost:1000') del channel print 'Success!' From a6624bb0b59b6019adefb9e29a23d0336222ce46 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sun, 7 Aug 2016 07:59:41 +0800 Subject: [PATCH 207/279] upgrade Google.Apis.Auth dependency to 0.15.0 --- src/csharp/Grpc.Auth/project.json | 4 ++-- templates/src/csharp/Grpc.Auth/project.json.template | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/csharp/Grpc.Auth/project.json b/src/csharp/Grpc.Auth/project.json index 6a1c9fc9900..ffa4e7cb454 100644 --- a/src/csharp/Grpc.Auth/project.json +++ b/src/csharp/Grpc.Auth/project.json @@ -23,13 +23,13 @@ }, "dependencies": { "Grpc.Core": "1.0.0-pre2", - "Google.Apis.Auth": "1.11.1" + "Google.Apis.Auth": "1.15.0" }, "frameworks": { "net45": { }, "netstandard1.5": { "imports": [ - "net45" + "portable-net45" ], "dependencies": { "Microsoft.NETCore.Portable.Compatibility": "1.0.1", diff --git a/templates/src/csharp/Grpc.Auth/project.json.template b/templates/src/csharp/Grpc.Auth/project.json.template index b3244e4d3c9..19d4b42cf06 100644 --- a/templates/src/csharp/Grpc.Auth/project.json.template +++ b/templates/src/csharp/Grpc.Auth/project.json.template @@ -25,13 +25,13 @@ }, "dependencies": { "Grpc.Core": "${settings.csharp_version}", - "Google.Apis.Auth": "1.11.1" + "Google.Apis.Auth": "1.15.0" }, "frameworks": { "net45": { }, "netstandard1.5": { "imports": [ - "net45" + "portable-net45" ], "dependencies": { "Microsoft.NETCore.Portable.Compatibility": "1.0.1", From 9490daf67fdf42e4308889eb6f486c88343aa6d7 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sun, 7 Aug 2016 21:10:25 +0800 Subject: [PATCH 208/279] remove Google.Apis.Auth related CoreCLR todos --- .../Grpc.IntegrationTesting/InteropClient.cs | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs index ec407d3fcf4..2747c0e5b76 100644 --- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs +++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs @@ -145,26 +145,16 @@ namespace Grpc.IntegrationTesting if (options.TestCase == "jwt_token_creds") { -#if !NETCOREAPP1_0 var googleCredential = await GoogleCredential.GetApplicationDefaultAsync(); Assert.IsTrue(googleCredential.IsCreateScopedRequired); credentials = ChannelCredentials.Create(credentials, googleCredential.ToCallCredentials()); -#else - // TODO(jtattermusch): implement this - throw new NotImplementedException("Not supported on CoreCLR yet"); -#endif } if (options.TestCase == "compute_engine_creds") { -#if !NETCOREAPP1_0 var googleCredential = await GoogleCredential.GetApplicationDefaultAsync(); Assert.IsFalse(googleCredential.IsCreateScopedRequired); credentials = ChannelCredentials.Create(credentials, googleCredential.ToCallCredentials()); -#else - // TODO(jtattermusch): implement this - throw new NotImplementedException("Not supported on CoreCLR yet"); -#endif } return credentials; } @@ -395,7 +385,6 @@ namespace Grpc.IntegrationTesting public static async Task RunOAuth2AuthTokenAsync(TestService.TestServiceClient client, string oauthScope) { -#if !NETCOREAPP1_0 Console.WriteLine("running oauth2_auth_token"); ITokenAccess credential = (await GoogleCredential.GetApplicationDefaultAsync()).CreateScoped(new[] { oauthScope }); string oauth2Token = await credential.GetAccessTokenForRequestAsync(); @@ -413,15 +402,10 @@ namespace Grpc.IntegrationTesting Assert.True(oauthScope.Contains(response.OauthScope)); Assert.AreEqual(GetEmailFromServiceAccountFile(), response.Username); Console.WriteLine("Passed!"); -#else - // TODO(jtattermusch): implement this - throw new NotImplementedException("Not supported on CoreCLR yet"); -#endif } public static async Task RunPerRpcCredsAsync(TestService.TestServiceClient client, string oauthScope) { -#if !NETCOREAPP1_0 Console.WriteLine("running per_rpc_creds"); ITokenAccess googleCredential = await GoogleCredential.GetApplicationDefaultAsync(); @@ -435,10 +419,6 @@ namespace Grpc.IntegrationTesting Assert.AreEqual(GetEmailFromServiceAccountFile(), response.Username); Console.WriteLine("Passed!"); -#else - // TODO(jtattermusch): implement this - throw new NotImplementedException("Not supported on CoreCLR yet"); -#endif } public static async Task RunCancelAfterBeginAsync(TestService.TestServiceClient client) @@ -731,17 +711,12 @@ namespace Grpc.IntegrationTesting // extracts the client_email field from service account file used for auth test cases private static string GetEmailFromServiceAccountFile() { -#if !NETCOREAPP1_0 string keyFile = Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS"); Assert.IsNotNull(keyFile); var jobject = JObject.Parse(File.ReadAllText(keyFile)); string email = jobject.GetValue("client_email").Value(); Assert.IsTrue(email.Length > 0); // spec requires nonempty client email. return email; -#else - // TODO(jtattermusch): implement this - throw new NotImplementedException("Not supported on CoreCLR yet"); -#endif } private static Metadata CreateTestMetadata() From 07bd74edb88d605ff1d8dca040ce03302c30bc1a Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sun, 7 Aug 2016 21:45:44 +0800 Subject: [PATCH 209/279] update csproj project to Google.Apis.Auth 0.15.0 --- src/csharp/Grpc.Auth/Grpc.Auth.csproj | 31 ++++++++----------- src/csharp/Grpc.Auth/packages.config | 4 +-- .../Grpc.IntegrationTesting.Client.csproj | 31 ++++++++----------- .../packages.config | 4 +-- .../Grpc.IntegrationTesting.Server.csproj | 31 ++++++++----------- .../packages.config | 4 +-- .../Grpc.IntegrationTesting.csproj | 18 +++++------ .../Grpc.IntegrationTesting/packages.config | 4 +-- 8 files changed, 56 insertions(+), 71 deletions(-) diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj index 1fa14fc3dfb..7a6955311ac 100644 --- a/src/csharp/Grpc.Auth/Grpc.Auth.csproj +++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj @@ -39,30 +39,25 @@ ..\keys\Grpc.snk - - False + + + + + ..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll - - False - ..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.dll + + ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - - False - ..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.PlatformServices.dll + + ..\packages\Google.Apis.Core.1.15.0\lib\net45\Google.Apis.Core.dll - - False - ..\packages\Google.Apis.Core.1.11.1\lib\net45\Google.Apis.Core.dll + + ..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.dll - - False - ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + + ..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll - - - - diff --git a/src/csharp/Grpc.Auth/packages.config b/src/csharp/Grpc.Auth/packages.config index c20d9ceed6a..738d3e6f3b6 100644 --- a/src/csharp/Grpc.Auth/packages.config +++ b/src/csharp/Grpc.Auth/packages.config @@ -1,7 +1,7 @@  - - + + \ No newline at end of file diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj index 91fb3ce5bcf..6816b5c5a2d 100644 --- a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj +++ b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj @@ -39,30 +39,25 @@ ..\keys\Grpc.snk - - False + + + + + ..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll - - False - ..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.dll + + ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - - False - ..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.PlatformServices.dll + + ..\packages\Google.Apis.Core.1.15.0\lib\net45\Google.Apis.Core.dll - - False - ..\packages\Google.Apis.Core.1.11.1\lib\net45\Google.Apis.Core.dll + + ..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.dll - - False - ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + + ..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll - - - - diff --git a/src/csharp/Grpc.IntegrationTesting.Client/packages.config b/src/csharp/Grpc.IntegrationTesting.Client/packages.config index c20d9ceed6a..738d3e6f3b6 100644 --- a/src/csharp/Grpc.IntegrationTesting.Client/packages.config +++ b/src/csharp/Grpc.IntegrationTesting.Client/packages.config @@ -1,7 +1,7 @@  - - + + \ No newline at end of file diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj index f73d99dbd1a..987387ca259 100644 --- a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj +++ b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj @@ -39,30 +39,25 @@ ..\keys\Grpc.snk - - False + + + + + ..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll - - False - ..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.dll + + ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - - False - ..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.PlatformServices.dll + + ..\packages\Google.Apis.Core.1.15.0\lib\net45\Google.Apis.Core.dll - - False - ..\packages\Google.Apis.Core.1.11.1\lib\net45\Google.Apis.Core.dll + + ..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.dll - - False - ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + + ..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll - - - - diff --git a/src/csharp/Grpc.IntegrationTesting.Server/packages.config b/src/csharp/Grpc.IntegrationTesting.Server/packages.config index c20d9ceed6a..738d3e6f3b6 100644 --- a/src/csharp/Grpc.IntegrationTesting.Server/packages.config +++ b/src/csharp/Grpc.IntegrationTesting.Server/packages.config @@ -1,7 +1,7 @@  - - + + \ No newline at end of file diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj index 7512d2a5d11..df1d76765e2 100644 --- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj +++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj @@ -51,15 +51,6 @@ ..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll - - ..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.dll - - - ..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.PlatformServices.dll - - - ..\packages\Google.Apis.Core.1.11.1\lib\net45\Google.Apis.Core.dll - ..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll @@ -75,6 +66,15 @@ ..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll + + ..\packages\Google.Apis.Core.1.15.0\lib\net45\Google.Apis.Core.dll + + + ..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.dll + + + ..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll + diff --git a/src/csharp/Grpc.IntegrationTesting/packages.config b/src/csharp/Grpc.IntegrationTesting/packages.config index e6e64e65581..a78af9dc885 100644 --- a/src/csharp/Grpc.IntegrationTesting/packages.config +++ b/src/csharp/Grpc.IntegrationTesting/packages.config @@ -2,8 +2,8 @@ - - + + From 68689229e8d5cecee9d9e534c2c8aec87bf31b27 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 9 Aug 2016 06:52:39 +0800 Subject: [PATCH 210/279] update Grpc.Auth.nuspec --- src/csharp/Grpc.Auth/Grpc.Auth.nuspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.nuspec b/src/csharp/Grpc.Auth/Grpc.Auth.nuspec index 4baed3704c4..a1f5668e2e0 100644 --- a/src/csharp/Grpc.Auth/Grpc.Auth.nuspec +++ b/src/csharp/Grpc.Auth/Grpc.Auth.nuspec @@ -15,7 +15,7 @@ Copyright 2015, Google Inc. gRPC RPC Protocol HTTP/2 Auth OAuth2 - + From fab839e96774e61567f085d8f961897a1cc3e07b Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 10 Aug 2016 18:54:14 +0800 Subject: [PATCH 211/279] remove leftover app.config --- .../Grpc.IntegrationTesting.QpsWorker.csproj | 1 - .../Grpc.IntegrationTesting.QpsWorker/app.config | 15 --------------- 2 files changed, 16 deletions(-) delete mode 100644 src/csharp/Grpc.IntegrationTesting.QpsWorker/app.config diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj index dda26a68923..593bf0939db 100644 --- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj +++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj @@ -58,7 +58,6 @@ - \ No newline at end of file diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/app.config b/src/csharp/Grpc.IntegrationTesting.QpsWorker/app.config deleted file mode 100644 index e204447bb34..00000000000 --- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/app.config +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file From 3ed00635f91dad88788b99b2e06d9d7e647fb9d5 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Thu, 11 Aug 2016 08:46:39 -0700 Subject: [PATCH 212/279] Add optional resource parameters to census resource test --- test/core/census/resource_test.c | 47 +++++++++++++++++++------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/test/core/census/resource_test.c b/test/core/census/resource_test.c index e1556d7d7b0..cfe4f037fd3 100644 --- a/test/core/census/resource_test.c +++ b/test/core/census/resource_test.c @@ -95,15 +95,13 @@ static void test_define_single_resource(const char *file, const char *name, } // Try deleting various resources (both those that exist and those that don't). -static void test_delete_resource() { +static void test_delete_resource(char* minimal_good, char* full) { initialize_resources(); // Try deleting resource before any are defined. census_delete_resource(0); // Create and check a couple of resources. - int32_t rid1 = define_resource_from_file( - "test/core/census/data/resource_minimal_good.pb"); - int32_t rid2 = - define_resource_from_file("test/core/census/data/resource_full.pb"); + int32_t rid1 = define_resource_from_file(minimal_good); + int32_t rid2 = define_resource_from_file(full); GPR_ASSERT(rid1 >= 0 && rid2 >= 0 && rid1 != rid2); int32_t rid3 = census_resource_id("minimal_good"); int32_t rid4 = census_resource_id("full_resource"); @@ -117,8 +115,7 @@ static void test_delete_resource() { rid3 = census_resource_id("minimal_good"); GPR_ASSERT(rid3 < 0); // Check that re-adding works. - rid1 = define_resource_from_file( - "test/core/census/data/resource_minimal_good.pb"); + rid1 = define_resource_from_file(minimal_good); GPR_ASSERT(rid1 >= 0); rid3 = census_resource_id("minimal_good"); GPR_ASSERT(rid1 == rid3); @@ -136,22 +133,34 @@ static void test_base_resources() { } int main(int argc, char **argv) { + char *resource_empty_name_pb, *resource_full_pb, *resource_minimal_good_pb, + *resource_no_name_pb, *resource_no_numerator_pb, *resource_no_unit_pb; + if (argc >= 7) { + resource_empty_name_pb = argv[1]; + resource_full_pb = argv[2]; + resource_minimal_good_pb = argv[3]; + resource_no_name_pb = argv[4]; + resource_no_numerator_pb = argv[5]; + resource_no_unit_pb = argv[6]; + } else { + resource_empty_name_pb = "test/core/census/data/resource_empty_name.pb"; + resource_full_pb = "test/core/census/data/resource_full.pb"; + resource_minimal_good_pb = "test/core/census/data/resource_minimal_good.pb"; + resource_no_name_pb = "test/core/census/data/resource_no_name.pb"; + resource_no_numerator_pb = "test/core/census/data/resource_no_numerator.pb"; + resource_no_unit_pb = "test/core/census/data/resource_no_unit.pb"; + } grpc_test_init(argc, argv); test_enable_disable(); test_empty_definition(); - test_define_single_resource("test/core/census/data/resource_minimal_good.pb", - "minimal_good", true); - test_define_single_resource("test/core/census/data/resource_full.pb", - "full_resource", true); - test_define_single_resource("test/core/census/data/resource_no_name.pb", - "resource_no_name", false); - test_define_single_resource("test/core/census/data/resource_no_numerator.pb", + test_define_single_resource(resource_minimal_good_pb, "minimal_good", true); + test_define_single_resource(resource_full_pb, "full_resource", true); + test_define_single_resource(resource_no_name_pb, "resource_no_name", false); + test_define_single_resource(resource_no_numerator_pb, "resource_no_numerator", false); - test_define_single_resource("test/core/census/data/resource_no_unit.pb", - "resource_no_unit", false); - test_define_single_resource("test/core/census/data/resource_empty_name.pb", - "resource_empty_name", false); - test_delete_resource(); + test_define_single_resource(resource_no_unit_pb, "resource_no_unit", false); + test_define_single_resource(resource_empty_name_pb, "resource_empty_name", false); + test_delete_resource(resource_minimal_good_pb, resource_full_pb); test_base_resources(); return 0; } From a6402a9d43410057100d90b0498371790c6052e4 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Thu, 11 Aug 2016 10:09:37 -0700 Subject: [PATCH 213/279] Made strings constant --- test/core/census/resource_test.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/core/census/resource_test.c b/test/core/census/resource_test.c index cfe4f037fd3..8f5a4387d1a 100644 --- a/test/core/census/resource_test.c +++ b/test/core/census/resource_test.c @@ -95,7 +95,7 @@ static void test_define_single_resource(const char *file, const char *name, } // Try deleting various resources (both those that exist and those that don't). -static void test_delete_resource(char* minimal_good, char* full) { +static void test_delete_resource(const char *minimal_good, const char *full) { initialize_resources(); // Try deleting resource before any are defined. census_delete_resource(0); @@ -133,9 +133,9 @@ static void test_base_resources() { } int main(int argc, char **argv) { - char *resource_empty_name_pb, *resource_full_pb, *resource_minimal_good_pb, + const char *resource_empty_name_pb, *resource_full_pb, *resource_minimal_good_pb, *resource_no_name_pb, *resource_no_numerator_pb, *resource_no_unit_pb; - if (argc >= 7) { + if (argc == 7) { resource_empty_name_pb = argv[1]; resource_full_pb = argv[2]; resource_minimal_good_pb = argv[3]; @@ -143,6 +143,7 @@ int main(int argc, char **argv) { resource_no_numerator_pb = argv[5]; resource_no_unit_pb = argv[6]; } else { + GPR_ASSERT(argc == 1); resource_empty_name_pb = "test/core/census/data/resource_empty_name.pb"; resource_full_pb = "test/core/census/data/resource_full.pb"; resource_minimal_good_pb = "test/core/census/data/resource_minimal_good.pb"; From 530284269a31568fab04c200992857c7c52c6b56 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Thu, 11 Aug 2016 11:21:30 -0700 Subject: [PATCH 214/279] Clang format --- test/core/census/resource_test.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/test/core/census/resource_test.c b/test/core/census/resource_test.c index 8f5a4387d1a..f0e70396156 100644 --- a/test/core/census/resource_test.c +++ b/test/core/census/resource_test.c @@ -133,8 +133,9 @@ static void test_base_resources() { } int main(int argc, char **argv) { - const char *resource_empty_name_pb, *resource_full_pb, *resource_minimal_good_pb, - *resource_no_name_pb, *resource_no_numerator_pb, *resource_no_unit_pb; + const char *resource_empty_name_pb, *resource_full_pb, + *resource_minimal_good_pb, *resource_no_name_pb, + *resource_no_numerator_pb, *resource_no_unit_pb; if (argc == 7) { resource_empty_name_pb = argv[1]; resource_full_pb = argv[2]; @@ -157,10 +158,11 @@ int main(int argc, char **argv) { test_define_single_resource(resource_minimal_good_pb, "minimal_good", true); test_define_single_resource(resource_full_pb, "full_resource", true); test_define_single_resource(resource_no_name_pb, "resource_no_name", false); - test_define_single_resource(resource_no_numerator_pb, - "resource_no_numerator", false); + test_define_single_resource(resource_no_numerator_pb, "resource_no_numerator", + false); test_define_single_resource(resource_no_unit_pb, "resource_no_unit", false); - test_define_single_resource(resource_empty_name_pb, "resource_empty_name", false); + test_define_single_resource(resource_empty_name_pb, "resource_empty_name", + false); test_delete_resource(resource_minimal_good_pb, resource_full_pb); test_base_resources(); return 0; From a9bc030a3a9eb876c4ca00b40d68013ed91a8d66 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Thu, 11 Aug 2016 12:05:55 -0700 Subject: [PATCH 215/279] add mutex wrapper around sending and modifying of initial metadata --- src/ruby/lib/grpc/generic/active_call.rb | 37 +++-- src/ruby/spec/generic/active_call_spec.rb | 159 ++++++++-------------- 2 files changed, 80 insertions(+), 116 deletions(-) diff --git a/src/ruby/lib/grpc/generic/active_call.rb b/src/ruby/lib/grpc/generic/active_call.rb index d43a9e7a4b7..f9c41f0c0ed 100644 --- a/src/ruby/lib/grpc/generic/active_call.rb +++ b/src/ruby/lib/grpc/generic/active_call.rb @@ -113,11 +113,17 @@ module GRPC fail(ArgumentError, 'Already sent md') if started && metadata_to_send @metadata_to_send = metadata_to_send || {} unless started + @send_initial_md_mutex = Mutex.new end + # Sends the initial metadata that has yet to be sent. + # Fails if metadata has already been sent for this call. def send_initial_metadata - fail 'Already sent metadata' if @metadata_sent - start_call(@metadata_to_send) + @send_initial_md_mutex.synchronize do + fail('Already send initial metadata') if @metadata_sent + @metadata_tag = ActiveCall.client_invoke(@call, @metadata_to_send) + @metadata_sent = true + end end # output_metadata are provides access to hash that can be used to @@ -195,7 +201,7 @@ module GRPC # @param marshalled [false, true] indicates if the object is already # marshalled. def remote_send(req, marshalled = false) - start_call(@metadata_to_send) unless @metadata_sent + send_initial_metadata unless @metadata_sent GRPC.logger.debug("sending #{req}, marshalled? #{marshalled}") payload = marshalled ? req : @marshal.call(req) @call.run_batch(SEND_MESSAGE => payload) @@ -211,7 +217,7 @@ module GRPC # list, mulitple metadata for its key are sent def send_status(code = OK, details = '', assert_finished = false, metadata: {}) - start_call unless @metadata_sent + send_initial_metadata unless @metadata_sent ops = { SEND_STATUS_FROM_SERVER => Struct::Status.new(code, details, metadata) } @@ -312,7 +318,8 @@ module GRPC # a list, multiple metadata for its key are sent # @return [Object] the response received from the server def request_response(req, metadata: {}) - start_call(metadata) + merge_metadata_to_send(metadata) && + send_initial_metadata unless @metadata_sent remote_send(req) writes_done(false) response = remote_read @@ -336,7 +343,8 @@ module GRPC # a list, multiple metadata for its key are sent # @return [Object] the response received from the server def client_streamer(requests, metadata: {}) - start_call(metadata) + merge_metadata_to_send(metadata) && + send_initial_metadata unless @metadata_sent requests.each { |r| remote_send(r) } writes_done(false) response = remote_read @@ -362,7 +370,8 @@ module GRPC # a list, multiple metadata for its key are sent # @return [Enumerator|nil] a response Enumerator def server_streamer(req, metadata: {}) - start_call(metadata) + merge_metadata_to_send(metadata) && + send_initial_metadata unless @metadata_sent remote_send(req) writes_done(false) replies = enum_for(:each_remote_read_then_finish) @@ -401,7 +410,8 @@ module GRPC # a list, multiple metadata for its key are sent # @return [Enumerator, nil] a response Enumerator def bidi_streamer(requests, metadata: {}, &blk) - start_call(metadata) unless @metadata_sent + merge_metadata_to_send(metadata) && + send_initial_metadata unless @metadata_sent bd = BidiCall.new(@call, @marshal, @unmarshal, @@ -444,9 +454,14 @@ module GRPC @op_notifier.notify(self) end + # Add to the metadata that will be sent from the server. + # Fails if metadata has already been sent. + # Unused by client calls. def merge_metadata_to_send(new_metadata = {}) - fail('cant change metadata after already sent') if @metadata_sent - @metadata_to_send.merge!(new_metadata) + @send_initial_md_mutex.synchronize do + fail('cant change metadata after already sent') if @metadata_sent + @metadata_to_send.merge!(new_metadata) + end end private @@ -456,7 +471,7 @@ module GRPC # a list, multiple metadata for its key are sent def start_call(metadata = {}) return if @metadata_sent - @metadata_tag = ActiveCall.client_invoke(@call, metadata) + merge_metadata_to_send(metadata) && send_initial_metadata @metadata_sent = true end diff --git a/src/ruby/spec/generic/active_call_spec.rb b/src/ruby/spec/generic/active_call_spec.rb index 0c72be9a98a..79f739e8fa7 100644 --- a/src/ruby/spec/generic/active_call_spec.rb +++ b/src/ruby/spec/generic/active_call_spec.rb @@ -242,7 +242,12 @@ describe GRPC::ActiveCall do describe '#merge_metadata_to_send', merge_metadata_to_send: true do it 'adds to existing metadata when there is existing metadata to send' do call = make_test_call - starting_metadata = { k1: 'key1_val', k2: 'key2_val' } + starting_metadata = { + k1: 'key1_val', + k2: 'key2_val', + k3: 'key3_val' + } + @client_call = ActiveCall.new( call, @pass_through, @pass_through, @@ -253,13 +258,13 @@ describe GRPC::ActiveCall do expect(@client_call.metadata_to_send).to eq(starting_metadata) @client_call.merge_metadata_to_send( - k3: 'key3_val', + k3: 'key3_new_val', k4: 'key4_val') expected_md_to_send = { k1: 'key1_val', k2: 'key2_val', - k3: 'key3_val', + k3: 'key3_new_val', k4: 'key4_val' } expect(@client_call.metadata_to_send).to eq(expected_md_to_send) @@ -269,23 +274,6 @@ describe GRPC::ActiveCall do expect(@client_call.metadata_to_send).to eq(expected_md_to_send) end - it 'overrides existing metadata if adding metadata with an existing key' do - call = make_test_call - starting_metadata = { k1: 'key1_val', k2: 'key2_val' } - @client_call = ActiveCall.new( - call, - @pass_through, - @pass_through, - deadline, - started: false, - metadata_to_send: starting_metadata) - - expect(@client_call.metadata_to_send).to eq(starting_metadata) - @client_call.merge_metadata_to_send(k1: 'key1_new_val') - expect(@client_call.metadata_to_send).to eq(k1: 'key1_new_val', - k2: 'key2_val') - end - it 'fails when initial metadata has already been sent' do call = make_test_call @client_call = ActiveCall.new( @@ -530,121 +518,82 @@ describe GRPC::ActiveCall do end # Test sending of the initial metadata in #run_server_bidi - # from the server handler both implicitly and explicitly, - # when the server handler function has one argument and two arguments - describe '#run_server_bidi sanity tests', run_server_bidi: true do - it 'sends the initial metadata implicitly if not already sent' do - requests = ['first message', 'second message'] - server_to_client_metadata = { 'test_key' => 'test_val' } - server_status = OK + # from the server handler both implicitly and explicitly. + describe '#run_server_bidi metadata sending tests', run_server_bidi: true do + before(:each) do + @requests = ['first message', 'second message'] + @server_to_client_metadata = { 'test_key' => 'test_val' } + @server_status = OK - client_call = make_test_call - client_call.run_batch(CallOps::SEND_INITIAL_METADATA => {}) + @client_call = make_test_call + @client_call.run_batch(CallOps::SEND_INITIAL_METADATA => {}) recvd_rpc = @server.request_call recvd_call = recvd_rpc.call - server_call = ActiveCall.new(recvd_call, - @pass_through, - @pass_through, - deadline, - metadata_received: true, - started: false, - metadata_to_send: server_to_client_metadata) - - # Server handler that doesn't have access to a "call" - # It echoes the requests - fake_gen_each_reply_with_no_call_param = proc do |msgs| - msgs - end - - server_thread = Thread.new do - server_call.run_server_bidi( - fake_gen_each_reply_with_no_call_param) - server_call.send_status(server_status) - end + @server_call = ActiveCall.new( + recvd_call, + @pass_through, + @pass_through, + deadline, + metadata_received: true, + started: false, + metadata_to_send: @server_to_client_metadata) + end + after(:each) do # Send the requests and send a close so the server can send a status - requests.each do |message| - client_call.run_batch(CallOps::SEND_MESSAGE => message) + @requests.each do |message| + @client_call.run_batch(CallOps::SEND_MESSAGE => message) end - client_call.run_batch(CallOps::SEND_CLOSE_FROM_CLIENT => nil) + @client_call.run_batch(CallOps::SEND_CLOSE_FROM_CLIENT => nil) - server_thread.join + @server_thread.join # Expect that initial metadata was sent, # the requests were echoed, and a status was sent - batch_result = client_call.run_batch( + batch_result = @client_call.run_batch( CallOps::RECV_INITIAL_METADATA => nil) - expect(batch_result.metadata).to eq(server_to_client_metadata) + expect(batch_result.metadata).to eq(@server_to_client_metadata) - requests.each do |message| - batch_result = client_call.run_batch( + @requests.each do |message| + batch_result = @client_call.run_batch( CallOps::RECV_MESSAGE => nil) expect(batch_result.message).to eq(message) end - batch_result = client_call.run_batch( + batch_result = @client_call.run_batch( CallOps::RECV_STATUS_ON_CLIENT => nil) - expect(batch_result.status.code).to eq(server_status) + expect(batch_result.status.code).to eq(@server_status) end - it 'sends the metadata when sent explicitly and not already sent' do - requests = ['first message', 'second message'] - server_to_client_metadata = { 'test_key' => 'test_val' } - server_status = OK - - client_call = make_test_call - client_call.run_batch(CallOps::SEND_INITIAL_METADATA => {}) + it 'sends the initial metadata implicitly if not already sent' do + # Server handler that doesn't have access to a "call" + # It echoes the requests + fake_gen_each_reply_with_no_call_param = proc do |msgs| + msgs + end - recvd_rpc = @server.request_call - recvd_call = recvd_rpc.call - server_call = ActiveCall.new(recvd_call, - @pass_through, - @pass_through, - deadline, - metadata_received: true, - started: false) + @server_thread = Thread.new do + @server_call.run_server_bidi( + fake_gen_each_reply_with_no_call_param) + @server_call.send_status(@server_status) + end + end + it 'sends the metadata when sent explicitly and not already sent' do # Fake server handler that has access to a "call" object and - # uses it to explicitly update and sent the initial metadata + # uses it to explicitly update and send the initial metadata fake_gen_each_reply_with_call_param = proc do |msgs, call_param| - call_param.merge_metadata_to_send(server_to_client_metadata) + call_param.merge_metadata_to_send(@server_to_client_metadata) call_param.send_initial_metadata msgs end - server_thread = Thread.new do - server_call.run_server_bidi( + @server_thread = Thread.new do + @server_call.run_server_bidi( fake_gen_each_reply_with_call_param) - server_call.send_status(server_status) - end - - # Send requests and a close from the client so the server - # can send a status - requests.each do |message| - client_call.run_batch( - CallOps::SEND_MESSAGE => message) - end - client_call.run_batch( - CallOps::SEND_CLOSE_FROM_CLIENT => nil) - - server_thread.join - - # Verify that the correct metadata was sent, the requests - # were echoed, and the correct status was sent - batch_result = client_call.run_batch( - CallOps::RECV_INITIAL_METADATA => nil) - expect(batch_result.metadata).to eq(server_to_client_metadata) - - requests.each do |message| - batch_result = client_call.run_batch( - CallOps::RECV_MESSAGE => nil) - expect(batch_result.message).to eq(message) + @server_call.send_status(@server_status) end - - batch_result = client_call.run_batch( - CallOps::RECV_STATUS_ON_CLIENT => nil) - expect(batch_result.status.code).to eq(server_status) end end From 280885eaa5e48912fe623dcbad8ad398d8eb405d Mon Sep 17 00:00:00 2001 From: Makarand Dharmapurikar Date: Thu, 11 Aug 2016 14:16:36 -0700 Subject: [PATCH 216/279] WIP --- .../cronet/transport/cronet_transport.c | 177 +++++++++++++----- 1 file changed, 128 insertions(+), 49 deletions(-) diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c index 1d756039809..8f11ef73792 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.c +++ b/src/core/ext/transport/cronet/transport/cronet_transport.c @@ -50,16 +50,13 @@ #include "third_party/objective_c/Cronet/cronet_c_for_grpc.h" #define GRPC_HEADER_SIZE_IN_BYTES 5 -// maximum ops in a batch. There is not much thinking behind this limit, except -// that it seems to be enough for most use cases. -#define MAX_PENDING_OPS 100 #define CRONET_LOG(...) \ { \ if (grpc_cronet_trace) gpr_log(__VA_ARGS__); \ } -// TODO (makdharma): Hook up into the wider tracing mechanism +/* TODO (makdharma): Hook up into the wider tracing mechanism */ int grpc_cronet_trace = 1; enum OP_RESULT { @@ -68,7 +65,7 @@ enum OP_RESULT { NO_ACTION_POSSIBLE }; -// Used for printing debug +/* Used for printing debug */ const char *op_result_string[] = {"ACTION_TAKEN_WITH_CALLBACK", "ACTION_TAKEN_NO_CALLBACK", "NO_ACTION_POSSIBLE"}; @@ -129,7 +126,7 @@ static cronet_bidirectional_stream_callback cronet_callbacks = { on_failed, on_canceled}; -// Cronet transport object +/* Cronet transport object */ struct grpc_cronet_transport { grpc_transport base; /* must be first element in this structure */ cronet_engine *engine; @@ -146,6 +143,7 @@ struct read_state { int length_field; char grpc_header_bytes[GRPC_HEADER_SIZE_IN_BYTES]; char *payload_field; + bool read_stream_closed; /* vars for holding data destined for the application */ struct grpc_slice_buffer_stream sbs; @@ -177,14 +175,13 @@ struct op_and_state { grpc_transport_stream_op op; struct op_state state; bool done; - struct stream_obj *s; /* Pointer back to the stream object */ + struct stream_obj *s; /* Pointer back to the stream object */ + struct op_and_state *next; /* next op_and_state in the linked list */ }; struct op_storage { - struct op_and_state pending_ops[MAX_PENDING_OPS]; - int wrptr; - int rdptr; int num_pending_ops; + struct op_and_state *head; }; struct stream_obj { @@ -217,20 +214,52 @@ static enum OP_RESULT execute_stream_op(struct op_and_state *oas); static void add_to_storage(struct stream_obj *s, grpc_transport_stream_op *op) { gpr_mu_lock(&s->mu); struct op_storage *storage = &s->storage; - GPR_ASSERT(storage->num_pending_ops < MAX_PENDING_OPS); + /* add new op at the beginning of the linked list. The memory is freed + in remove_from_storage */ + struct op_and_state *new_op = gpr_malloc(sizeof(struct op_and_state)); + memcpy(&new_op->op, op, sizeof(grpc_transport_stream_op)); + memset(&new_op->state, 0, sizeof(new_op->state)); + new_op->s = s; + new_op->done = false; + new_op->next = storage->head; + storage->head = new_op; storage->num_pending_ops++; - CRONET_LOG(GPR_DEBUG, "adding new op @wrptr=%d. %d in the queue.", - storage->wrptr, storage->num_pending_ops); - memcpy(&storage->pending_ops[storage->wrptr].op, op, - sizeof(grpc_transport_stream_op)); - memset(&storage->pending_ops[storage->wrptr].state, 0, - sizeof(storage->pending_ops[storage->wrptr].state)); - storage->pending_ops[storage->wrptr].done = false; - storage->pending_ops[storage->wrptr].s = s; - storage->wrptr = (storage->wrptr + 1) % MAX_PENDING_OPS; + CRONET_LOG(GPR_DEBUG, "adding new op %p. %d in the queue.", new_op, + storage->num_pending_ops); gpr_mu_unlock(&s->mu); } +/* + Traverse the linked list and delete op and free memory +*/ +static void remove_from_storage(struct stream_obj *s, + struct op_and_state *oas) { + struct op_and_state *curr; + if (s->storage.head == NULL || oas == NULL) { + return; + } + if (s->storage.head == oas) { + s->storage.head = oas->next; + gpr_free(oas); + s->storage.num_pending_ops--; + CRONET_LOG(GPR_DEBUG, "Freed %p. Now %d in the queue", oas, + s->storage.num_pending_ops); + } else { + for (curr = s->storage.head; curr != NULL; curr = curr->next) { + if (curr->next == oas) { + curr->next = oas->next; + s->storage.num_pending_ops--; + CRONET_LOG(GPR_DEBUG, "Freed %p. Now %d in the queue", oas, + s->storage.num_pending_ops); + gpr_free(oas); + break; + } else if (curr->next == NULL) { + CRONET_LOG(GPR_ERROR, "Reached end of LL and did not find op to free"); + } + } + } +} + /* Cycle through ops and try to take next action. Break when either an action with callback is taken, or no action is possible. @@ -239,18 +268,21 @@ static void add_to_storage(struct stream_obj *s, grpc_transport_stream_op *op) { */ static void execute_from_storage(stream_obj *s) { gpr_mu_lock(&s->mu); - for (int i = 0; i < s->storage.wrptr;) { - CRONET_LOG(GPR_DEBUG, "calling execute_stream_op[%d]. done = %d", i, - s->storage.pending_ops[i].done); - if (s->storage.pending_ops[i].done) { - i++; - continue; + for (struct op_and_state *curr = s->storage.head; curr != NULL;) { + CRONET_LOG(GPR_DEBUG, "calling op at %p. done = %d", curr, curr->done); + GPR_ASSERT(curr->done == 0); + enum OP_RESULT result = execute_stream_op(curr); + CRONET_LOG(GPR_DEBUG, "execute_stream_op[%p] returns %s", curr, + op_result_string[result]); + /* if this op is done, then remove it and free memory */ + if (curr->done) { + struct op_and_state *next = curr->next; + remove_from_storage(s, curr); + curr = next; } - enum OP_RESULT result = execute_stream_op(&s->storage.pending_ops[i]); - CRONET_LOG(GPR_DEBUG, "%s = execute_stream_op[%d]", - op_result_string[result], i); + /* continue processing the same op if ACTION_TAKEN_WITHOUT_CALLBACK */ if (result == NO_ACTION_POSSIBLE) { - i++; + curr = curr->next; } else if (result == ACTION_TAKEN_WITH_CALLBACK) { break; } @@ -268,6 +300,14 @@ static void on_failed(cronet_bidirectional_stream *stream, int net_error) { cronet_bidirectional_stream_destroy(s->cbs); s->state.state_callback_received[OP_FAILED] = true; s->cbs = NULL; + if (s->header_array.headers) { + gpr_free(s->header_array.headers); + s->header_array.headers = NULL; + } + if (s->state.ws.write_buffer) { + gpr_free(s->state.ws.write_buffer); + s->state.ws.write_buffer = NULL; + } execute_from_storage(s); } @@ -280,6 +320,14 @@ static void on_canceled(cronet_bidirectional_stream *stream) { cronet_bidirectional_stream_destroy(s->cbs); s->state.state_callback_received[OP_CANCELED] = true; s->cbs = NULL; + if (s->header_array.headers) { + gpr_free(s->header_array.headers); + s->header_array.headers = NULL; + } + if (s->state.ws.write_buffer) { + gpr_free(s->state.ws.write_buffer); + s->state.ws.write_buffer = NULL; + } execute_from_storage(s); } @@ -306,6 +354,7 @@ static void on_request_headers_sent(cronet_bidirectional_stream *stream) { /* Free the memory allocated for headers */ if (s->header_array.headers) { gpr_free(s->header_array.headers); + s->header_array.headers = NULL; } execute_from_storage(s); } @@ -358,6 +407,7 @@ static void on_read_completed(cronet_bidirectional_stream *stream, char *data, stream_obj *s = (stream_obj *)stream->annotation; CRONET_LOG(GPR_DEBUG, "R: on_read_completed(%p, %p, %d)", stream, data, count); + s->state.state_callback_received[OP_RECV_MESSAGE] = true; if (count > 0) { s->state.rs.received_bytes += count; s->state.rs.remaining_bytes -= count; @@ -370,7 +420,9 @@ static void on_read_completed(cronet_bidirectional_stream *stream, char *data, } else { execute_from_storage(s); } - s->state.state_callback_received[OP_RECV_MESSAGE] = true; + } else { + s->state.rs.read_stream_closed = true; + execute_from_storage(s); } } @@ -570,38 +622,51 @@ static bool op_can_be_run(grpc_transport_stream_op *curr_op, } else if (op_id == OP_ON_COMPLETE) { /* already executed (note we're checking op specific state, not stream state) */ - if (op_state->state_op_done[OP_ON_COMPLETE]) result = false; + if (op_state->state_op_done[OP_ON_COMPLETE]) { + CRONET_LOG(GPR_DEBUG, "Because"); + result = false; + } /* Check if every op that was asked for is done. */ else if (curr_op->send_initial_metadata && - !stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) + !stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) { + CRONET_LOG(GPR_DEBUG, "Because"); result = false; - else if (curr_op->send_message && - !stream_state->state_op_done[OP_SEND_MESSAGE]) + } else if (curr_op->send_message && + !op_state->state_op_done[OP_SEND_MESSAGE]) { + CRONET_LOG(GPR_DEBUG, "Because"); result = false; - else if (curr_op->send_message && - !stream_state->state_callback_received[OP_SEND_MESSAGE]) + } else if (curr_op->send_message && + !stream_state->state_callback_received[OP_SEND_MESSAGE]) { + CRONET_LOG(GPR_DEBUG, "Because"); result = false; - else if (curr_op->send_trailing_metadata && - !stream_state->state_op_done[OP_SEND_TRAILING_METADATA]) + } else if (curr_op->send_trailing_metadata && + !stream_state->state_op_done[OP_SEND_TRAILING_METADATA]) { + CRONET_LOG(GPR_DEBUG, "Because"); result = false; - else if (curr_op->recv_initial_metadata && - !stream_state->state_op_done[OP_RECV_INITIAL_METADATA]) + } else if (curr_op->recv_initial_metadata && + !stream_state->state_op_done[OP_RECV_INITIAL_METADATA]) { + CRONET_LOG(GPR_DEBUG, "Because"); result = false; - else if (curr_op->recv_message && - !stream_state->state_op_done[OP_RECV_MESSAGE]) + } else if (curr_op->recv_message && + !stream_state->state_op_done[OP_RECV_MESSAGE]) { + CRONET_LOG(GPR_DEBUG, "Because"); result = false; - else if (curr_op->recv_trailing_metadata) { + } else if (curr_op->recv_trailing_metadata) { /* We aren't done with trailing metadata yet */ - if (!stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) + if (!stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) { + CRONET_LOG(GPR_DEBUG, "Because"); result = false; + } /* We've asked for actual message in an earlier op, and it hasn't been delivered yet. */ else if (stream_state->state_op_done[OP_READ_REQ_MADE]) { /* If this op is not the one asking for read, (which means some earlier op has asked), and the read hasn't been delivered. */ if (!curr_op->recv_message && - !stream_state->state_op_done[OP_SUCCEEDED]) + !stream_state->state_callback_received[OP_SUCCEEDED]) { + CRONET_LOG(GPR_DEBUG, "Because"); result = false; + } } } /* We should see at least one on_write_completed for the trailers that we @@ -625,6 +690,7 @@ static enum OP_RESULT execute_stream_op(struct op_and_state *oas) { OP_SEND_INITIAL_METADATA)) { CRONET_LOG(GPR_DEBUG, "running: %p OP_SEND_INITIAL_METADATA", oas); /* This OP is the beginning. Reset various states */ + memset(&s->header_array, 0, sizeof(s->header_array)); memset(&stream_state->rs, 0, sizeof(stream_state->rs)); memset(&stream_state->ws, 0, sizeof(stream_state->ws)); memset(stream_state->state_op_done, 0, sizeof(stream_state->state_op_done)); @@ -637,6 +703,7 @@ static enum OP_RESULT execute_stream_op(struct op_and_state *oas) { s->cbs = cronet_bidirectional_stream_create(s->curr_ct.engine, s->curr_gs, &cronet_callbacks); char *url; + s->header_array.headers = NULL; convert_metadata_to_cronet_headers( stream_op->send_initial_metadata->list.head, s->curr_ct.host, &url, &s->header_array.headers, &s->header_array.count); @@ -696,6 +763,13 @@ static enum OP_RESULT execute_stream_op(struct op_and_state *oas) { grpc_exec_ctx_sched(&s->exec_ctx, stream_op->recv_message_ready, GRPC_ERROR_CANCELLED, NULL); stream_state->state_op_done[OP_RECV_MESSAGE] = true; + } else if (stream_state->rs.read_stream_closed == true) { + /* No more data will be received */ + CRONET_LOG(GPR_DEBUG, "read stream closed"); + grpc_exec_ctx_sched(&s->exec_ctx, stream_op->recv_message_ready, + GRPC_ERROR_NONE, NULL); + stream_state->state_op_done[OP_RECV_MESSAGE] = true; + oas->state.state_op_done[OP_RECV_MESSAGE] = true; } else if (stream_state->rs.length_field_received == false) { if (stream_state->rs.received_bytes == GRPC_HEADER_SIZE_IN_BYTES && stream_state->rs.remaining_bytes == 0) { @@ -808,9 +882,12 @@ static enum OP_RESULT execute_stream_op(struct op_and_state *oas) { NULL); oas->state.state_op_done[OP_ON_COMPLETE] = true; oas->done = true; - /* reset any send or receive message state. */ - stream_state->state_callback_received[OP_SEND_MESSAGE] = false; - stream_state->state_op_done[OP_SEND_MESSAGE] = false; + /* reset any send message state, only if this ON_COMPLETE is about a send. + */ + if (stream_op->send_message) { + stream_state->state_callback_received[OP_SEND_MESSAGE] = false; + stream_state->state_op_done[OP_SEND_MESSAGE] = false; + } result = ACTION_TAKEN_NO_CALLBACK; /* If this is the on_complete callback being called for a received message - make a note */ @@ -831,9 +908,11 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, const void *server_data) { stream_obj *s = (stream_obj *)gs; memset(&s->storage, 0, sizeof(s->storage)); + s->storage.head = NULL; memset(&s->state, 0, sizeof(s->state)); s->curr_op = NULL; s->cbs = NULL; + memset(&s->header_array, 0, sizeof(s->header_array)); memset(&s->state.rs, 0, sizeof(s->state.rs)); memset(&s->state.ws, 0, sizeof(s->state.ws)); memset(s->state.state_op_done, 0, sizeof(s->state.state_op_done)); From 17d5c071153b540ee502712a4b0521b911d148bf Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Thu, 11 Aug 2016 15:21:43 -0700 Subject: [PATCH 217/279] use sent flag only under mutex and dont fail in send_initial_metadata --- src/ruby/lib/grpc/generic/active_call.rb | 22 ++++++++-------------- src/ruby/lib/grpc/generic/bidi_call.rb | 3 +-- src/ruby/spec/generic/active_call_spec.rb | 4 ++-- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/ruby/lib/grpc/generic/active_call.rb b/src/ruby/lib/grpc/generic/active_call.rb index f9c41f0c0ed..23688dc9244 100644 --- a/src/ruby/lib/grpc/generic/active_call.rb +++ b/src/ruby/lib/grpc/generic/active_call.rb @@ -117,10 +117,10 @@ module GRPC end # Sends the initial metadata that has yet to be sent. - # Fails if metadata has already been sent for this call. + # Does nothing if metadata has already been sent for this call. def send_initial_metadata @send_initial_md_mutex.synchronize do - fail('Already send initial metadata') if @metadata_sent + return if @metadata_sent @metadata_tag = ActiveCall.client_invoke(@call, @metadata_to_send) @metadata_sent = true end @@ -201,7 +201,7 @@ module GRPC # @param marshalled [false, true] indicates if the object is already # marshalled. def remote_send(req, marshalled = false) - send_initial_metadata unless @metadata_sent + send_initial_metadata GRPC.logger.debug("sending #{req}, marshalled? #{marshalled}") payload = marshalled ? req : @marshal.call(req) @call.run_batch(SEND_MESSAGE => payload) @@ -217,7 +217,7 @@ module GRPC # list, mulitple metadata for its key are sent def send_status(code = OK, details = '', assert_finished = false, metadata: {}) - send_initial_metadata unless @metadata_sent + send_initial_metadata ops = { SEND_STATUS_FROM_SERVER => Struct::Status.new(code, details, metadata) } @@ -318,8 +318,7 @@ module GRPC # a list, multiple metadata for its key are sent # @return [Object] the response received from the server def request_response(req, metadata: {}) - merge_metadata_to_send(metadata) && - send_initial_metadata unless @metadata_sent + merge_metadata_to_send(metadata) && send_initial_metadata remote_send(req) writes_done(false) response = remote_read @@ -343,8 +342,7 @@ module GRPC # a list, multiple metadata for its key are sent # @return [Object] the response received from the server def client_streamer(requests, metadata: {}) - merge_metadata_to_send(metadata) && - send_initial_metadata unless @metadata_sent + merge_metadata_to_send(metadata) && send_initial_metadata requests.each { |r| remote_send(r) } writes_done(false) response = remote_read @@ -370,8 +368,7 @@ module GRPC # a list, multiple metadata for its key are sent # @return [Enumerator|nil] a response Enumerator def server_streamer(req, metadata: {}) - merge_metadata_to_send(metadata) && - send_initial_metadata unless @metadata_sent + merge_metadata_to_send(metadata) && send_initial_metadata remote_send(req) writes_done(false) replies = enum_for(:each_remote_read_then_finish) @@ -410,8 +407,7 @@ module GRPC # a list, multiple metadata for its key are sent # @return [Enumerator, nil] a response Enumerator def bidi_streamer(requests, metadata: {}, &blk) - merge_metadata_to_send(metadata) && - send_initial_metadata unless @metadata_sent + merge_metadata_to_send(metadata) && send_initial_metadata bd = BidiCall.new(@call, @marshal, @unmarshal, @@ -470,9 +466,7 @@ module GRPC # @param metadata [Hash] metadata to be sent to the server. If a value is # a list, multiple metadata for its key are sent def start_call(metadata = {}) - return if @metadata_sent merge_metadata_to_send(metadata) && send_initial_metadata - @metadata_sent = true end def self.view_class(*visible_methods) diff --git a/src/ruby/lib/grpc/generic/bidi_call.rb b/src/ruby/lib/grpc/generic/bidi_call.rb index 0b6ef4918c6..14905b721cc 100644 --- a/src/ruby/lib/grpc/generic/bidi_call.rb +++ b/src/ruby/lib/grpc/generic/bidi_call.rb @@ -172,8 +172,7 @@ module GRPC payload = @marshal.call(req) # Fails if status already received begin - @req_view.send_initial_metadata unless - @req_view.nil? || @req_view.metadata_sent + @req_view.send_initial_metadata unless @req_view.nil? @call.run_batch(SEND_MESSAGE => payload) rescue GRPC::Core::CallError => e # This is almost definitely caused by a status arriving while still diff --git a/src/ruby/spec/generic/active_call_spec.rb b/src/ruby/spec/generic/active_call_spec.rb index 79f739e8fa7..48bc61e494f 100644 --- a/src/ruby/spec/generic/active_call_spec.rb +++ b/src/ruby/spec/generic/active_call_spec.rb @@ -221,7 +221,7 @@ describe GRPC::ActiveCall do @client_call.send_initial_metadata end - it 'explicit sending fails if metadata has already been sent' do + it 'explicit sending does nothing if metadata has already been sent' do call = make_test_call @client_call = ActiveCall.new(call, @@ -235,7 +235,7 @@ describe GRPC::ActiveCall do @client_call.send_initial_metadata end - expect { blk.call }.to raise_error + expect { blk.call }.to_not raise_error end end From 91d519532a79e7309e0d63a246c064398eec5288 Mon Sep 17 00:00:00 2001 From: Makarand Dharmapurikar Date: Thu, 11 Aug 2016 15:30:52 -0700 Subject: [PATCH 218/279] removed file from commit --- .../CoreCronetEnd2EndTests.m | 403 ------------------ 1 file changed, 403 deletions(-) delete mode 100644 src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m deleted file mode 100644 index d2181120e93..00000000000 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m +++ /dev/null @@ -1,403 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/* - * This test file is derived from fixture h2_ssl.c in core end2end test - * (test/core/end2end/fixture/h2_ssl.c). The structure of the fixture is - * preserved as much as possible - * - * This fixture creates a server full stack using chttp2 and a client - * full stack using Cronet. End-to-end tests are run against this - * configuration - * - */ - - -#import -#include "test/core/end2end/end2end_tests.h" - -#include -#include - -#include -#include -#include - -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/security/credentials/credentials.h" -#include "src/core/lib/support/env.h" -#include "src/core/lib/support/string.h" -#include "src/core/lib/support/tmpfile.h" -#include "test/core/end2end/data/ssl_test_data.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" - -#include -#import - -typedef struct fullstack_secure_fixture_data { - char *localaddr; -} fullstack_secure_fixture_data; - -static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( - grpc_channel_args *client_args, grpc_channel_args *server_args) { - grpc_end2end_test_fixture f; - int port = grpc_pick_unused_port_or_die(); - fullstack_secure_fixture_data *ffd = - gpr_malloc(sizeof(fullstack_secure_fixture_data)); - memset(&f, 0, sizeof(f)); - - gpr_join_host_port(&ffd->localaddr, "127.0.0.1", port); - - f.fixture_data = ffd; - f.cq = grpc_completion_queue_create(NULL); - - return f; -} - -static void process_auth_failure(void *state, grpc_auth_context *ctx, - const grpc_metadata *md, size_t md_count, - grpc_process_auth_metadata_done_cb cb, - void *user_data) { - GPR_ASSERT(state == NULL); - cb(user_data, NULL, 0, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, NULL); -} - -static void cronet_init_client_secure_fullstack( - grpc_end2end_test_fixture *f, grpc_channel_args *client_args, - cronet_engine *cronetEngine) { - fullstack_secure_fixture_data *ffd = f->fixture_data; - f->client = - grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr, client_args, NULL); - GPR_ASSERT(f->client != NULL); -} - -static void chttp2_init_server_secure_fullstack( - grpc_end2end_test_fixture *f, grpc_channel_args *server_args, - grpc_server_credentials *server_creds) { - fullstack_secure_fixture_data *ffd = f->fixture_data; - if (f->server) { - grpc_server_destroy(f->server); - } - f->server = grpc_server_create(server_args, NULL); - grpc_server_register_completion_queue(f->server, f->cq, NULL); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, - server_creds)); - grpc_server_credentials_release(server_creds); - grpc_server_start(f->server); -} - -static void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { - fullstack_secure_fixture_data *ffd = f->fixture_data; - gpr_free(ffd->localaddr); - gpr_free(ffd); -} - -static void cronet_init_client_simple_ssl_secure_fullstack( - grpc_end2end_test_fixture *f, grpc_channel_args *client_args) { - grpc_arg ssl_name_override = {GRPC_ARG_STRING, - GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, - {"foo.test.google.fr"}}; - - grpc_channel_args *new_client_args = - grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1); - static bool done = false; - // TODO (makdharma): DO NOT CHECK IN THIS HACK!!! - if (!done) { - done = true; - [Cronet setHttp2Enabled:YES]; - NSURL *url = [[[NSFileManager defaultManager] - URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; - NSLog(@"Documents directory: %@", url); - [Cronet start]; - [Cronet startNetLogToFile: @"Documents/cronet_netlog.json" logBytes:YES]; - } - cronet_engine *cronetEngine = [Cronet getGlobalEngine]; - - cronet_init_client_secure_fullstack(f, new_client_args, cronetEngine); - grpc_channel_args_destroy(new_client_args); -} - -static int fail_server_auth_check(grpc_channel_args *server_args) { - size_t i; - if (server_args == NULL) return 0; - for (i = 0; i < server_args->num_args; i++) { - if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) == - 0) { - return 1; - } - } - return 0; -} - -static void chttp2_init_server_simple_ssl_secure_fullstack( - grpc_end2end_test_fixture *f, grpc_channel_args *server_args) { - grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key, - test_server1_cert}; - grpc_server_credentials *ssl_creds = - grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL); - if (fail_server_auth_check(server_args)) { - grpc_auth_metadata_processor processor = {process_auth_failure, NULL, NULL}; - grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor); - } - chttp2_init_server_secure_fullstack(f, server_args, ssl_creds); -} - -/* All test configurations */ - -static grpc_end2end_test_config configs[] = { - {"chttp2/simple_ssl_fullstack", - FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | - FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, - chttp2_create_fixture_secure_fullstack, - cronet_init_client_simple_ssl_secure_fullstack, - chttp2_init_server_simple_ssl_secure_fullstack, - chttp2_tear_down_secure_fullstack}, -}; - - - -static char *roots_filename; - -@interface CoreCronetEnd2EndTests : XCTestCase - -@end - -@implementation CoreCronetEnd2EndTests - - -// The setUp() function is run before the test cases run and only run once -+ (void)setUp { - [super setUp]; - - FILE *roots_file; - size_t roots_size = strlen(test_root_cert); - - char *argv[] = {"CoreCronetEnd2EndTests"}; - grpc_test_init(1, argv); - grpc_end2end_tests_pre_init(); - - /* Set the SSL roots env var. */ - roots_file = gpr_tmpfile("chttp2_simple_ssl_fullstack_test", &roots_filename); - GPR_ASSERT(roots_filename != NULL); - GPR_ASSERT(roots_file != NULL); - GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); - fclose(roots_file); - gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); - - grpc_init(); - -} - -// The tearDown() function is run after all test cases finish running -+ (void)tearDown { - grpc_shutdown(); - - /* Cleanup. */ - remove(roots_filename); - gpr_free(roots_filename); - - [super tearDown]; -} - -- (void)testIndividualCase:(char*)test_case { - char *argv[] = {"h2_ssl", test_case}; - - for (int i = 0; i < sizeof(configs) / sizeof(*configs); i++) { - grpc_end2end_tests(sizeof(argv) / sizeof(argv[0]), argv, configs[i]); - } -} - -// TODO(mxyan): Use NSStringFromSelector(_cmd) to acquire test name from the -// test case method name, so that bodies of test cases can stay identical -- (void)testBadHostname { - [self testIndividualCase:"bad_hostname"]; -} - -- (void)testBinaryMetadata { - //[self testIndividualCase:"binary_metadata"]; -} - -- (void)testCallCreds { - [self testIndividualCase:"call_creds"]; -} - -- (void)testCancelAfterAccept { - [self testIndividualCase:"cancel_after_accept"]; -} - -- (void)testCancelAfterClientDone { - [self testIndividualCase:"cancel_after_client_done"]; -} - -- (void)testCancelAfterInvoke { - [self testIndividualCase:"cancel_after_invoke"]; -} - -- (void)testCancelBeforeInvoke { - [self testIndividualCase:"cancel_before_invoke"]; -} - -- (void)testCancelInAVacuum { - [self testIndividualCase:"cancel_in_a_vacuum"]; -} - -- (void)testCancelWithStatus { - [self testIndividualCase:"cancel_with_status"]; -} - -- (void)testCompressedPayload { - [self testIndividualCase:"compressed_payload"]; -} - -- (void)testConnectivity { - [self testIndividualCase:"connectivity"]; -} - -- (void)testDefaultHost { - [self testIndividualCase:"default_host"]; -} - -- (void)testDisappearingServer { - [self testIndividualCase:"disappearing_server"]; -} - -- (void)testEmptyBatch { - [self testIndividualCase:"empty_batch"]; -} - -- (void)testFilterCausesClose { - [self testIndividualCase:"filter_causes_close"]; -} - -- (void)testGracefulServerShutdown { - [self testIndividualCase:"graceful_server_shutdown"]; -} - -- (void)testHighInitialSeqno { - [self testIndividualCase:"high_initial_seqno"]; -} - -- (void)testHpackSize { - [self testIndividualCase:"hpack_size"]; -} - -- (void)testIdempotentRequest { - [self testIndividualCase:"idempotent_request"]; -} - -- (void)testInvokeLargeRequest { - [self testIndividualCase:"invoke_large_request"]; -} - -- (void)testLargeMetadata { - [self testIndividualCase:"large_metadata"]; -} - -- (void)testMaxConcurrentStreams { - [self testIndividualCase:"max_concurrent_streams"]; -} - -- (void)testMaxMessageLength { - [self testIndividualCase:"max_message_length"]; -} - -- (void)testNegativeDeadline { - [self testIndividualCase:"negative_deadline"]; -} - -- (void)testNetworkStatusChange { - [self testIndividualCase:"network_status_change"]; -} - -- (void)testNoOp { - [self testIndividualCase:"no_op"]; -} - -- (void)testPayload { - [self testIndividualCase:"payload"]; -} - -- (void)testPing { - [self testIndividualCase:"ping"]; -} - -- (void)testPingPongStreaming { - [self testIndividualCase:"ping_pong_streaming"]; -} - -- (void)testRegisteredCall { - [self testIndividualCase:"registered_call"]; -} - -- (void)testRequestWithFlags { - [self testIndividualCase:"request_with_flags"]; -} - -- (void)testRequestWithPayload { - [self testIndividualCase:"request_with_payload"]; -} - -- (void)testServerFinishesRequest { - [self testIndividualCase:"server_finishes_request"]; -} - -- (void)testShutdownFinishesCalls { - [self testIndividualCase:"shutdown_finishes_calls"]; -} - -- (void)testShutdownFinishesTags { - [self testIndividualCase:"shutdown_finishes_tags"]; -} - -- (void)testSimpleDelayedRequest { - [self testIndividualCase:"simple_delayed_request"]; -} - -- (void)testSimpleMetadata { - [self testIndividualCase:"simple_metadata"]; -} - -- (void)testSimpleRequest { - [self testIndividualCase:"simple_request"]; -} - -- (void)testStreamingErrorResponse { - [self testIndividualCase:"streaming_error_response"]; -} - -- (void)testTrailingMetadata { - [self testIndividualCase:"trailing_metadata"]; -} - -@end From 5804745aed0e6513706ad0ea0108ed6305003eba Mon Sep 17 00:00:00 2001 From: "David G. Quintas" Date: Thu, 11 Aug 2016 15:40:56 -0700 Subject: [PATCH 219/279] Merge pull request #7688 from dgquintas/cpp_readme fix c++ readme and tutorial --- examples/cpp/README.md | 31 ++-- examples/cpp/cpptutorial.md | 337 ++++++++++++++++++++++++------------ 2 files changed, 243 insertions(+), 125 deletions(-) diff --git a/examples/cpp/README.md b/examples/cpp/README.md index 3fa7ad4c784..783935cd53d 100644 --- a/examples/cpp/README.md +++ b/examples/cpp/README.md @@ -2,26 +2,14 @@ ## Installation -To install gRPC on your system, follow the instructions to build from source [here](../../INSTALL.md). This also installs the protocol buffer compiler `protoc` (if you don't have it already), and the C++ gRPC plugin for `protoc`. +To install gRPC on your system, follow the instructions to build from source +[here](../../INSTALL.md). This also installs the protocol buffer compiler +`protoc` (if you don't have it already), and the C++ gRPC plugin for `protoc`. ## Hello C++ gRPC! -Here's how to build and run the C++ implementation of the [Hello World](../protos/helloworld.proto) example used in [Getting started](..). - -The example code for this and our other examples lives in the `examples` -directory. Clone this repository to your local machine by running the -following command: - - -```sh -$ git clone -b $(curl -L http://grpc.io/release) https://github.com/grpc/grpc -``` - -Change your current directory to examples/cpp/helloworld - -```sh -$ cd examples/cpp/helloworld/ -``` +Here's how to build and run the C++ implementation of the [Hello +World](../protos/helloworld.proto) example used in [Getting started](..). ### Client and server implementations @@ -31,18 +19,25 @@ The server implementation is at [greeter_server.cc](helloworld/greeter_server.cc ### Try it! Build client and server: + ```sh $ make ``` + Run the server, which will listen on port 50051: + ```sh $ ./greeter_server ``` + Run the client (in a different terminal): + ```sh $ ./greeter_client ``` -If things go smoothly, you will see the "Greeter received: Hello world" in the client side output. + +If things go smoothly, you will see the "Greeter received: Hello world" in the +client side output. ## Tutorial diff --git a/examples/cpp/cpptutorial.md b/examples/cpp/cpptutorial.md index 80fef07192e..de7e4b26365 100644 --- a/examples/cpp/cpptutorial.md +++ b/examples/cpp/cpptutorial.md @@ -1,58 +1,77 @@ #gRPC Basics: C++ -This tutorial provides a basic C++ programmer's introduction to working with gRPC. By walking through this example you'll learn how to: +This tutorial provides a basic C++ programmer's introduction to working with +gRPC. By walking through this example you'll learn how to: -- Define a service in a .proto file. +- Define a service in a `.proto` file. - Generate server and client code using the protocol buffer compiler. - Use the C++ gRPC API to write a simple client and server for your service. -It assumes that you have read the [Getting started](..) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release: you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. - -This isn't a comprehensive guide to using gRPC in C++: more reference documentation is coming soon. +It assumes that you are familiar with +[protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). +Note that the example in this tutorial uses the proto3 version of the protocol +buffers language, which is currently in alpha release: you can find out more in +the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) +and see the [release notes](https://github.com/google/protobuf/releases) for the +new version in the protocol buffers Github repository. ## Why use gRPC? -Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. +Our example is a simple route mapping application that lets clients get +information about features on their route, create a summary of their route, and +exchange route information such as traffic updates with the server and other +clients. -With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. +With gRPC we can define our service once in a `.proto` file and implement clients +and servers in any of gRPC's supported languages, which in turn can be run in +environments ranging from servers inside Google to your own tablet - all the +complexity of communication between different languages and environments is +handled for you by gRPC. We also get all the advantages of working with protocol +buffers, including efficient serialization, a simple IDL, and easy interface +updating. ## Example code and setup -The example code for our tutorial is in [examples/cpp/route_guide](route_guide). To download the example, clone this repository by running the following command: -```shell -$ git clone -b $(curl -L http://grpc.io/release) https://github.com/grpc/grpc -``` - -Then change your current directory to `examples/cpp/route_guide`: -```shell -$ cd examples/cpp/route_guide -``` - -You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [gRPC in 3 minutes](README.md). - +The example code for our tutorial is in [examples/cpp/route_guide](route_guide). +You also should have the relevant tools installed to generate the server and +client interface code - if you don't already, follow the setup instructions in +[INSTALL.md](../../INSTALL.md). ## Defining the service -Our first step (as you'll know from [Getting started](..) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`examples/protos/route_guide.proto`](../protos/route_guide.proto). +Our first step is to define the gRPC *service* and the method *request* and +*response* types using +[protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). +You can see the complete `.proto` file in +[`examples/protos/route_guide.proto`](../protos/route_guide.proto). -To define a service, you specify a named `service` in your .proto file: +To define a service, you specify a named `service` in your `.proto` file: -``` +```protobuf service RouteGuide { ... } ``` -Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: +Then you define `rpc` methods inside your service definition, specifying their +request and response types. gRPC lets you define four kinds of service method, +all of which are used in the `RouteGuide` service: -- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. -``` +- A *simple RPC* where the client sends a request to the server using the stub + and waits for a response to come back, just like a normal function call. + +```protobuf // Obtains the feature at a given position. rpc GetFeature(Point) returns (Feature) {} ``` -- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. -``` +- A *server-side streaming RPC* where the client sends a request to the server + and gets a stream to read a sequence of messages back. The client reads from + the returned stream until there are no more messages. As you can see in our + example, you specify a server-side streaming method by placing the `stream` + keyword before the *response* type. + +```protobuf // Obtains the Features available within the given Rectangle. Results are // streamed rather than returned at once (e.g. in a response message with a // repeated field), as the rectangle may cover a large area and contain a @@ -60,22 +79,38 @@ Then you define `rpc` methods inside your service definition, specifying their r rpc ListFeatures(Rectangle) returns (stream Feature) {} ``` -- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a client-side streaming method by placing the `stream` keyword before the *request* type. -``` +- A *client-side streaming RPC* where the client writes a sequence of messages + and sends them to the server, again using a provided stream. Once the client + has finished writing the messages, it waits for the server to read them all + and return its response. You specify a client-side streaming method by placing + the `stream` keyword before the *request* type. + +```protobuf // Accepts a stream of Points on a route being traversed, returning a // RouteSummary when traversal is completed. rpc RecordRoute(stream Point) returns (RouteSummary) {} ``` -- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. -``` +- A *bidirectional streaming RPC* where both sides send a sequence of messages + using a read-write stream. The two streams operate independently, so clients + and servers can read and write in whatever order they like: for example, the + server could wait to receive all the client messages before writing its + responses, or it could alternately read a message then write a message, or + some other combination of reads and writes. The order of messages in each + stream is preserved. You specify this type of method by placing the `stream` + keyword before both the request and the response. + +```protobuf // Accepts a stream of RouteNotes sent while a route is being traversed, // while receiving other RouteNotes (e.g. from other users). rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} ``` -Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: -``` +Our `.proto` file also contains protocol buffer message type definitions for all +the request and response types used in our service methods - for example, here's +the `Point` message type: + +```protobuf // Points are represented as latitude-longitude pairs in the E7 representation // (degrees multiplied by 10**7 and rounded to the nearest integer). // Latitudes should be in the range +/- 90 degrees and longitude should be in @@ -86,12 +121,16 @@ message Point { } ``` - ## Generating client and server code -Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C++ plugin. +Next we need to generate the gRPC client and server interfaces from our `.proto` +service definition. We do this using the protocol buffer compiler `protoc` with +a special gRPC C++ plugin. -For simplicity, we've provided a [makefile](route_guide/Makefile) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've installed protoc and followed the gRPC code [installation instructions](../../INSTALL.md) first): +For simplicity, we've provided a [makefile](route_guide/Makefile) that runs +`protoc` for you with the appropriate plugin, input, and output (if you want to +run this yourself, make sure you've installed protoc and followed the gRPC code +[installation instructions](../../INSTALL.md) first): ```shell $ make route_guide.grpc.pb.cc route_guide.pb.cc @@ -107,39 +146,58 @@ $ protoc -I ../../protos --cpp_out=. ../../protos/route_guide.proto Running this command generates the following files in your current directory: - `route_guide.pb.h`, the header which declares your generated message classes - `route_guide.pb.cc`, which contains the implementation of your message classes -- `route_guide.grpc.pb.h`, the header which declares your generated service classes -- `route_guide.grpc.pb.cc`, which contains the implementation of your service classes +- `route_guide.grpc.pb.h`, the header which declares your generated service + classes +- `route_guide.grpc.pb.cc`, which contains the implementation of your service + classes These contain: -- All the protocol buffer code to populate, serialize, and retrieve our request and response message types +- All the protocol buffer code to populate, serialize, and retrieve our request + and response message types - A class called `RouteGuide` that contains - - a remote interface type (or *stub*) for clients to call with the methods defined in the `RouteGuide` service. - - two abstract interfaces for servers to implement, also with the methods defined in the `RouteGuide` service. + - a remote interface type (or *stub*) for clients to call with the methods + defined in the `RouteGuide` service. + - two abstract interfaces for servers to implement, also with the methods + defined in the `RouteGuide` service. ## Creating the server -First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). +First let's look at how we create a `RouteGuide` server. If you're only +interested in creating gRPC clients, you can skip this section and go straight +to [Creating the client](#client) (though you might find it interesting +anyway!). There are two parts to making our `RouteGuide` service do its job: -- Implementing the service interface generated from our service definition: doing the actual "work" of our service. -- Running a gRPC server to listen for requests from clients and return the service responses. +- Implementing the service interface generated from our service definition: + doing the actual "work" of our service. +- Running a gRPC server to listen for requests from clients and return the + service responses. -You can find our example `RouteGuide` server in [route_guide/route_guide_server.cc](route_guide/route_guide_server.cc). Let's take a closer look at how it works. +You can find our example `RouteGuide` server in +[route_guide/route_guide_server.cc](route_guide/route_guide_server.cc). Let's +take a closer look at how it works. ### Implementing RouteGuide -As you can see, our server has a `RouteGuideImpl` class that implements the generated `RouteGuide::Service` interface: +As you can see, our server has a `RouteGuideImpl` class that implements the +generated `RouteGuide::Service` interface: ```cpp class RouteGuideImpl final : public RouteGuide::Service { ... } ``` -In this case we're implementing the *synchronous* version of `RouteGuide`, which provides our default gRPC server behaviour. It's also possible to implement an asynchronous interface, `RouteGuide::AsyncService`, which allows you to further customize your server's threading behaviour, though we won't look at this in this tutorial. +In this case we're implementing the *synchronous* version of `RouteGuide`, which +provides our default gRPC server behaviour. It's also possible to implement an +asynchronous interface, `RouteGuide::AsyncService`, which allows you to further +customize your server's threading behaviour, though we won't look at this in +this tutorial. -`RouteGuideImpl` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. +`RouteGuideImpl` implements all our service methods. Let's look at the simplest +type first, `GetFeature`, which just gets a `Point` from the client and returns +the corresponding feature information from its database in a `Feature`. ```cpp Status GetFeature(ServerContext* context, const Point* point, @@ -150,34 +208,52 @@ In this case we're implementing the *synchronous* version of `RouteGuide`, which } ``` -The method is passed a context object for the RPC, the client's `Point` protocol buffer request, and a `Feature` protocol buffer to fill in with the response information. In the method we populate the `Feature` with the appropriate information, and then `return` with an `OK` status to tell gRPC that we've finished dealing with the RPC and that the `Feature` can be returned to the client. +The method is passed a context object for the RPC, the client's `Point` protocol +buffer request, and a `Feature` protocol buffer to fill in with the response +information. In the method we populate the `Feature` with the appropriate +information, and then `return` with an `OK` status to tell gRPC that we've +finished dealing with the RPC and that the `Feature` can be returned to the +client. -Now let's look at something a bit more complicated - a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. +Now let's look at something a bit more complicated - a streaming RPC. +`ListFeatures` is a server-side streaming RPC, so we need to send back multiple +`Feature`s to our client. ```cpp - Status ListFeatures(ServerContext* context, const Rectangle* rectangle, - ServerWriter* writer) override { - auto lo = rectangle->lo(); - auto hi = rectangle->hi(); - long left = std::min(lo.longitude(), hi.longitude()); - long right = std::max(lo.longitude(), hi.longitude()); - long top = std::max(lo.latitude(), hi.latitude()); - long bottom = std::min(lo.latitude(), hi.latitude()); - for (const Feature& f : feature_list_) { - if (f.location().longitude() >= left && - f.location().longitude() <= right && - f.location().latitude() >= bottom && - f.location().latitude() <= top) { - writer->Write(f); - } +Status ListFeatures(ServerContext* context, const Rectangle* rectangle, + ServerWriter* writer) override { + auto lo = rectangle->lo(); + auto hi = rectangle->hi(); + long left = std::min(lo.longitude(), hi.longitude()); + long right = std::max(lo.longitude(), hi.longitude()); + long top = std::max(lo.latitude(), hi.latitude()); + long bottom = std::min(lo.latitude(), hi.latitude()); + for (const Feature& f : feature_list_) { + if (f.location().longitude() >= left && + f.location().longitude() <= right && + f.location().latitude() >= bottom && + f.location().latitude() <= top) { + writer->Write(f); } - return Status::OK; } + return Status::OK; +} ``` -As you can see, instead of getting simple request and response objects in our method parameters, this time we get a request object (the `Rectangle` in which our client wants to find `Feature`s) and a special `ServerWriter` object. In the method, we populate as many `Feature` objects as we need to return, writing them to the `ServerWriter` using its `Write()` method. Finally, as in our simple RPC, we `return Status::OK` to tell gRPC that we've finished writing responses. +As you can see, instead of getting simple request and response objects in our +method parameters, this time we get a request object (the `Rectangle` in which +our client wants to find `Feature`s) and a special `ServerWriter` object. In the +method, we populate as many `Feature` objects as we need to return, writing them +to the `ServerWriter` using its `Write()` method. Finally, as in our simple RPC, +we `return Status::OK` to tell gRPC that we've finished writing responses. -If you look at the client-side streaming method `RecordRoute` you'll see it's quite similar, except this time we get a `ServerReader` instead of a request object and a single response. We use the `ServerReader`s `Read()` method to repeatedly read in our client's requests to a request object (in this case a `Point`) until there are no more messages: the server needs to check the return value of `Read()` after each call. If `true`, the stream is still good and it can continue reading; if `false` the message stream has ended. +If you look at the client-side streaming method `RecordRoute` you'll see it's +quite similar, except this time we get a `ServerReader` instead of a request +object and a single response. We use the `ServerReader`s `Read()` method to +repeatedly read in our client's requests to a request object (in this case a +`Point`) until there are no more messages: the server needs to check the return +value of `Read()` after each call. If `true`, the stream is still good and it +can continue reading; if `false` the message stream has ended. ```cpp while (stream->Read(&point)) { @@ -205,11 +281,18 @@ Finally, let's look at our bidirectional streaming RPC `RouteChat()`. } ``` -This time we get a `ServerReaderWriter` that can be used to read *and* write messages. The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. +This time we get a `ServerReaderWriter` that can be used to read *and* write +messages. The syntax for reading and writing here is exactly the same as for our +client-streaming and server-streaming methods. Although each side will always +get the other's messages in the order they were written, both the client and +server can read and write in any order — the streams operate completely +independently. ### Starting the server -Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: +Once we've implemented all our methods, we also need to start up a gRPC server +so that clients can actually use our service. The following snippet shows how we +do this for our `RouteGuide` service: ```cpp void RunServer(const std::string& db_path) { @@ -227,44 +310,55 @@ void RunServer(const std::string& db_path) { As you can see, we build and start our server using a `ServerBuilder`. To do this, we: 1. Create an instance of our service implementation class `RouteGuideImpl`. -2. Create an instance of the factory `ServerBuilder` class. -3. Specify the address and port we want to use to listen for client requests using the builder's `AddListeningPort()` method. -4. Register our service implementation with the builder. -5. Call `BuildAndStart()` on the builder to create and start an RPC server for our service. -5. Call `Wait()` on the server to do a blocking wait until process is killed or `Shutdown()` is called. +1. Create an instance of the factory `ServerBuilder` class. +1. Specify the address and port we want to use to listen for client requests + using the builder's `AddListeningPort()` method. +1. Register our service implementation with the builder. +1. Call `BuildAndStart()` on the builder to create and start an RPC server for + our service. +1. Call `Wait()` on the server to do a blocking wait until process is killed or + `Shutdown()` is called. ## Creating the client -In this section, we'll look at creating a C++ client for our `RouteGuide` service. You can see our complete example client code in [route_guide/route_guide_client.cc](route_guide/route_guide_client.cc). +In this section, we'll look at creating a C++ client for our `RouteGuide` +service. You can see our complete example client code in +[route_guide/route_guide_client.cc](route_guide/route_guide_client.cc). ### Creating a stub To call service methods, we first need to create a *stub*. -First we need to create a gRPC *channel* for our stub, specifying the server address and port we want to connect to without SSL: +First we need to create a gRPC *channel* for our stub, specifying the server +address and port we want to connect to without SSL: ```cpp grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()); ``` -Now we can use the channel to create our stub using the `NewStub` method provided in the `RouteGuide` class we generated from our .proto. +Now we can use the channel to create our stub using the `NewStub` method +provided in the `RouteGuide` class we generated from our `.proto`. ```cpp - public: - RouteGuideClient(std::shared_ptr channel, const std::string& db) - : stub_(RouteGuide::NewStub(channel)) { - ... - } +public: + RouteGuideClient(std::shared_ptr channel, const std::string& db) + : stub_(RouteGuide::NewStub(channel)) { + ... + } ``` ### Calling service methods -Now let's look at how we call our service methods. Note that in this tutorial we're calling the *blocking/synchronous* versions of each method: this means that the RPC call waits for the server to respond, and will either return a response or raise an exception. +Now let's look at how we call our service methods. Note that in this tutorial +we're calling the *blocking/synchronous* versions of each method: this means +that the RPC call waits for the server to respond, and will either return a +response or raise an exception. #### Simple RPC -Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local method. +Calling the simple RPC `GetFeature` is nearly as straightforward as calling a +local method. ```cpp Point point; @@ -281,33 +375,53 @@ Calling the simple RPC `GetFeature` is nearly as straightforward as calling a lo } ``` -As you can see, we create and populate a request protocol buffer object (in our case `Point`), and create a response protocol buffer object for the server to fill in. We also create a `ClientContext` object for our call - you can optionally set RPC configuration values on this object, such as deadlines, though for now we'll use the default settings. Note that you cannot reuse this object between calls. Finally, we call the method on the stub, passing it the context, request, and response. If the method returns `OK`, then we can read the response information from the server from our response object. +As you can see, we create and populate a request protocol buffer object (in our +case `Point`), and create a response protocol buffer object for the server to +fill in. We also create a `ClientContext` object for our call - you can +optionally set RPC configuration values on this object, such as deadlines, +though for now we'll use the default settings. Note that you cannot reuse this +object between calls. Finally, we call the method on the stub, passing it the +context, request, and response. If the method returns `OK`, then we can read the +response information from the server from our response object. ```cpp - std::cout << "Found feature called " << feature->name() << " at " - << feature->location().latitude()/kCoordFactor_ << ", " - << feature->location().longitude()/kCoordFactor_ << std::endl; +std::cout << "Found feature called " << feature->name() << " at " + << feature->location().latitude()/kCoordFactor_ << ", " + << feature->location().longitude()/kCoordFactor_ << std::endl; ``` #### Streaming RPCs -Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s: +Now let's look at our streaming methods. If you've already read [Creating the +server](#server) some of this may look very familiar - streaming RPCs are +implemented in a similar way on both sides. Here's where we call the server-side +streaming method `ListFeatures`, which returns a stream of geographical +`Feature`s: ```cpp - std::unique_ptr > reader( - stub_->ListFeatures(&context, rect)); - while (reader->Read(&feature)) { - std::cout << "Found feature called " - << feature.name() << " at " - << feature.location().latitude()/kCoordFactor_ << ", " - << feature.location().longitude()/kCoordFactor_ << std::endl; - } - Status status = reader->Finish(); +std::unique_ptr > reader( + stub_->ListFeatures(&context, rect)); +while (reader->Read(&feature)) { + std::cout << "Found feature called " + << feature.name() << " at " + << feature.location().latitude()/kCoordFactor_ << ", " + << feature.location().longitude()/kCoordFactor_ << std::endl; +} +Status status = reader->Finish(); ``` -Instead of passing the method a context, request, and response, we pass it a context and request and get a `ClientReader` object back. The client can use the `ClientReader` to read the server's responses. We use the `ClientReader`s `Read()` method to repeatedly read in the server's responses to a response protocol buffer object (in this case a `Feature`) until there are no more messages: the client needs to check the return value of `Read()` after each call. If `true`, the stream is still good and it can continue reading; if `false` the message stream has ended. Finally, we call `Finish()` on the stream to complete the call and get our RPC status. +Instead of passing the method a context, request, and response, we pass it a +context and request and get a `ClientReader` object back. The client can use the +`ClientReader` to read the server's responses. We use the `ClientReader`s +`Read()` method to repeatedly read in the server's responses to a response +protocol buffer object (in this case a `Feature`) until there are no more +messages: the client needs to check the return value of `Read()` after each +call. If `true`, the stream is still good and it can continue reading; if +`false` the message stream has ended. Finally, we call `Finish()` on the stream +to complete the call and get our RPC status. -The client-side streaming method `RecordRoute` is similar, except there we pass the method a context and response object and get back a `ClientWriter`. +The client-side streaming method `RecordRoute` is similar, except there we pass +the method a context and response object and get back a `ClientWriter`. ```cpp std::unique_ptr > writer( @@ -337,16 +451,26 @@ The client-side streaming method `RecordRoute` is similar, except there we pass } ``` -Once we've finished writing our client's requests to the stream using `Write()`, we need to call `WritesDone()` on the stream to let gRPC know that we've finished writing, then `Finish()` to complete the call and get our RPC status. If the status is `OK`, our response object that we initially passed to `RecordRoute()` will be populated with the server's response. +Once we've finished writing our client's requests to the stream using `Write()`, +we need to call `WritesDone()` on the stream to let gRPC know that we've +finished writing, then `Finish()` to complete the call and get our RPC status. +If the status is `OK`, our response object that we initially passed to +`RecordRoute()` will be populated with the server's response. -Finally, let's look at our bidirectional streaming RPC `RouteChat()`. In this case, we just pass a context to the method and get back a `ClientReaderWriter`, which we can use to both write and read messages. +Finally, let's look at our bidirectional streaming RPC `RouteChat()`. In this +case, we just pass a context to the method and get back a `ClientReaderWriter`, +which we can use to both write and read messages. ```cpp - std::shared_ptr > stream( - stub_->RouteChat(&context)); +std::shared_ptr > stream( + stub_->RouteChat(&context)); ``` -The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. +The syntax for reading and writing here is exactly the same as for our +client-streaming and server-streaming methods. Although each side will always +get the other's messages in the order they were written, both the client and +server can read and write in any order — the streams operate completely +independently. ## Try it out! @@ -362,4 +486,3 @@ Run the client (in a different terminal): ```shell $ ./route_guide_client ``` - From c61b1d3cd0e14c672741a8d3b27dedb421682abd Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Thu, 11 Aug 2016 16:15:41 -0700 Subject: [PATCH 220/279] s/makefile/Makefile --- examples/cpp/cpptutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/cpp/cpptutorial.md b/examples/cpp/cpptutorial.md index de7e4b26365..ae84aba9163 100644 --- a/examples/cpp/cpptutorial.md +++ b/examples/cpp/cpptutorial.md @@ -127,7 +127,7 @@ Next we need to generate the gRPC client and server interfaces from our `.proto` service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C++ plugin. -For simplicity, we've provided a [makefile](route_guide/Makefile) that runs +For simplicity, we've provided a [Makefile](route_guide/Makefile) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've installed protoc and followed the gRPC code [installation instructions](../../INSTALL.md) first): From d161f20a919763a2ee47cd8d4997fba2424fb219 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 11 Aug 2016 17:01:45 -0700 Subject: [PATCH 221/279] Don't get dependencies for Node grpc-health-check package build --- tools/run_tests/build_package_node.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/run_tests/build_package_node.sh b/tools/run_tests/build_package_node.sh index f20daeaea09..a5636cf87a7 100755 --- a/tools/run_tests/build_package_node.sh +++ b/tools/run_tests/build_package_node.sh @@ -50,7 +50,6 @@ cp grpc-*.tgz $artifacts/grpc.tgz mkdir -p bin cd $base/src/node/health_check -npm update npm pack cp grpc-health-check-*.tgz $artifacts/ From f2c074a73edb85ef71616d33f44c6fbda1159b25 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 12 Aug 2016 03:23:10 +0200 Subject: [PATCH 222/279] Updating build package C# scripts. --- src/csharp/build_packages.bat | 8 ++------ templates/src/csharp/build_packages.bat.template | 8 ++------ tools/run_tests/package_targets.py | 9 ++++++++- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/csharp/build_packages.bat b/src/csharp/build_packages.bat index 1d40ef9eb2d..9f544ff085d 100644 --- a/src/csharp/build_packages.bat +++ b/src/csharp/build_packages.bat @@ -31,10 +31,7 @@ @rem Current package versions set VERSION=1.0.0-pre2 -set PROTOBUF_VERSION=3.0.0-beta3 - -@rem Packages that depend on prerelease packages (like Google.Protobuf) need to have prerelease suffix as well. -set VERSION_WITH_BETA=%VERSION%-beta +set PROTOBUF_VERSION=3.0.0 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe @@ -58,7 +55,6 @@ xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=macos\artifacts\* pr @rem Fetch all dependencies %NUGET% restore ..\..\vsprojects\grpc_csharp_ext.sln || goto :error -%NUGET% restore Grpc.sln || goto :error setlocal @@ -73,7 +69,7 @@ endlocal %NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols -Version %VERSION% || goto :error %NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols -Version %VERSION% || goto :error -%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION_WITH_BETA% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error +%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error %NUGET% pack Grpc.nuspec -Version %VERSION% || goto :error %NUGET% pack Grpc.Tools.nuspec -Version %VERSION% || goto :error diff --git a/templates/src/csharp/build_packages.bat.template b/templates/src/csharp/build_packages.bat.template index ea2acb661ee..5cbd8e3746d 100644 --- a/templates/src/csharp/build_packages.bat.template +++ b/templates/src/csharp/build_packages.bat.template @@ -33,10 +33,7 @@ @rem Current package versions set VERSION=${settings.csharp_version} - set PROTOBUF_VERSION=3.0.0-beta3 - - @rem Packages that depend on prerelease packages (like Google.Protobuf) need to have prerelease suffix as well. - set VERSION_WITH_BETA=%VERSION%-beta + set PROTOBUF_VERSION=3.0.0 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe @@ -60,7 +57,6 @@ @rem Fetch all dependencies %%NUGET% restore ..\..\vsprojects\grpc_csharp_ext.sln || goto :error - %%NUGET% restore Grpc.sln || goto :error setlocal @@ -75,7 +71,7 @@ %%NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols -Version %VERSION% || goto :error %%NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols -Version %VERSION% || goto :error - %%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION_WITH_BETA% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error + %%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error %%NUGET% pack Grpc.nuspec -Version %VERSION% || goto :error %%NUGET% pack Grpc.Tools.nuspec -Version %VERSION% || goto :error diff --git a/tools/run_tests/package_targets.py b/tools/run_tests/package_targets.py index 39a11a243d6..5cafa6c296e 100644 --- a/tools/run_tests/package_targets.py +++ b/tools/run_tests/package_targets.py @@ -81,7 +81,14 @@ class CSharpPackage: self.labels += ['windows'] def pre_build_jobspecs(self): - return [] + if self.platform == 'windows': + return [create_jobspec('prebuild_%s' % self.name, + ['tools\\run_tests\\pre_build_csharp.bat'], + shell=True, + flake_retries=5, + timeout_retries=2)] + else: + return [] def build_jobspec(self): if self.use_coreclr: From 6ee23ee614f192ff97b8e0c306f0523375acc045 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 12 Aug 2016 09:46:07 +0200 Subject: [PATCH 223/279] There's no 'platform' in package_targets.py, only labels. --- tools/run_tests/package_targets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/package_targets.py b/tools/run_tests/package_targets.py index 5cafa6c296e..8217d7698af 100644 --- a/tools/run_tests/package_targets.py +++ b/tools/run_tests/package_targets.py @@ -81,7 +81,7 @@ class CSharpPackage: self.labels += ['windows'] def pre_build_jobspecs(self): - if self.platform == 'windows': + if 'windows' in self.labels: return [create_jobspec('prebuild_%s' % self.name, ['tools\\run_tests\\pre_build_csharp.bat'], shell=True, From 80c704bfa8be8a643e3cefefdacee4b8072f173c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 12 Aug 2016 20:41:57 +0800 Subject: [PATCH 224/279] update distribtest project to Google.Apis.Auth 0.15.0 --- test/distrib/csharp/DistribTest/App.config | 14 ----- .../csharp/DistribTest/DistribTest.csproj | 54 +++++++------------ .../csharp/DistribTest/packages.config | 8 +-- 3 files changed, 21 insertions(+), 55 deletions(-) delete mode 100644 test/distrib/csharp/DistribTest/App.config diff --git a/test/distrib/csharp/DistribTest/App.config b/test/distrib/csharp/DistribTest/App.config deleted file mode 100644 index 30d3e094721..00000000000 --- a/test/distrib/csharp/DistribTest/App.config +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/test/distrib/csharp/DistribTest/DistribTest.csproj b/test/distrib/csharp/DistribTest/DistribTest.csproj index 1acb34d1b2e..6ca03b2c800 100644 --- a/test/distrib/csharp/DistribTest/DistribTest.csproj +++ b/test/distrib/csharp/DistribTest/DistribTest.csproj @@ -1,5 +1,5 @@  - + Debug @@ -41,6 +41,8 @@ prompt MinimumRecommendedRules.ruleset true + 4 + false bin\x64\Release\ @@ -51,39 +53,15 @@ prompt MinimumRecommendedRules.ruleset true + 4 - - ..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll - - - ..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.dll - - - ..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.PlatformServices.dll - - - ..\packages\Google.Apis.Core.1.9.3\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll - ..\packages\Grpc.Auth.__GRPC_NUGET_VERSION__\lib\net45\Grpc.Auth.dll ..\packages\Grpc.Core.__GRPC_NUGET_VERSION__\lib\net45\Grpc.Core.dll - - ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll - - - ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll - - - ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll - - - False - ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - @@ -91,25 +69,33 @@ - - ..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll - - - ..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll - + + ..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll + + + ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + + + ..\packages\Google.Apis.Core.1.15.0\lib\net45\Google.Apis.Core.dll + + + ..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.dll + + + ..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll + - @@ -119,9 +105,7 @@ This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - -