aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/ruby_generator_helpers-inl.h4
-rw-r--r--src/core/ext/census/base_resources.c71
-rw-r--r--src/core/ext/census/base_resources.h39
-rw-r--r--src/core/ext/census/gen/census.pb.c55
-rw-r--r--src/core/ext/census/gen/census.pb.h135
-rw-r--r--src/core/ext/census/grpc_filter.c18
-rw-r--r--src/core/ext/census/initialize.c20
-rw-r--r--src/core/ext/census/placeholders.c45
-rw-r--r--src/core/ext/census/resource.c312
-rw-r--r--src/core/ext/census/resource.h63
-rw-r--r--src/core/ext/client_config/client_channel.c8
-rw-r--r--src/core/ext/client_config/lb_policy.h11
-rw-r--r--src/core/ext/client_config/subchannel.c25
-rw-r--r--src/core/ext/client_config/subchannel.h4
-rw-r--r--src/core/ext/client_config/subchannel_call_holder.c38
-rw-r--r--src/core/ext/lb_policy/grpclb/grpclb.c1039
-rw-r--r--src/core/ext/lb_policy/grpclb/grpclb.h44
-rw-r--r--src/core/ext/lb_policy/grpclb/load_balancer_api.c141
-rw-r--r--src/core/ext/lb_policy/grpclb/load_balancer_api.h36
-rw-r--r--src/core/ext/load_reporting/load_reporting.c60
-rw-r--r--src/core/ext/load_reporting/load_reporting.h61
-rw-r--r--src/core/ext/load_reporting/load_reporting_filter.c160
-rw-r--r--src/core/ext/load_reporting/load_reporting_filter.h1
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.c2
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_encoder.c6
-rw-r--r--src/core/ext/transport/chttp2/transport/parsing.c6
-rw-r--r--src/core/ext/transport/chttp2/transport/writing.c6
-rw-r--r--src/core/lib/channel/channel_stack.c29
-rw-r--r--src/core/lib/channel/channel_stack.h36
-rw-r--r--src/core/lib/channel/compress_filter.c10
-rw-r--r--src/core/lib/channel/connected_channel.c14
-rw-r--r--src/core/lib/channel/http_client_filter.c9
-rw-r--r--src/core/lib/channel/http_server_filter.c9
-rw-r--r--src/core/lib/iomgr/error.h2
-rw-r--r--src/core/lib/iomgr/tcp_posix.c2
-rw-r--r--src/core/lib/security/transport/client_auth_filter.c9
-rw-r--r--src/core/lib/security/transport/secure_endpoint.c4
-rw-r--r--src/core/lib/security/transport/server_auth_filter.c10
-rw-r--r--src/core/lib/surface/call.c76
-rw-r--r--src/core/lib/surface/lame_client.c9
-rw-r--r--src/core/lib/surface/server.c9
-rw-r--r--src/core/lib/transport/static_metadata.c33
-rw-r--r--src/core/lib/transport/static_metadata.h189
-rw-r--r--src/core/lib/transport/timeout_encoding.c (renamed from src/core/ext/transport/chttp2/transport/timeout_encoding.c)6
-rw-r--r--src/core/lib/transport/timeout_encoding.h (renamed from src/core/ext/transport/chttp2/transport/timeout_encoding.h)14
-rw-r--r--src/core/plugin_registry/grpc_plugin_registry.c4
-rw-r--r--src/core/plugin_registry/grpc_unsecure_plugin_registry.c4
-rw-r--r--src/cpp/server/server_context.cc15
-rw-r--r--src/csharp/.nuget/packages.config6
-rw-r--r--src/csharp/Grpc.Core.Tests/SanityTest.cs7
-rw-r--r--src/csharp/Grpc.Core.Tests/packages.config5
-rw-r--r--src/csharp/Grpc.Core.Tests/project.json5
-rw-r--r--src/csharp/Grpc.Examples.MathClient/packages.config3
-rw-r--r--src/csharp/Grpc.Examples.MathServer/packages.config3
-rw-r--r--src/csharp/Grpc.IntegrationTesting.QpsWorker/packages.config3
-rw-r--r--src/csharp/Grpc.IntegrationTesting.StressClient/packages.config3
-rw-r--r--src/node/ext/call_credentials.cc30
-rw-r--r--src/node/health_check/package.json4
-rw-r--r--src/node/src/credentials.js5
-rw-r--r--src/php/README.md43
-rw-r--r--src/php/composer.json4
-rw-r--r--src/php/ext/grpc/call.c545
-rw-r--r--src/php/ext/grpc/call.h30
-rw-r--r--src/php/ext/grpc/call_credentials.c141
-rwxr-xr-xsrc/php/ext/grpc/call_credentials.h29
-rw-r--r--src/php/ext/grpc/channel.c168
-rwxr-xr-xsrc/php/ext/grpc/channel.h17
-rw-r--r--src/php/ext/grpc/channel_credentials.c117
-rwxr-xr-xsrc/php/ext/grpc/channel_credentials.h28
-rw-r--r--src/php/ext/grpc/package.xml156
-rw-r--r--src/php/ext/grpc/php7_wrapper.h166
-rw-r--r--src/php/ext/grpc/server.c115
-rwxr-xr-xsrc/php/ext/grpc/server.h18
-rw-r--r--src/php/ext/grpc/server_credentials.c98
-rwxr-xr-xsrc/php/ext/grpc/server_credentials.h25
-rw-r--r--src/php/ext/grpc/timeval.c129
-rwxr-xr-xsrc/php/ext/grpc/timeval.h20
-rw-r--r--src/proto/census/census.proto119
-rw-r--r--src/python/grpcio/grpc_core_dependencies.py5
-rw-r--r--src/ruby/.rubocop.yml4
-rwxr-xr-xsrc/ruby/bin/math_client.rb2
-rw-r--r--[-rwxr-xr-x]src/ruby/bin/math_pb.rb (renamed from src/ruby/bin/math.rb)0
-rwxr-xr-xsrc/ruby/bin/math_server.rb2
-rw-r--r--[-rwxr-xr-x]src/ruby/bin/math_services_pb.rb (renamed from src/ruby/bin/math_services.rb)2
-rw-r--r--src/ruby/ext/grpc/rb_grpc_imports.generated.c22
-rw-r--r--src/ruby/ext/grpc/rb_grpc_imports.generated.h33
-rw-r--r--src/ruby/pb/grpc/health/checker.rb2
-rw-r--r--src/ruby/pb/grpc/health/v1/health_pb.rb (renamed from src/ruby/pb/grpc/health/v1/health.rb)0
-rw-r--r--src/ruby/pb/grpc/health/v1/health_services_pb.rb (renamed from src/ruby/pb/grpc/health/v1/health_services.rb)2
-rw-r--r--src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services_pb.rb (renamed from src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services.rb)4
-rw-r--r--src/ruby/pb/grpc/testing/metrics_pb.rb (renamed from src/ruby/pb/grpc/testing/metrics.rb)2
-rw-r--r--src/ruby/pb/grpc/testing/metrics_services_pb.rb (renamed from src/ruby/pb/grpc/testing/metrics_services.rb)4
-rw-r--r--src/ruby/pb/src/proto/grpc/testing/empty_pb.rb (renamed from src/ruby/pb/src/proto/grpc/testing/empty.rb)0
-rw-r--r--src/ruby/pb/src/proto/grpc/testing/messages_pb.rb (renamed from src/ruby/pb/src/proto/grpc/testing/messages.rb)0
-rw-r--r--src/ruby/pb/src/proto/grpc/testing/test_pb.rb (renamed from src/ruby/pb/src/proto/grpc/testing/test.rb)4
-rw-r--r--src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb (renamed from src/ruby/pb/src/proto/grpc/testing/test_services.rb)2
-rwxr-xr-xsrc/ruby/pb/test/client.rb6
-rwxr-xr-xsrc/ruby/pb/test/server.rb6
-rw-r--r--src/ruby/qps/client.rb2
-rw-r--r--src/ruby/qps/server.rb6
-rw-r--r--src/ruby/qps/src/proto/grpc/testing/control_pb.rb (renamed from src/ruby/qps/src/proto/grpc/testing/control.rb)6
-rw-r--r--src/ruby/qps/src/proto/grpc/testing/messages_pb.rb (renamed from src/ruby/qps/src/proto/grpc/testing/messages.rb)0
-rw-r--r--src/ruby/qps/src/proto/grpc/testing/payloads_pb.rb (renamed from src/ruby/qps/src/proto/grpc/testing/payloads.rb)0
-rw-r--r--src/ruby/qps/src/proto/grpc/testing/services_pb.rb (renamed from src/ruby/qps/src/proto/grpc/testing/services.rb)4
-rw-r--r--src/ruby/qps/src/proto/grpc/testing/services_services_pb.rb (renamed from src/ruby/qps/src/proto/grpc/testing/services_services.rb)2
-rw-r--r--src/ruby/qps/src/proto/grpc/testing/stats_pb.rb (renamed from src/ruby/qps/src/proto/grpc/testing/stats.rb)0
-rwxr-xr-xsrc/ruby/qps/worker.rb2
-rw-r--r--src/ruby/spec/pb/duplicate/codegen_spec.rb4
-rw-r--r--src/ruby/spec/pb/health/checker_spec.rb8
-rw-r--r--src/ruby/stress/metrics_server.rb4
-rwxr-xr-xsrc/ruby/tools/bin/grpc_tools_ruby_protoc (renamed from src/ruby/tools/bin/grpc_tools_ruby_protoc.rb)17
-rwxr-xr-xsrc/ruby/tools/bin/grpc_tools_ruby_protoc_plugin (renamed from src/ruby/tools/bin/grpc_tools_ruby_protoc_plugin.rb)0
-rw-r--r--src/ruby/tools/grpc-tools.gemspec2
113 files changed, 3034 insertions, 2070 deletions
diff --git a/src/compiler/ruby_generator_helpers-inl.h b/src/compiler/ruby_generator_helpers-inl.h
index ff6939ed9f..aa3c22fea6 100644
--- a/src/compiler/ruby_generator_helpers-inl.h
+++ b/src/compiler/ruby_generator_helpers-inl.h
@@ -48,7 +48,7 @@ inline bool ServicesFilename(const grpc::protobuf::FileDescriptor *file,
file->name().find_last_of(".proto") == file->name().size() - 1) {
*file_name_or_error =
file->name().substr(0, file->name().size() - proto_suffix_length) +
- "_services.rb";
+ "_services_pb.rb";
return true;
} else {
*file_name_or_error = "Invalid proto file name: must end with .proto";
@@ -58,7 +58,7 @@ inline bool ServicesFilename(const grpc::protobuf::FileDescriptor *file,
inline grpc::string MessagesRequireName(
const grpc::protobuf::FileDescriptor *file) {
- return Replace(file->name(), ".proto", "");
+ return Replace(file->name(), ".proto", "_pb");
}
// Get leading or trailing comments in a string. Comment lines start with "# ".
diff --git a/src/core/ext/census/base_resources.c b/src/core/ext/census/base_resources.c
new file mode 100644
index 0000000000..f9aa4bb994
--- /dev/null
+++ b/src/core/ext/census/base_resources.c
@@ -0,0 +1,71 @@
+/*
+ * 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/base_resources.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/census.h>
+#include <grpc/support/log.h>
+
+#include "src/core/ext/census/resource.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.
+
+// Define all base resources. This should be called by census initialization.
+void define_base_resources() {
+ 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
new file mode 100644
index 0000000000..e5a7696db4
--- /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/gen/census.pb.c b/src/core/ext/census/gen/census.pb.c
index d614636c90..647f0635b7 100644
--- a/src/core/ext/census/gen/census.pb.c
+++ b/src/core/ext/census/gen/census.pb.c
@@ -53,29 +53,24 @@ 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),
+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
};
-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),
- 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,25 +119,27 @@ 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
};
-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_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[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
};
@@ -156,7 +153,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 +164,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 d040fe29e7..dae583f33d 100644
--- a/src/core/ext/census/gen/census.pb.h
+++ b/src/core/ext/census/gen/census.pb.h
@@ -45,14 +45,21 @@ 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;
+
+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 {
@@ -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;
@@ -89,17 +98,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,37 +139,36 @@ 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;
+ 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;
pb_size_t which_data;
union {
+ uint64_t count;
google_census_Distribution distribution;
google_census_IntervalStats interval_stats;
} data;
@@ -177,10 +180,9 @@ 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_AggregationDescriptor_init_default {0, {google_census_AggregationDescriptor_BucketBoundaries_init_default}}
+#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 {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}}
@@ -188,15 +190,14 @@ 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_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_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, {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_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_AggregationDescriptor_init_zero {0, {google_census_AggregationDescriptor_BucketBoundaries_init_zero}}
+#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 {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}}
@@ -204,25 +205,25 @@ 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_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_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, {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
#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,32 +235,33 @@ 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_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
#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_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_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_AggregationDescriptor_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[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];
@@ -268,13 +270,12 @@ 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_ViewAggregations_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
#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/core/ext/census/grpc_filter.c b/src/core/ext/census/grpc_filter.c
index f51d850e01..9dacc17eb4 100644
--- a/src/core/ext/census/grpc_filter.c
+++ b/src/core/ext/census/grpc_filter.c
@@ -127,38 +127,40 @@ 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,
grpc_call_element *elem,
- const grpc_call_stats *stats,
+ const grpc_call_final_info *final_info,
void *ignored) {
call_data *d = elem->call_data;
GPR_ASSERT(d != NULL);
/* 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,
grpc_call_element *elem,
- const grpc_call_stats *stats,
+ const grpc_call_final_info *final_info,
void *ignored) {
call_data *d = elem->call_data;
GPR_ASSERT(d != NULL);
diff --git a/src/core/ext/census/initialize.c b/src/core/ext/census/initialize.c
index 896276e44a..55cbbe8e95 100644
--- a/src/core/ext/census/initialize.c
+++ b/src/core/ext/census/initialize.c
@@ -32,19 +32,31 @@
*/
#include <grpc/census.h>
+#include "src/core/ext/census/base_resources.h"
+#include "src/core/ext/census/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 fe23d13971..9f99c5bdcf 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 0000000000..ed44f004f9
--- /dev/null
+++ b/src/core/ext/census/resource.c
@@ -0,0 +1,312 @@
+/*
+ *
+ * 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 "third_party/nanopb/pb_decode.h"
+
+#include <grpc/census.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+
+#include <stdbool.h>
+#include <string.h>
+
+// 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(void) {
+ gpr_mu_init(&resource_lock);
+ gpr_mu_lock(&resource_lock);
+ GPR_ASSERT(resources == NULL && n_resources == 0 && n_defined_resources == 0);
+ gpr_mu_unlock(&resource_lock);
+}
+
+// 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);
+ 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) {
+ 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:
+ 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;
+ 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;
+}
+
+// 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;
+ uint64_t value;
+ if (!pb_decode_varint(stream, &value)) {
+ return false;
+ }
+ *(*bup + *count - 1) = (google_census_Resource_BasicUnit)value;
+ }
+ return true;
+}
+
+// Validate units field of a Resource proto.
+static bool validate_units(pb_istream_t *stream, const pb_field_t *field,
+ void **arg) {
+ 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;
+}
+
+// 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);
+ 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.description.arg = resources[id];
+ vresource.unit.numerator.funcs.decode = &validate_units;
+ 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);
+ 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 &&
+ resources[id]->n_numerators > 0);
+}
+
+// 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;
+ size_t id = n_resources; // resource ID - initialize to invalid value.
+ // Expand resources if needed.
+ if (n_resources == n_defined_resources) {
+ 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,
+ (new_n_resources - n_resources) * sizeof(resource *));
+ gpr_free(resources);
+ resources = new_resources;
+ n_resources = new_n_resources;
+ 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));
+ 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)) {
+ delete_resource_locked(id);
+ gpr_mu_unlock(&resource_lock);
+ return -1;
+ }
+ 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 && strcmp(resources[id]->name, name) == 0) {
+ gpr_mu_unlock(&resource_lock);
+ return id;
+ }
+ }
+ 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) + 1;
+ 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
new file mode 100644
index 0000000000..591bff07da
--- /dev/null
+++ b/src/core/ext/census/resource.h
@@ -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.
+ *
+ */
+
+/* Census-internal resource definition and manipluation functions. */
+#ifndef GRPC_CORE_EXT_CENSUS_RESOURCE_H
+#define GRPC_CORE_EXT_CENSUS_RESOURCE_H
+
+#include <grpc/grpc.h>
+#include "src/core/ext/census/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 */
diff --git a/src/core/ext/client_config/client_channel.c b/src/core/ext/client_config/client_channel.c
index a096435c98..2c0c4abffc 100644
--- a/src/core/ext/client_config/client_channel.c
+++ b/src/core/ext/client_config/client_channel.c
@@ -436,15 +436,17 @@ 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 */
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) {
grpc_subchannel_call_holder_destroy(exec_ctx, elem->call_data);
gpr_free(and_free_memory);
diff --git a/src/core/ext/client_config/lb_policy.h b/src/core/ext/client_config/lb_policy.h
index 3cfd041d3a..a2f5446fc6 100644
--- a/src/core/ext/client_config/lb_policy.h
+++ b/src/core/ext/client_config/lb_policy.h
@@ -73,7 +73,7 @@ struct grpc_lb_policy_vtable {
void (*ping_one)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
grpc_closure *closure);
- /** try to enter a READY connectivity state */
+ /** Try to enter a READY connectivity state */
void (*exit_idle)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy);
/** check the current connectivity of the lb_policy */
@@ -82,7 +82,9 @@ struct grpc_lb_policy_vtable {
grpc_error **connectivity_error);
/** call notify when the connectivity state of a channel changes from *state.
- Updates *state with the new state of the policy */
+ Updates *state with the new state of the policy. Calling with a NULL \a
+ state cancels the subscription.
+ */
void (*notify_on_state_change)(grpc_exec_ctx *exec_ctx,
grpc_lb_policy *policy,
grpc_connectivity_state *state,
@@ -125,7 +127,7 @@ void grpc_lb_policy_init(grpc_lb_policy *policy,
/** Given initial metadata in \a initial_metadata, find an appropriate
target for this rpc, and 'return' it by calling \a on_complete after setting
\a target.
- Picking can be asynchronous. Any IO should be done under \a pollset. */
+ Picking can be asynchronous. Any IO should be done under \a pollent. */
int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
grpc_polling_entity *pollent,
grpc_metadata_batch *initial_metadata,
@@ -147,8 +149,11 @@ void grpc_lb_policy_cancel_picks(grpc_exec_ctx *exec_ctx,
uint32_t initial_metadata_flags_mask,
uint32_t initial_metadata_flags_eq);
+/** Try to enter a READY connectivity state */
void grpc_lb_policy_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy);
+/* Call notify when the connectivity state of a channel changes from \a *state.
+ * Updates \a *state with the new state of the policy */
void grpc_lb_policy_notify_on_state_change(grpc_exec_ctx *exec_ctx,
grpc_lb_policy *policy,
grpc_connectivity_state *state,
diff --git a/src/core/ext/client_config/subchannel.c b/src/core/ext/client_config/subchannel.c
index d089cd4399..df35904b85 100644
--- a/src/core/ext/client_config/subchannel.c
+++ b/src/core/ext/client_config/subchannel.c
@@ -702,19 +702,26 @@ 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; // Ref is added below.
+ 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);
+ 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_init(exec_ctx, chanstk, 1, subchannel_call_destroy, call,
- NULL, NULL, callstk);
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 b6d39f5dc5..ae1d96e640 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 b96a0ad093..be6d054af4 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_error != GRPC_ERROR_NONE) {
- 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) {
@@ -158,10 +164,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, GRPC_ERROR_REF(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;
}
@@ -189,10 +202,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) {
+ new_error = 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);
diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c
new file mode 100644
index 0000000000..dec25efe61
--- /dev/null
+++ b/src/core/ext/lb_policy/grpclb/grpclb.c
@@ -0,0 +1,1039 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/** Implementation of the gRPC LB policy.
+ *
+ * This policy takes as input a set of resolved addresses {a1..an} for which the
+ * LB set was set (it's the resolver's responsibility to ensure this). That is
+ * to say, {a1..an} represent a collection of LB servers.
+ *
+ * An internal channel (\a glb_lb_policy.lb_channel) is created over {a1..an}.
+ * This channel behaves just like a regular channel. In particular, the
+ * constructed URI over the addresses a1..an will use the default pick first
+ * policy to select from this list of LB server backends.
+ *
+ * The first time the policy gets a request for a pick, a ping, or to exit the
+ * idle state, \a query_for_backends() is called. It creates an instance of \a
+ * lb_client_data, an internal struct meant to contain the data associated with
+ * the internal communication with the LB server. This instance is created via
+ * \a lb_client_data_create(). There, the call over lb_channel to pick-first
+ * from {a1..an} is created, the \a LoadBalancingRequest message is assembled
+ * and all necessary callbacks for the progress of the internal call configured.
+ *
+ * Back in \a query_for_backends(), the internal *streaming* call to the LB
+ * server (whichever address from {a1..an} pick-first chose) is kicked off.
+ * It'll progress over the callbacks configured in \a lb_client_data_create()
+ * (see the field docstrings of \a lb_client_data for more details).
+ *
+ * If the call fails with UNIMPLEMENTED, the original call will also fail.
+ * There's a misconfiguration somewhere: at least one of {a1..an} isn't a LB
+ * server, which contradicts the LB bit being set. If the internal call times
+ * out, the usual behavior of pick-first applies, continuing to pick from the
+ * list {a1..an}.
+ *
+ * Upon sucesss, a \a LoadBalancingResponse is expected in \a res_recv_cb. An
+ * invalid one results in the termination of the streaming call. A new streaming
+ * call should be created if possible, failing the original call otherwise.
+ * For a valid \a LoadBalancingResponse, the server list of actual backends is
+ * extracted. A Round Robin policy will be created from this list. There are two
+ * possible scenarios:
+ *
+ * 1. This is the first server list received. There was no previous instance of
+ * the Round Robin policy. \a rr_handover() will instantiate the RR policy
+ * and perform all the pending operations over it.
+ * 2. There's already a RR policy instance active. We need to introduce the new
+ * one build from the new serverlist, but taking care not to disrupt the
+ * operations in progress over the old RR instance. This is done by
+ * decreasing the reference count on the old policy. The moment no more
+ * references are held on the old RR policy, it'll be destroyed and \a
+ * rr_connectivity_changed notified with a \a GRPC_CHANNEL_SHUTDOWN state.
+ * At this point we can transition to a new RR instance safely, which is done
+ * once again via \a rr_handover().
+ *
+ *
+ * Once a RR policy instance is in place (and getting updated as described),
+ * calls to for a pick, a ping or a cancellation will be serviced right away by
+ * forwarding them to the RR instance. Any time there's no RR policy available
+ * (ie, right after the creation of the gRPCLB policy, if an empty serverlist
+ * is received, etc), pick/ping requests are added to a list of pending
+ * picks/pings to be flushed and serviced as part of \a rr_handover() the moment
+ * the RR policy instance becomes available.
+ *
+ * \see https://github.com/grpc/grpc/blob/master/doc/load-balancing.md for the
+ * high level design and details. */
+
+/* TODO(dgq):
+ * - Implement LB service forwarding (point 2c. in the doc's diagram).
+ */
+
+#include <string.h>
+
+#include <grpc/byte_buffer_reader.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/ext/client_config/client_channel_factory.h"
+#include "src/core/ext/client_config/lb_policy_registry.h"
+#include "src/core/ext/client_config/parse_address.h"
+#include "src/core/ext/lb_policy/grpclb/grpclb.h"
+#include "src/core/ext/lb_policy/grpclb/load_balancer_api.h"
+#include "src/core/lib/iomgr/sockaddr_utils.h"
+#include "src/core/lib/support/string.h"
+#include "src/core/lib/surface/call.h"
+#include "src/core/lib/surface/channel.h"
+
+int grpc_lb_glb_trace = 0;
+
+typedef struct wrapped_rr_closure_arg {
+ /* the original closure. Usually a on_complete/notify cb for pick() and ping()
+ * calls against the internal RR instance, respectively. */
+ grpc_closure *wrapped_closure;
+
+ /* The RR instance related to the closure */
+ grpc_lb_policy *rr_policy;
+
+ /* when not NULL, represents a pending_{pick,ping} node to be freed upon
+ * closure execution */
+ void *owning_pending_node; /* to be freed if not NULL */
+} wrapped_rr_closure_arg;
+
+/* The \a on_complete closure passed as part of the pick requires keeping a
+ * reference to its associated round robin instance. We wrap this closure in
+ * order to unref the round robin instance upon its invocation */
+static void wrapped_rr_closure(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error) {
+ wrapped_rr_closure_arg *wc_arg = arg;
+ if (wc_arg->rr_policy != NULL) {
+ if (grpc_lb_glb_trace) {
+ gpr_log(GPR_INFO, "Unreffing RR (0x%" PRIxPTR ")",
+ (intptr_t)wc_arg->rr_policy);
+ }
+ GRPC_LB_POLICY_UNREF(exec_ctx, wc_arg->rr_policy, "wrapped_rr_closure");
+ }
+ GPR_ASSERT(wc_arg->wrapped_closure != NULL);
+ grpc_exec_ctx_sched(exec_ctx, wc_arg->wrapped_closure, error, NULL);
+ gpr_free(wc_arg->owning_pending_node);
+}
+
+/* Linked list of pending pick requests. It stores all information needed to
+ * eventually call (Round Robin's) pick() on them. They mainly stay pending
+ * waiting for the RR policy to be created/updated.
+ *
+ * One particularity is the wrapping of the user-provided \a on_complete closure
+ * (in \a wrapped_on_complete and \a wrapped_on_complete_arg). This is needed in
+ * order to correctly unref the RR policy instance upon completion of the pick.
+ * See \a wrapped_rr_closure for details. */
+typedef struct pending_pick {
+ struct pending_pick *next;
+
+ /* polling entity for the pick()'s async notification */
+ grpc_polling_entity *pollent;
+
+ /* the initial metadata for the pick. See grpc_lb_policy_pick() */
+ grpc_metadata_batch *initial_metadata;
+
+ /* bitmask passed to pick() and used for selective cancelling. See
+ * grpc_lb_policy_cancel_picks() */
+ uint32_t initial_metadata_flags;
+
+ /* output argument where to store the pick()ed connected subchannel, or NULL
+ * upon error. */
+ grpc_connected_subchannel **target;
+
+ /* a closure wrapping the original on_complete one to be invoked once the
+ * pick() has completed (regardless of success) */
+ grpc_closure wrapped_on_complete;
+
+ /* args for wrapped_on_complete */
+ wrapped_rr_closure_arg wrapped_on_complete_arg;
+} pending_pick;
+
+static void add_pending_pick(pending_pick **root, grpc_polling_entity *pollent,
+ grpc_metadata_batch *initial_metadata,
+ uint32_t initial_metadata_flags,
+ grpc_connected_subchannel **target,
+ grpc_closure *on_complete) {
+ pending_pick *pp = gpr_malloc(sizeof(*pp));
+ memset(pp, 0, sizeof(pending_pick));
+ memset(&pp->wrapped_on_complete_arg, 0, sizeof(wrapped_rr_closure_arg));
+ pp->next = *root;
+ pp->pollent = pollent;
+ pp->target = target;
+ pp->initial_metadata = initial_metadata;
+ pp->initial_metadata_flags = initial_metadata_flags;
+ pp->wrapped_on_complete_arg.wrapped_closure = on_complete;
+ grpc_closure_init(&pp->wrapped_on_complete, wrapped_rr_closure,
+ &pp->wrapped_on_complete_arg);
+ *root = pp;
+}
+
+/* Same as the \a pending_pick struct but for ping operations */
+typedef struct pending_ping {
+ struct pending_ping *next;
+
+ /* a closure wrapping the original on_complete one to be invoked once the
+ * ping() has completed (regardless of success) */
+ grpc_closure wrapped_notify;
+
+ /* args for wrapped_notify */
+ wrapped_rr_closure_arg wrapped_notify_arg;
+} pending_ping;
+
+static void add_pending_ping(pending_ping **root, grpc_closure *notify) {
+ pending_ping *pping = gpr_malloc(sizeof(*pping));
+ memset(pping, 0, sizeof(pending_ping));
+ memset(&pping->wrapped_notify_arg, 0, sizeof(wrapped_rr_closure_arg));
+ pping->next = *root;
+ grpc_closure_init(&pping->wrapped_notify, wrapped_rr_closure,
+ &pping->wrapped_notify_arg);
+ pping->wrapped_notify_arg.wrapped_closure = notify;
+ *root = pping;
+}
+
+/*
+ * glb_lb_policy
+ */
+typedef struct rr_connectivity_data rr_connectivity_data;
+struct lb_client_data;
+static const grpc_lb_policy_vtable glb_lb_policy_vtable;
+typedef struct glb_lb_policy {
+ /** base policy: must be first */
+ grpc_lb_policy base;
+
+ /** mutex protecting remaining members */
+ gpr_mu mu;
+
+ grpc_client_channel_factory *cc_factory;
+
+ /** for communicating with the LB server */
+ grpc_channel *lb_channel;
+
+ /** the RR policy to use of the backend servers returned by the LB server */
+ grpc_lb_policy *rr_policy;
+
+ bool started_picking;
+
+ /** our connectivity state tracker */
+ grpc_connectivity_state_tracker state_tracker;
+
+ /** stores the deserialized response from the LB. May be NULL until one such
+ * response has arrived. */
+ grpc_grpclb_serverlist *serverlist;
+
+ /** list of picks that are waiting on RR's policy connectivity */
+ pending_pick *pending_picks;
+
+ /** list of pings that are waiting on RR's policy connectivity */
+ pending_ping *pending_pings;
+
+ /** client data associated with the LB server communication */
+ struct lb_client_data *lb_client;
+
+ /** for tracking of the RR connectivity */
+ rr_connectivity_data *rr_connectivity;
+
+ /* a wrapped (see \a wrapped_rr_closure) on-complete closure for readily
+ * available RR picks */
+ grpc_closure wrapped_on_complete;
+
+ /* arguments for the wrapped_on_complete closure */
+ wrapped_rr_closure_arg wc_arg;
+} glb_lb_policy;
+
+/* Keeps track and reacts to changes in connectivity of the RR instance */
+struct rr_connectivity_data {
+ grpc_closure on_change;
+ grpc_connectivity_state state;
+ glb_lb_policy *glb_policy;
+};
+
+static grpc_lb_policy *create_rr(grpc_exec_ctx *exec_ctx,
+ const grpc_grpclb_serverlist *serverlist,
+ glb_lb_policy *glb_policy) {
+ /* TODO(dgq): support mixed ip version */
+ GPR_ASSERT(serverlist != NULL && serverlist->num_servers > 0);
+ char **host_ports = gpr_malloc(sizeof(char *) * serverlist->num_servers);
+ for (size_t i = 0; i < serverlist->num_servers; ++i) {
+ gpr_join_host_port(&host_ports[i], serverlist->servers[i]->ip_address,
+ serverlist->servers[i]->port);
+ }
+
+ size_t uri_path_len;
+ char *concat_ipports = gpr_strjoin_sep(
+ (const char **)host_ports, serverlist->num_servers, ",", &uri_path_len);
+
+ grpc_lb_policy_args args;
+ args.client_channel_factory = glb_policy->cc_factory;
+ args.addresses = gpr_malloc(sizeof(grpc_resolved_addresses));
+ args.addresses->naddrs = serverlist->num_servers;
+ args.addresses->addrs =
+ gpr_malloc(sizeof(grpc_resolved_address) * args.addresses->naddrs);
+ size_t out_addrs_idx = 0;
+ for (size_t i = 0; i < serverlist->num_servers; ++i) {
+ grpc_uri uri;
+ struct sockaddr_storage sa;
+ size_t sa_len;
+ uri.path = host_ports[i];
+ if (parse_ipv4(&uri, &sa, &sa_len)) { /* TODO(dgq): add support for ipv6 */
+ memcpy(args.addresses->addrs[out_addrs_idx].addr, &sa, sa_len);
+ args.addresses->addrs[out_addrs_idx].len = sa_len;
+ ++out_addrs_idx;
+ } else {
+ gpr_log(GPR_ERROR, "Invalid LB service address '%s', ignoring.",
+ host_ports[i]);
+ }
+ }
+
+ grpc_lb_policy *rr = grpc_lb_policy_create(exec_ctx, "round_robin", &args);
+
+ gpr_free(concat_ipports);
+ for (size_t i = 0; i < serverlist->num_servers; i++) {
+ gpr_free(host_ports[i]);
+ }
+ gpr_free(host_ports);
+ gpr_free(args.addresses->addrs);
+ gpr_free(args.addresses);
+ return rr;
+}
+
+static void rr_handover(grpc_exec_ctx *exec_ctx, glb_lb_policy *glb_policy,
+ grpc_error *error) {
+ GRPC_ERROR_REF(error);
+ glb_policy->rr_policy =
+ create_rr(exec_ctx, glb_policy->serverlist, glb_policy);
+
+ if (grpc_lb_glb_trace) {
+ gpr_log(GPR_INFO, "Created RR policy (0x%" PRIxPTR ")",
+ (intptr_t)glb_policy->rr_policy);
+ }
+ GPR_ASSERT(glb_policy->rr_policy != NULL);
+ glb_policy->rr_connectivity->state = grpc_lb_policy_check_connectivity(
+ exec_ctx, glb_policy->rr_policy, &error);
+ grpc_lb_policy_notify_on_state_change(
+ exec_ctx, glb_policy->rr_policy, &glb_policy->rr_connectivity->state,
+ &glb_policy->rr_connectivity->on_change);
+ grpc_connectivity_state_set(exec_ctx, &glb_policy->state_tracker,
+ glb_policy->rr_connectivity->state, error,
+ "rr_handover");
+ grpc_lb_policy_exit_idle(exec_ctx, glb_policy->rr_policy);
+
+ /* flush pending ops */
+ pending_pick *pp;
+ while ((pp = glb_policy->pending_picks)) {
+ glb_policy->pending_picks = pp->next;
+ GRPC_LB_POLICY_REF(glb_policy->rr_policy, "rr_handover_pending_pick");
+ pp->wrapped_on_complete_arg.rr_policy = glb_policy->rr_policy;
+ if (grpc_lb_glb_trace) {
+ gpr_log(GPR_INFO, "Pending pick about to PICK from 0x%" PRIxPTR "",
+ (intptr_t)glb_policy->rr_policy);
+ }
+ grpc_lb_policy_pick(exec_ctx, glb_policy->rr_policy, pp->pollent,
+ pp->initial_metadata, pp->initial_metadata_flags,
+ pp->target, &pp->wrapped_on_complete);
+ pp->wrapped_on_complete_arg.owning_pending_node = pp;
+ }
+
+ pending_ping *pping;
+ while ((pping = glb_policy->pending_pings)) {
+ glb_policy->pending_pings = pping->next;
+ GRPC_LB_POLICY_REF(glb_policy->rr_policy, "rr_handover_pending_ping");
+ pping->wrapped_notify_arg.rr_policy = glb_policy->rr_policy;
+ if (grpc_lb_glb_trace) {
+ gpr_log(GPR_INFO, "Pending ping about to PING from 0x%" PRIxPTR "",
+ (intptr_t)glb_policy->rr_policy);
+ }
+ grpc_lb_policy_ping_one(exec_ctx, glb_policy->rr_policy,
+ &pping->wrapped_notify);
+ pping->wrapped_notify_arg.owning_pending_node = pping;
+ }
+ GRPC_ERROR_UNREF(error);
+}
+
+static void rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error) {
+ rr_connectivity_data *rr_conn_data = arg;
+ glb_lb_policy *glb_policy = rr_conn_data->glb_policy;
+ if (rr_conn_data->state == GRPC_CHANNEL_SHUTDOWN) {
+ if (glb_policy->serverlist != NULL) {
+ /* a RR policy is shutting down but there's a serverlist available ->
+ * perform a handover */
+ rr_handover(exec_ctx, glb_policy, error);
+ } else {
+ /* shutting down and no new serverlist available. Bail out. */
+ gpr_free(rr_conn_data);
+ }
+ } else {
+ if (error == GRPC_ERROR_NONE) {
+ /* RR not shutting down. Mimic the RR's policy state */
+ grpc_connectivity_state_set(exec_ctx, &glb_policy->state_tracker,
+ rr_conn_data->state, error,
+ "rr_connectivity_changed");
+ /* resubscribe */
+ grpc_lb_policy_notify_on_state_change(exec_ctx, glb_policy->rr_policy,
+ &rr_conn_data->state,
+ &rr_conn_data->on_change);
+ } else { /* error */
+ gpr_free(rr_conn_data);
+ }
+ }
+ GRPC_ERROR_UNREF(error);
+}
+
+static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
+ grpc_lb_policy_factory *factory,
+ grpc_lb_policy_args *args) {
+ glb_lb_policy *glb_policy = gpr_malloc(sizeof(*glb_policy));
+ memset(glb_policy, 0, sizeof(*glb_policy));
+
+ /* All input addresses in args->addresses come from a resolver that claims
+ * they are LB services. It's the resolver's responsibility to make sure this
+ * policy is only instantiated and used in that case.
+ *
+ * Create a client channel over them to communicate with a LB service */
+ glb_policy->cc_factory = args->client_channel_factory;
+ GPR_ASSERT(glb_policy->cc_factory != NULL);
+ if (args->addresses->naddrs == 0) {
+ return NULL;
+ }
+
+ /* construct a target from the args->addresses, in the form
+ * ipvX://ip1:port1,ip2:port2,...
+ * TODO(dgq): support mixed ip version */
+ char **addr_strs = gpr_malloc(sizeof(char *) * args->addresses->naddrs);
+ addr_strs[0] =
+ grpc_sockaddr_to_uri((const struct sockaddr *)&args->addresses->addrs[0]);
+ for (size_t i = 1; i < args->addresses->naddrs; i++) {
+ GPR_ASSERT(grpc_sockaddr_to_string(
+ &addr_strs[i],
+ (const struct sockaddr *)&args->addresses->addrs[i],
+ true) == 0);
+ }
+ size_t uri_path_len;
+ char *target_uri_str = gpr_strjoin_sep(
+ (const char **)addr_strs, args->addresses->naddrs, ",", &uri_path_len);
+
+ /* will pick using pick_first */
+ glb_policy->lb_channel = grpc_client_channel_factory_create_channel(
+ exec_ctx, glb_policy->cc_factory, target_uri_str,
+ GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, NULL);
+
+ gpr_free(target_uri_str);
+ for (size_t i = 0; i < args->addresses->naddrs; i++) {
+ gpr_free(addr_strs[i]);
+ }
+ gpr_free(addr_strs);
+
+ if (glb_policy->lb_channel == NULL) {
+ gpr_free(glb_policy);
+ return NULL;
+ }
+
+ rr_connectivity_data *rr_connectivity =
+ gpr_malloc(sizeof(rr_connectivity_data));
+ memset(rr_connectivity, 0, sizeof(rr_connectivity_data));
+ grpc_closure_init(&rr_connectivity->on_change, rr_connectivity_changed,
+ rr_connectivity);
+ rr_connectivity->glb_policy = glb_policy;
+ glb_policy->rr_connectivity = rr_connectivity;
+
+ grpc_lb_policy_init(&glb_policy->base, &glb_lb_policy_vtable);
+ gpr_mu_init(&glb_policy->mu);
+ grpc_connectivity_state_init(&glb_policy->state_tracker, GRPC_CHANNEL_IDLE,
+ "grpclb");
+ return &glb_policy->base;
+}
+
+static void glb_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
+ glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
+ GPR_ASSERT(glb_policy->pending_picks == NULL);
+ GPR_ASSERT(glb_policy->pending_pings == NULL);
+ grpc_channel_destroy(glb_policy->lb_channel);
+ glb_policy->lb_channel = NULL;
+ grpc_connectivity_state_destroy(exec_ctx, &glb_policy->state_tracker);
+ if (glb_policy->serverlist != NULL) {
+ grpc_grpclb_destroy_serverlist(glb_policy->serverlist);
+ }
+ gpr_mu_destroy(&glb_policy->mu);
+ gpr_free(glb_policy);
+}
+
+static void lb_client_data_destroy(struct lb_client_data *lb_client);
+static void glb_shutdown(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
+ glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
+ gpr_mu_lock(&glb_policy->mu);
+
+ pending_pick *pp = glb_policy->pending_picks;
+ glb_policy->pending_picks = NULL;
+ pending_ping *pping = glb_policy->pending_pings;
+ glb_policy->pending_pings = NULL;
+ gpr_mu_unlock(&glb_policy->mu);
+
+ while (pp != NULL) {
+ pending_pick *next = pp->next;
+ *pp->target = NULL;
+ grpc_exec_ctx_sched(exec_ctx, &pp->wrapped_on_complete, GRPC_ERROR_NONE,
+ NULL);
+ gpr_free(pp);
+ pp = next;
+ }
+
+ while (pping != NULL) {
+ pending_ping *next = pping->next;
+ grpc_exec_ctx_sched(exec_ctx, &pping->wrapped_notify, GRPC_ERROR_NONE,
+ NULL);
+ pping = next;
+ }
+
+ if (glb_policy->rr_policy) {
+ /* unsubscribe */
+ grpc_lb_policy_notify_on_state_change(
+ exec_ctx, glb_policy->rr_policy, NULL,
+ &glb_policy->rr_connectivity->on_change);
+ GRPC_LB_POLICY_UNREF(exec_ctx, glb_policy->rr_policy, "glb_shutdown");
+ }
+
+ lb_client_data_destroy(glb_policy->lb_client);
+ glb_policy->lb_client = NULL;
+
+ grpc_connectivity_state_set(
+ exec_ctx, &glb_policy->state_tracker, GRPC_CHANNEL_SHUTDOWN,
+ GRPC_ERROR_CREATE("Channel Shutdown"), "glb_shutdown");
+}
+
+static void glb_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
+ grpc_connected_subchannel **target) {
+ glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
+ gpr_mu_lock(&glb_policy->mu);
+ pending_pick *pp = glb_policy->pending_picks;
+ glb_policy->pending_picks = NULL;
+ while (pp != NULL) {
+ pending_pick *next = pp->next;
+ if (pp->target == target) {
+ grpc_polling_entity_del_from_pollset_set(
+ exec_ctx, pp->pollent, glb_policy->base.interested_parties);
+ *target = NULL;
+ grpc_exec_ctx_sched(exec_ctx, &pp->wrapped_on_complete,
+ GRPC_ERROR_CANCELLED, NULL);
+ gpr_free(pp);
+ } else {
+ pp->next = glb_policy->pending_picks;
+ glb_policy->pending_picks = pp;
+ }
+ pp = next;
+ }
+ gpr_mu_unlock(&glb_policy->mu);
+}
+
+static grpc_call *lb_client_data_get_call(struct lb_client_data *lb_client);
+static void glb_cancel_picks(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
+ uint32_t initial_metadata_flags_mask,
+ uint32_t initial_metadata_flags_eq) {
+ glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
+ gpr_mu_lock(&glb_policy->mu);
+ if (glb_policy->lb_client != NULL) {
+ /* cancel the call to the load balancer service, if any */
+ grpc_call_cancel(lb_client_data_get_call(glb_policy->lb_client), NULL);
+ }
+ pending_pick *pp = glb_policy->pending_picks;
+ glb_policy->pending_picks = NULL;
+ while (pp != NULL) {
+ pending_pick *next = pp->next;
+ if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
+ initial_metadata_flags_eq) {
+ grpc_polling_entity_del_from_pollset_set(
+ exec_ctx, pp->pollent, glb_policy->base.interested_parties);
+ grpc_exec_ctx_sched(exec_ctx, &pp->wrapped_on_complete,
+ GRPC_ERROR_CANCELLED, NULL);
+ gpr_free(pp);
+ } else {
+ pp->next = glb_policy->pending_picks;
+ glb_policy->pending_picks = pp;
+ }
+ pp = next;
+ }
+ gpr_mu_unlock(&glb_policy->mu);
+}
+
+static void query_for_backends(grpc_exec_ctx *exec_ctx,
+ glb_lb_policy *glb_policy);
+static void start_picking(grpc_exec_ctx *exec_ctx, glb_lb_policy *glb_policy) {
+ glb_policy->started_picking = true;
+ query_for_backends(exec_ctx, glb_policy);
+}
+
+static void glb_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
+ glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
+ gpr_mu_lock(&glb_policy->mu);
+ if (!glb_policy->started_picking) {
+ start_picking(exec_ctx, glb_policy);
+ }
+ gpr_mu_unlock(&glb_policy->mu);
+}
+
+static int glb_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
+ grpc_polling_entity *pollent,
+ grpc_metadata_batch *initial_metadata,
+ uint32_t initial_metadata_flags,
+ grpc_connected_subchannel **target,
+ grpc_closure *on_complete) {
+ glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
+ gpr_mu_lock(&glb_policy->mu);
+ int r;
+
+ if (glb_policy->rr_policy != NULL) {
+ if (grpc_lb_glb_trace) {
+ gpr_log(GPR_INFO, "about to PICK from 0x%" PRIxPTR "",
+ (intptr_t)glb_policy->rr_policy);
+ }
+ GRPC_LB_POLICY_REF(glb_policy->rr_policy, "glb_pick");
+ memset(&glb_policy->wc_arg, 0, sizeof(wrapped_rr_closure_arg));
+ glb_policy->wc_arg.rr_policy = glb_policy->rr_policy;
+ glb_policy->wc_arg.wrapped_closure = on_complete;
+ grpc_closure_init(&glb_policy->wrapped_on_complete, wrapped_rr_closure,
+ &glb_policy->wc_arg);
+ r = grpc_lb_policy_pick(exec_ctx, glb_policy->rr_policy, pollent,
+ initial_metadata, initial_metadata_flags, target,
+ &glb_policy->wrapped_on_complete);
+ if (r != 0) {
+ /* the call to grpc_lb_policy_pick has been sychronous. Unreffing the RR
+ * policy and notify the original callback */
+ glb_policy->wc_arg.wrapped_closure = NULL;
+ if (grpc_lb_glb_trace) {
+ gpr_log(GPR_INFO, "Unreffing RR (0x%" PRIxPTR ")",
+ (intptr_t)glb_policy->wc_arg.rr_policy);
+ }
+ GRPC_LB_POLICY_UNREF(exec_ctx, glb_policy->wc_arg.rr_policy, "glb_pick");
+ grpc_exec_ctx_sched(exec_ctx, glb_policy->wc_arg.wrapped_closure,
+ GRPC_ERROR_NONE, NULL);
+ }
+ } else {
+ grpc_polling_entity_add_to_pollset_set(exec_ctx, pollent,
+ glb_policy->base.interested_parties);
+ add_pending_pick(&glb_policy->pending_picks, pollent, initial_metadata,
+ initial_metadata_flags, target, on_complete);
+
+ if (!glb_policy->started_picking) {
+ start_picking(exec_ctx, glb_policy);
+ }
+ r = 0;
+ }
+ gpr_mu_unlock(&glb_policy->mu);
+ return r;
+}
+
+static grpc_connectivity_state glb_check_connectivity(
+ grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
+ grpc_error **connectivity_error) {
+ glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
+ grpc_connectivity_state st;
+ gpr_mu_lock(&glb_policy->mu);
+ st = grpc_connectivity_state_check(&glb_policy->state_tracker,
+ connectivity_error);
+ gpr_mu_unlock(&glb_policy->mu);
+ return st;
+}
+
+static void glb_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
+ grpc_closure *closure) {
+ glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
+ gpr_mu_lock(&glb_policy->mu);
+ if (glb_policy->rr_policy) {
+ grpc_lb_policy_ping_one(exec_ctx, glb_policy->rr_policy, closure);
+ } else {
+ add_pending_ping(&glb_policy->pending_pings, closure);
+ if (!glb_policy->started_picking) {
+ start_picking(exec_ctx, glb_policy);
+ }
+ }
+ gpr_mu_unlock(&glb_policy->mu);
+}
+
+static void glb_notify_on_state_change(grpc_exec_ctx *exec_ctx,
+ grpc_lb_policy *pol,
+ grpc_connectivity_state *current,
+ grpc_closure *notify) {
+ glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
+ gpr_mu_lock(&glb_policy->mu);
+ grpc_connectivity_state_notify_on_state_change(
+ exec_ctx, &glb_policy->state_tracker, current, notify);
+
+ gpr_mu_unlock(&glb_policy->mu);
+}
+
+/*
+ * lb_client_data
+ *
+ * Used internally for the client call to the LB */
+typedef struct lb_client_data {
+ gpr_mu mu;
+
+ /* called once initial metadata's been sent */
+ grpc_closure md_sent;
+
+ /* called once initial metadata's been received */
+ grpc_closure md_rcvd;
+
+ /* called once the LoadBalanceRequest has been sent to the LB server. See
+ * src/proto/grpc/.../load_balancer.proto */
+ grpc_closure req_sent;
+
+ /* A response from the LB server has been received (or error). Process it */
+ grpc_closure res_rcvd;
+
+ /* After the client has sent a close to the LB server */
+ grpc_closure close_sent;
+
+ /* ... and the status from the LB server has been received */
+ grpc_closure srv_status_rcvd;
+
+ grpc_call *lb_call; /* streaming call to the LB server, */
+ gpr_timespec deadline; /* for the streaming call to the LB server */
+
+ grpc_metadata_array initial_metadata_recv; /* initial MD from LB server */
+ grpc_metadata_array trailing_metadata_recv; /* trailing MD from LB server */
+
+ /* what's being sent to the LB server. Note that its value may vary if the LB
+ * server indicates a redirect. */
+ grpc_byte_buffer *request_payload;
+
+ /* response from the LB server, if any. Processed in res_recv_cb() */
+ grpc_byte_buffer *response_payload;
+
+ /* the call's status and status detailset in srv_status_rcvd_cb() */
+ grpc_status_code status;
+ char *status_details;
+ size_t status_details_capacity;
+
+ /* pointer back to the enclosing policy */
+ glb_lb_policy *glb_policy;
+} lb_client_data;
+
+static void md_sent_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error);
+static void md_recv_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error);
+static void req_sent_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error);
+static void res_recv_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error);
+static void close_sent_cb(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error);
+static void srv_status_rcvd_cb(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error);
+
+static lb_client_data *lb_client_data_create(glb_lb_policy *glb_policy) {
+ lb_client_data *lb_client = gpr_malloc(sizeof(lb_client_data));
+ memset(lb_client, 0, sizeof(lb_client_data));
+
+ gpr_mu_init(&lb_client->mu);
+ grpc_closure_init(&lb_client->md_sent, md_sent_cb, lb_client);
+
+ grpc_closure_init(&lb_client->md_rcvd, md_recv_cb, lb_client);
+ grpc_closure_init(&lb_client->req_sent, req_sent_cb, lb_client);
+ grpc_closure_init(&lb_client->res_rcvd, res_recv_cb, lb_client);
+ grpc_closure_init(&lb_client->close_sent, close_sent_cb, lb_client);
+ grpc_closure_init(&lb_client->srv_status_rcvd, srv_status_rcvd_cb, lb_client);
+
+ /* TODO(dgq): get the deadline from the client config instead of fabricating
+ * one here. */
+ lb_client->deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
+ gpr_time_from_seconds(3, GPR_TIMESPAN));
+
+ lb_client->lb_call = grpc_channel_create_pollset_set_call(
+ glb_policy->lb_channel, NULL, GRPC_PROPAGATE_DEFAULTS,
+ glb_policy->base.interested_parties, "/BalanceLoad",
+ NULL, /* FIXME(dgq): which "host" value to use? */
+ lb_client->deadline, NULL);
+
+ grpc_metadata_array_init(&lb_client->initial_metadata_recv);
+ grpc_metadata_array_init(&lb_client->trailing_metadata_recv);
+
+ grpc_grpclb_request *request = grpc_grpclb_request_create(
+ "load.balanced.service.name"); /* FIXME(dgq): get the name of the load
+ balanced service from the resolver */
+ gpr_slice request_payload_slice = grpc_grpclb_request_encode(request);
+ lb_client->request_payload =
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ gpr_slice_unref(request_payload_slice);
+ grpc_grpclb_request_destroy(request);
+
+ lb_client->status_details = NULL;
+ lb_client->status_details_capacity = 0;
+ lb_client->glb_policy = glb_policy;
+ return lb_client;
+}
+
+static void lb_client_data_destroy(lb_client_data *lb_client) {
+ grpc_call_destroy(lb_client->lb_call);
+ grpc_metadata_array_destroy(&lb_client->initial_metadata_recv);
+ grpc_metadata_array_destroy(&lb_client->trailing_metadata_recv);
+
+ grpc_byte_buffer_destroy(lb_client->request_payload);
+
+ gpr_free(lb_client->status_details);
+ gpr_mu_destroy(&lb_client->mu);
+ gpr_free(lb_client);
+}
+static grpc_call *lb_client_data_get_call(lb_client_data *lb_client) {
+ return lb_client->lb_call;
+}
+
+/*
+ * Auxiliary functions and LB client callbacks.
+ */
+static void query_for_backends(grpc_exec_ctx *exec_ctx,
+ glb_lb_policy *glb_policy) {
+ GPR_ASSERT(glb_policy->lb_channel != NULL);
+
+ glb_policy->lb_client = lb_client_data_create(glb_policy);
+ grpc_call_error call_error;
+ grpc_op ops[1];
+ memset(ops, 0, sizeof(ops));
+ grpc_op *op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ call_error = grpc_call_start_batch_and_execute(
+ exec_ctx, glb_policy->lb_client->lb_call, ops, (size_t)(op - ops),
+ &glb_policy->lb_client->md_sent);
+ GPR_ASSERT(GRPC_CALL_OK == call_error);
+
+ op = ops;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata =
+ &glb_policy->lb_client->trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &glb_policy->lb_client->status;
+ op->data.recv_status_on_client.status_details =
+ &glb_policy->lb_client->status_details;
+ op->data.recv_status_on_client.status_details_capacity =
+ &glb_policy->lb_client->status_details_capacity;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ call_error = grpc_call_start_batch_and_execute(
+ exec_ctx, glb_policy->lb_client->lb_call, ops, (size_t)(op - ops),
+ &glb_policy->lb_client->srv_status_rcvd);
+ GPR_ASSERT(GRPC_CALL_OK == call_error);
+}
+
+static void md_sent_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
+ lb_client_data *lb_client = arg;
+ GPR_ASSERT(lb_client->lb_call);
+ grpc_op ops[1];
+ memset(ops, 0, sizeof(ops));
+ grpc_op *op = ops;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata = &lb_client->initial_metadata_recv;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ grpc_call_error call_error = grpc_call_start_batch_and_execute(
+ exec_ctx, lb_client->lb_call, ops, (size_t)(op - ops),
+ &lb_client->md_rcvd);
+ GPR_ASSERT(GRPC_CALL_OK == call_error);
+}
+
+static void md_recv_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
+ lb_client_data *lb_client = arg;
+ GPR_ASSERT(lb_client->lb_call);
+ grpc_op ops[1];
+ memset(ops, 0, sizeof(ops));
+ grpc_op *op = ops;
+
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message = lb_client->request_payload;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ grpc_call_error call_error = grpc_call_start_batch_and_execute(
+ exec_ctx, lb_client->lb_call, ops, (size_t)(op - ops),
+ &lb_client->req_sent);
+ GPR_ASSERT(GRPC_CALL_OK == call_error);
+}
+
+static void req_sent_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
+ lb_client_data *lb_client = arg;
+
+ grpc_op ops[1];
+ memset(ops, 0, sizeof(ops));
+ grpc_op *op = ops;
+
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message = &lb_client->response_payload;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ grpc_call_error call_error = grpc_call_start_batch_and_execute(
+ exec_ctx, lb_client->lb_call, ops, (size_t)(op - ops),
+ &lb_client->res_rcvd);
+ GPR_ASSERT(GRPC_CALL_OK == call_error);
+}
+
+static void res_recv_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
+ lb_client_data *lb_client = arg;
+ grpc_op ops[2];
+ memset(ops, 0, sizeof(ops));
+ grpc_op *op = ops;
+ if (lb_client->response_payload != NULL) {
+ /* Received data from the LB server. Look inside
+ * lb_client->response_payload, for
+ * a serverlist. */
+ grpc_byte_buffer_reader bbr;
+ grpc_byte_buffer_reader_init(&bbr, lb_client->response_payload);
+ gpr_slice response_slice = grpc_byte_buffer_reader_readall(&bbr);
+ grpc_byte_buffer_destroy(lb_client->response_payload);
+ grpc_grpclb_serverlist *serverlist =
+ grpc_grpclb_response_parse_serverlist(response_slice);
+ if (serverlist != NULL) {
+ gpr_slice_unref(response_slice);
+ if (grpc_lb_glb_trace) {
+ gpr_log(GPR_INFO, "Serverlist with %zu servers received",
+ serverlist->num_servers);
+ }
+
+ /* update serverlist */
+ if (serverlist->num_servers > 0) {
+ if (grpc_grpclb_serverlist_equals(lb_client->glb_policy->serverlist,
+ serverlist)) {
+ if (grpc_lb_glb_trace) {
+ gpr_log(GPR_INFO,
+ "Incoming server list identical to current, ignoring.");
+ }
+ } else { /* new serverlist */
+ if (lb_client->glb_policy->serverlist != NULL) {
+ /* dispose of the old serverlist */
+ grpc_grpclb_destroy_serverlist(lb_client->glb_policy->serverlist);
+ }
+ /* and update the copy in the glb_lb_policy instance */
+ lb_client->glb_policy->serverlist = serverlist;
+ }
+ if (lb_client->glb_policy->rr_policy == NULL) {
+ /* initial "handover", in this case from a null RR policy, meaning
+ * it'll just create the first RR policy instance */
+ rr_handover(exec_ctx, lb_client->glb_policy, error);
+ } else {
+ /* unref the RR policy, eventually leading to its substitution with a
+ * new one constructed from the received serverlist (see
+ * rr_connectivity_changed) */
+ GRPC_LB_POLICY_UNREF(exec_ctx, lb_client->glb_policy->rr_policy,
+ "serverlist_received");
+ }
+ } else {
+ if (grpc_lb_glb_trace) {
+ gpr_log(GPR_INFO,
+ "Received empty server list. Picks will stay pending until a "
+ "response with > 0 servers is received");
+ }
+ }
+
+ /* keep listening for serverlist updates */
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message = &lb_client->response_payload;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ const grpc_call_error call_error = grpc_call_start_batch_and_execute(
+ exec_ctx, lb_client->lb_call, ops, (size_t)(op - ops),
+ &lb_client->res_rcvd); /* loop */
+ GPR_ASSERT(GRPC_CALL_OK == call_error);
+ return;
+ }
+
+ GPR_ASSERT(serverlist == NULL);
+ gpr_log(GPR_ERROR, "Invalid LB response received: '%s'",
+ gpr_dump_slice(response_slice, GPR_DUMP_ASCII));
+ gpr_slice_unref(response_slice);
+
+ /* Disconnect from server returning invalid response. */
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ grpc_call_error call_error = grpc_call_start_batch_and_execute(
+ exec_ctx, lb_client->lb_call, ops, (size_t)(op - ops),
+ &lb_client->close_sent);
+ GPR_ASSERT(GRPC_CALL_OK == call_error);
+ }
+ /* empty payload: call cancelled by server. Cleanups happening in
+ * srv_status_rcvd_cb */
+}
+
+static void close_sent_cb(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error) {
+ if (grpc_lb_glb_trace) {
+ gpr_log(GPR_INFO,
+ "Close from LB client sent. Waiting from server status now");
+ }
+}
+
+static void srv_status_rcvd_cb(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error) {
+ lb_client_data *lb_client = arg;
+ if (grpc_lb_glb_trace) {
+ gpr_log(GPR_INFO,
+ "status from lb server received. Status = %d, Details = '%s', "
+ "Capaticy "
+ "= %zu",
+ lb_client->status, lb_client->status_details,
+ lb_client->status_details_capacity);
+ }
+ /* TODO(dgq): deal with stream termination properly (fire up another one? fail
+ * the original call?) */
+}
+
+/* Code wiring the policy with the rest of the core */
+static const grpc_lb_policy_vtable glb_lb_policy_vtable = {
+ glb_destroy, glb_shutdown, glb_pick,
+ glb_cancel_pick, glb_cancel_picks, glb_ping_one,
+ glb_exit_idle, glb_check_connectivity, glb_notify_on_state_change};
+
+static void glb_factory_ref(grpc_lb_policy_factory *factory) {}
+
+static void glb_factory_unref(grpc_lb_policy_factory *factory) {}
+
+static const grpc_lb_policy_factory_vtable glb_factory_vtable = {
+ glb_factory_ref, glb_factory_unref, glb_create, "grpclb"};
+
+static grpc_lb_policy_factory glb_lb_policy_factory = {&glb_factory_vtable};
+
+grpc_lb_policy_factory *grpc_glb_lb_factory_create() {
+ return &glb_lb_policy_factory;
+}
+
+/* Plugin registration */
+void grpc_lb_policy_grpclb_init() {
+ grpc_register_lb_policy(grpc_glb_lb_factory_create());
+ grpc_register_tracer("glb", &grpc_lb_glb_trace);
+}
+
+void grpc_lb_policy_grpclb_shutdown() {}
diff --git a/src/core/ext/lb_policy/grpclb/grpclb.h b/src/core/ext/lb_policy/grpclb/grpclb.h
new file mode 100644
index 0000000000..83552b4fa0
--- /dev/null
+++ b/src/core/ext/lb_policy/grpclb/grpclb.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * 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_LB_POLICY_GRPCLB_GRPCLB_H
+#define GRPC_CORE_EXT_LB_POLICY_GRPCLB_GRPCLB_H
+
+#include "src/core/ext/client_config/lb_policy_factory.h"
+
+/** Returns a load balancing factory for the glb policy, which tries to connect
+ * to a load balancing server to decide the next successfully connected
+ * subchannel to pick. */
+grpc_lb_policy_factory *grpc_glb_lb_factory_create();
+
+#endif /* GRPC_CORE_EXT_LB_POLICY_GRPCLB_GRPCLB_H */
diff --git a/src/core/ext/lb_policy/grpclb/load_balancer_api.c b/src/core/ext/lb_policy/grpclb/load_balancer_api.c
index 59b89997dd..f4720a1345 100644
--- a/src/core/ext/lb_policy/grpclb/load_balancer_api.c
+++ b/src/core/ext/lb_policy/grpclb/load_balancer_api.c
@@ -38,9 +38,15 @@
#include <grpc/support/alloc.h>
typedef struct decode_serverlist_arg {
- int first_pass;
- int i;
+ /* The first pass counts the number of servers in the server list. The second
+ * one allocates and decodes. */
+ bool first_pass;
+ /* The decoding callback is invoked once per server in serverlist. Remember
+ * which index of the serverlist are we currently decoding */
+ size_t decoding_idx;
+ /* Populated after the first pass. Number of server in the input serverlist */
size_t num_servers;
+ /* The decoded serverlist */
grpc_grpclb_server **servers;
} decode_serverlist_arg;
@@ -48,23 +54,24 @@ typedef struct decode_serverlist_arg {
static bool decode_serverlist(pb_istream_t *stream, const pb_field_t *field,
void **arg) {
decode_serverlist_arg *dec_arg = *arg;
- if (dec_arg->first_pass != 0) { /* first pass */
+ if (dec_arg->first_pass) { /* count how many server do we have */
grpc_grpclb_server server;
if (!pb_decode(stream, grpc_lb_v1_Server_fields, &server)) {
return false;
}
dec_arg->num_servers++;
- } else { /* second pass */
+ } else { /* second pass. Actually decode. */
grpc_grpclb_server *server = gpr_malloc(sizeof(grpc_grpclb_server));
+ memset(server, 0, sizeof(grpc_grpclb_server));
GPR_ASSERT(dec_arg->num_servers > 0);
- if (dec_arg->i == 0) { /* first iteration of second pass */
+ if (dec_arg->decoding_idx == 0) { /* first iteration of second pass */
dec_arg->servers =
gpr_malloc(sizeof(grpc_grpclb_server *) * dec_arg->num_servers);
}
if (!pb_decode(stream, grpc_lb_v1_Server_fields, server)) {
return false;
}
- dec_arg->servers[dec_arg->i++] = server;
+ dec_arg->servers[dec_arg->decoding_idx++] = server;
}
return true;
@@ -102,57 +109,59 @@ void grpc_grpclb_request_destroy(grpc_grpclb_request *request) {
gpr_free(request);
}
-grpc_grpclb_response *grpc_grpclb_response_parse(gpr_slice encoded_response) {
- bool status;
+typedef grpc_lb_v1_LoadBalanceResponse grpc_grpclb_response;
+grpc_grpclb_initial_response *grpc_grpclb_initial_response_parse(
+ gpr_slice encoded_grpc_grpclb_response) {
pb_istream_t stream =
- pb_istream_from_buffer(GPR_SLICE_START_PTR(encoded_response),
- GPR_SLICE_LENGTH(encoded_response));
- grpc_grpclb_response *res = gpr_malloc(sizeof(grpc_grpclb_response));
- memset(res, 0, sizeof(*res));
- status = pb_decode(&stream, grpc_lb_v1_LoadBalanceResponse_fields, res);
- if (!status) {
- grpc_grpclb_response_destroy(res);
+ pb_istream_from_buffer(GPR_SLICE_START_PTR(encoded_grpc_grpclb_response),
+ GPR_SLICE_LENGTH(encoded_grpc_grpclb_response));
+ grpc_grpclb_response res;
+ memset(&res, 0, sizeof(grpc_grpclb_response));
+ if (!pb_decode(&stream, grpc_lb_v1_LoadBalanceResponse_fields, &res)) {
return NULL;
}
- return res;
+ grpc_grpclb_initial_response *initial_res =
+ gpr_malloc(sizeof(grpc_grpclb_initial_response));
+ memcpy(initial_res, &res.initial_response,
+ sizeof(grpc_grpclb_initial_response));
+
+ return initial_res;
}
grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist(
- gpr_slice encoded_response) {
+ gpr_slice encoded_grpc_grpclb_response) {
bool status;
decode_serverlist_arg arg;
pb_istream_t stream =
- pb_istream_from_buffer(GPR_SLICE_START_PTR(encoded_response),
- GPR_SLICE_LENGTH(encoded_response));
+ pb_istream_from_buffer(GPR_SLICE_START_PTR(encoded_grpc_grpclb_response),
+ GPR_SLICE_LENGTH(encoded_grpc_grpclb_response));
pb_istream_t stream_at_start = stream;
- grpc_grpclb_response *res = gpr_malloc(sizeof(grpc_grpclb_response));
- memset(res, 0, sizeof(*res));
+ grpc_grpclb_response res;
+ memset(&res, 0, sizeof(grpc_grpclb_response));
memset(&arg, 0, sizeof(decode_serverlist_arg));
- res->server_list.servers.funcs.decode = decode_serverlist;
- res->server_list.servers.arg = &arg;
- arg.first_pass = 1;
- status = pb_decode(&stream, grpc_lb_v1_LoadBalanceResponse_fields, res);
+ res.server_list.servers.funcs.decode = decode_serverlist;
+ res.server_list.servers.arg = &arg;
+ arg.first_pass = true;
+ status = pb_decode(&stream, grpc_lb_v1_LoadBalanceResponse_fields, &res);
if (!status) {
- grpc_grpclb_response_destroy(res);
return NULL;
}
- arg.first_pass = 0;
+ arg.first_pass = false;
status =
- pb_decode(&stream_at_start, grpc_lb_v1_LoadBalanceResponse_fields, res);
+ pb_decode(&stream_at_start, grpc_lb_v1_LoadBalanceResponse_fields, &res);
if (!status) {
- grpc_grpclb_response_destroy(res);
return NULL;
}
grpc_grpclb_serverlist *sl = gpr_malloc(sizeof(grpc_grpclb_serverlist));
+ memset(sl, 0, sizeof(*sl));
sl->num_servers = arg.num_servers;
sl->servers = arg.servers;
- if (res->server_list.has_expiration_interval) {
- sl->expiration_interval = res->server_list.expiration_interval;
+ if (res.server_list.has_expiration_interval) {
+ sl->expiration_interval = res.server_list.expiration_interval;
}
- grpc_grpclb_response_destroy(res);
return sl;
}
@@ -167,6 +176,72 @@ void grpc_grpclb_destroy_serverlist(grpc_grpclb_serverlist *serverlist) {
gpr_free(serverlist);
}
-void grpc_grpclb_response_destroy(grpc_grpclb_response *response) {
+grpc_grpclb_serverlist *grpc_grpclb_serverlist_copy(
+ const grpc_grpclb_serverlist *sl) {
+ grpc_grpclb_serverlist *copy = gpr_malloc(sizeof(grpc_grpclb_serverlist));
+ memset(copy, 0, sizeof(grpc_grpclb_serverlist));
+ copy->num_servers = sl->num_servers;
+ memcpy(&copy->expiration_interval, &sl->expiration_interval,
+ sizeof(grpc_grpclb_duration));
+ copy->servers = gpr_malloc(sizeof(grpc_grpclb_server *) * sl->num_servers);
+ for (size_t i = 0; i < sl->num_servers; i++) {
+ copy->servers[i] = gpr_malloc(sizeof(grpc_grpclb_server));
+ memcpy(copy->servers[i], sl->servers[i], sizeof(grpc_grpclb_server));
+ }
+ return copy;
+}
+
+bool grpc_grpclb_serverlist_equals(const grpc_grpclb_serverlist *lhs,
+ const grpc_grpclb_serverlist *rhs) {
+ if ((lhs == NULL) || (rhs == NULL)) {
+ return false;
+ }
+ if (lhs->num_servers != rhs->num_servers) {
+ return false;
+ }
+ if (grpc_grpclb_duration_compare(&lhs->expiration_interval,
+ &rhs->expiration_interval) != 0) {
+ return false;
+ }
+ for (size_t i = 0; i < lhs->num_servers; i++) {
+ if (!grpc_grpclb_server_equals(lhs->servers[i], rhs->servers[i])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool grpc_grpclb_server_equals(const grpc_grpclb_server *lhs,
+ const grpc_grpclb_server *rhs) {
+ return memcmp(lhs, rhs, sizeof(grpc_grpclb_server)) == 0;
+}
+
+int grpc_grpclb_duration_compare(const grpc_grpclb_duration *lhs,
+ const grpc_grpclb_duration *rhs) {
+ GPR_ASSERT(lhs && rhs);
+ if (lhs->has_seconds && rhs->has_seconds) {
+ if (lhs->seconds < rhs->seconds) return -1;
+ if (lhs->seconds > rhs->seconds) return 1;
+ } else if (lhs->has_seconds) {
+ return 1;
+ } else if (rhs->has_seconds) {
+ return -1;
+ }
+
+ GPR_ASSERT(lhs->seconds == rhs->seconds);
+ if (lhs->has_nanos && rhs->has_nanos) {
+ if (lhs->nanos < rhs->nanos) return -1;
+ if (lhs->nanos > rhs->nanos) return 1;
+ } else if (lhs->has_nanos) {
+ return 1;
+ } else if (rhs->has_nanos) {
+ return -1;
+ }
+
+ return 0;
+}
+
+void grpc_grpclb_initial_response_destroy(
+ grpc_grpclb_initial_response *response) {
gpr_free(response);
}
diff --git a/src/core/ext/lb_policy/grpclb/load_balancer_api.h b/src/core/ext/lb_policy/grpclb/load_balancer_api.h
index 71b5616d0c..9726c87a37 100644
--- a/src/core/ext/lb_policy/grpclb/load_balancer_api.h
+++ b/src/core/ext/lb_policy/grpclb/load_balancer_api.h
@@ -46,7 +46,7 @@ extern "C" {
#define GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH 128
typedef grpc_lb_v1_LoadBalanceRequest grpc_grpclb_request;
-typedef grpc_lb_v1_LoadBalanceResponse grpc_grpclb_response;
+typedef grpc_lb_v1_InitialLoadBalanceResponse grpc_grpclb_initial_response;
typedef grpc_lb_v1_Server grpc_grpclb_server;
typedef grpc_lb_v1_Duration grpc_grpclb_duration;
typedef struct grpc_grpclb_serverlist {
@@ -64,19 +64,37 @@ gpr_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request);
/** Destroy \a request */
void grpc_grpclb_request_destroy(grpc_grpclb_request *request);
-/** Parse (ie, decode) the bytes in \a encoded_response as a \a
- * grpc_grpclb_response */
-grpc_grpclb_response *grpc_grpclb_response_parse(gpr_slice encoded_response);
+/** Parse (ie, decode) the bytes in \a encoded_grpc_grpclb_response as a \a
+ * grpc_grpclb_initial_response */
+grpc_grpclb_initial_response *grpc_grpclb_initial_response_parse(
+ gpr_slice encoded_grpc_grpclb_response);
+
+/** Parse the list of servers from an encoded \a grpc_grpclb_response */
+grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist(
+ gpr_slice encoded_grpc_grpclb_response);
+
+/** Return a copy of \a sl. The caller is responsible for calling \a
+ * grpc_grpclb_destroy_serverlist on the returned copy. */
+grpc_grpclb_serverlist *grpc_grpclb_serverlist_copy(
+ const grpc_grpclb_serverlist *sl);
+
+bool grpc_grpclb_serverlist_equals(const grpc_grpclb_serverlist *lhs,
+ const grpc_grpclb_serverlist *rhs);
+
+bool grpc_grpclb_server_equals(const grpc_grpclb_server *lhs,
+ const grpc_grpclb_server *rhs);
/** Destroy \a serverlist */
void grpc_grpclb_destroy_serverlist(grpc_grpclb_serverlist *serverlist);
-/** Parse the list of servers from an encoded \a grpc_grpclb_response */
-grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist(
- gpr_slice encoded_response);
+/** Compare \a lhs against \a rhs and return 0 if \a lhs and \a rhs are equal,
+ * < 0 if \a lhs represents a duration shorter than \a rhs and > 0 otherwise */
+int grpc_grpclb_duration_compare(const grpc_grpclb_duration *lhs,
+ const grpc_grpclb_duration *rhs);
-/** Destroy \a response */
-void grpc_grpclb_response_destroy(grpc_grpclb_response *response);
+/** Destroy \a initial_response */
+void grpc_grpclb_initial_response_destroy(
+ grpc_grpclb_initial_response *response);
#ifdef __cplusplus
}
diff --git a/src/core/ext/load_reporting/load_reporting.c b/src/core/ext/load_reporting/load_reporting.c
index 9e4d32676f..df1ea0ec9a 100644
--- a/src/core/ext/load_reporting/load_reporting.c
+++ b/src/core/ext/load_reporting/load_reporting.c
@@ -42,42 +42,12 @@
#include "src/core/lib/channel/channel_stack_builder.h"
#include "src/core/lib/surface/channel_init.h"
-struct grpc_load_reporting_config {
- grpc_load_reporting_fn fn;
- void *user_data;
-};
-
-grpc_load_reporting_config *grpc_load_reporting_config_create(
- grpc_load_reporting_fn fn, void *user_data) {
- GPR_ASSERT(fn != NULL);
- grpc_load_reporting_config *lrc =
- gpr_malloc(sizeof(grpc_load_reporting_config));
- lrc->fn = fn;
- lrc->user_data = user_data;
- return lrc;
-}
-
-grpc_load_reporting_config *grpc_load_reporting_config_copy(
- grpc_load_reporting_config *src) {
- return grpc_load_reporting_config_create(src->fn, src->user_data);
-}
-
-void grpc_load_reporting_config_destroy(grpc_load_reporting_config *lrc) {
- gpr_free(lrc);
-}
-
-void grpc_load_reporting_config_call(
- grpc_load_reporting_config *lrc,
- const grpc_load_reporting_call_data *call_data) {
- lrc->fn(call_data, lrc->user_data);
-}
-
static bool is_load_reporting_enabled(const grpc_channel_args *a) {
if (a == NULL) return false;
for (size_t i = 0; i < a->num_args; i++) {
if (0 == strcmp(a->args[i].key, GRPC_ARG_ENABLE_LOAD_REPORTING)) {
- return a->args[i].type == GRPC_ARG_POINTER &&
- a->args[i].value.pointer.p != NULL;
+ return a->args[i].type == GRPC_ARG_INTEGER &&
+ a->args[i].value.integer != 0;
}
}
return false;
@@ -94,37 +64,17 @@ static bool maybe_add_load_reporting_filter(grpc_channel_stack_builder *builder,
return true;
}
-static void lrd_arg_destroy(void *p) { grpc_load_reporting_config_destroy(p); }
-
-static void *lrd_arg_copy(void *p) {
- return grpc_load_reporting_config_copy(p);
-}
-
-static int lrd_arg_cmp(void *a, void *b) {
- grpc_load_reporting_config *lhs = a;
- grpc_load_reporting_config *rhs = b;
- return !(lhs->fn == rhs->fn && lhs->user_data == rhs->user_data);
-}
-
-static const grpc_arg_pointer_vtable lrd_ptr_vtable = {
- lrd_arg_copy, lrd_arg_destroy, lrd_arg_cmp};
-
-grpc_arg grpc_load_reporting_config_create_arg(
- grpc_load_reporting_config *lrc) {
+grpc_arg grpc_load_reporting_enable_arg() {
grpc_arg arg;
- arg.type = GRPC_ARG_POINTER;
+ arg.type = GRPC_ARG_INTEGER;
arg.key = GRPC_ARG_ENABLE_LOAD_REPORTING;
- arg.value.pointer.p = lrc;
- arg.value.pointer.vtable = &lrd_ptr_vtable;
+ arg.value.integer = 1;
return arg;
}
/* Plugin registration */
void grpc_load_reporting_plugin_init(void) {
- grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX,
- maybe_add_load_reporting_filter,
- (void *)&grpc_load_reporting_filter);
grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX,
maybe_add_load_reporting_filter,
(void *)&grpc_load_reporting_filter);
diff --git a/src/core/ext/load_reporting/load_reporting.h b/src/core/ext/load_reporting/load_reporting.h
index 316cd89bd7..e37817d8c2 100644
--- a/src/core/ext/load_reporting/load_reporting.h
+++ b/src/core/ext/load_reporting/load_reporting.h
@@ -34,42 +34,47 @@
#ifndef GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_H
#define GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_H
-#include "src/core/lib/iomgr/closure.h"
-#include "src/core/lib/surface/call.h"
+#include <grpc/impl/codegen/grpc_types.h>
+#include "src/core/lib/channel/channel_stack.h"
-typedef struct grpc_load_reporting_config grpc_load_reporting_config;
+/** Metadata key for initial metadata coming from clients */
+/* TODO(dgq): change to the final value TBD */
+#define GRPC_LOAD_REPORTING_INITIAL_MD_KEY "load-reporting-initial"
-/** Call information to be passed to the provided load reporting function upon
- * completion of the call */
-typedef struct grpc_load_reporting_call_data {
- const grpc_call_stats *stats; /**< Stats for the call */
- const char *trailing_md_string; /**< LR trailing metadata info */
-} grpc_load_reporting_call_data;
+/** Metadata key for trailing metadata from servers */
+/* TODO(dgq): change to the final value TBD */
+#define GRPC_LOAD_REPORTING_TRAILING_MD_KEY "load-reporting-trailing"
-/** Custom function to be called by the load reporting filter. */
-typedef void (*grpc_load_reporting_fn)(
- const grpc_load_reporting_call_data *call_data, void *user_data);
+/** Identifiers for the invocation point of the users LR callback */
+typedef enum grpc_load_reporting_source {
+ GRPC_LR_POINT_UNKNOWN = 0,
+ GRPC_LR_POINT_CHANNEL_CREATION,
+ GRPC_LR_POINT_CHANNEL_DESTRUCTION,
+ GRPC_LR_POINT_CALL_CREATION,
+ GRPC_LR_POINT_CALL_DESTRUCTION
+} grpc_load_reporting_source;
-/** Register \a fn as the function to be invoked by the load reporting filter.
- * \a fn will be invoked at the beginning and at the end of the call.
- *
- * For the first invocation, \a fn's first argument
- * (grpc_load_reporting_call_data*) will be NULL. \a user_data is always passed
- * as-is. */
-grpc_load_reporting_config *grpc_load_reporting_config_create(
- grpc_load_reporting_fn fn, void *user_data);
+/** Call information to be passed to the provided LR callback. */
+typedef struct grpc_load_reporting_call_data {
+ const grpc_load_reporting_source source; /**< point of last data update. */
+
+ /** Unique identifier for the channel associated with the data */
+ intptr_t channel_id;
-grpc_load_reporting_config *grpc_load_reporting_config_copy(
- grpc_load_reporting_config *src);
+ /** Unique identifier for the call associated with the data. If the call
+ * hasn't been created yet, it'll have a value of zero. */
+ intptr_t call_id;
-void grpc_load_reporting_config_destroy(grpc_load_reporting_config *lrc);
+ /** Only valid when \a source is \a GRPC_LR_POINT_CALL_DESTRUCTION, that is,
+ * once the call has completed */
+ const grpc_call_final_info *final_info;
-/** Invoke the function registered by \a grpc_load_reporting_init. */
-void grpc_load_reporting_config_call(
- grpc_load_reporting_config *lrc,
- const grpc_load_reporting_call_data *call_data);
+ const char *initial_md_string; /**< value string for LR's initial md key */
+ const char *trailing_md_string; /**< value string for LR's trailing md key */
+ const char *method_name; /**< Corresponds to :path header */
+} grpc_load_reporting_call_data;
/** Return a \a grpc_arg enabling load reporting */
-grpc_arg grpc_load_reporting_config_create_arg(grpc_load_reporting_config *lrc);
+grpc_arg grpc_load_reporting_enable_arg();
#endif /* GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_H */
diff --git a/src/core/ext/load_reporting/load_reporting_filter.c b/src/core/ext/load_reporting/load_reporting_filter.c
index f372f88c3a..394f0cb832 100644
--- a/src/core/ext/load_reporting/load_reporting_filter.c
+++ b/src/core/ext/load_reporting/load_reporting_filter.c
@@ -31,6 +31,7 @@
*
*/
+#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
@@ -42,38 +43,112 @@
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/transport/static_metadata.h"
-typedef struct call_data { const char *trailing_md_string; } call_data;
+typedef struct call_data {
+ intptr_t id; /**< an id unique to the call */
+ char *trailing_md_string;
+ char *initial_md_string;
+ const char *service_method;
+
+ /* stores the recv_initial_metadata op's ready closure, which we wrap with our
+ * own (on_initial_md_ready) in order to capture the incoming initial metadata
+ * */
+ grpc_closure *ops_recv_initial_metadata_ready;
+
+ /* to get notified of the availability of the incoming initial metadata. */
+ grpc_closure on_initial_md_ready;
+ grpc_metadata_batch *recv_initial_metadata;
+} call_data;
+
typedef struct channel_data {
- gpr_mu mu;
- grpc_load_reporting_config *lrc;
+ intptr_t id; /**< an id unique to the channel */
} channel_data;
-static void invoke_lr_fn_locked(grpc_load_reporting_config *lrc,
- grpc_load_reporting_call_data *lr_call_data) {
- GPR_TIMER_BEGIN("load_reporting_config_fn", 0);
- grpc_load_reporting_config_call(lrc, lr_call_data);
- GPR_TIMER_END("load_reporting_config_fn", 0);
+typedef struct {
+ grpc_call_element *elem;
+ grpc_exec_ctx *exec_ctx;
+} recv_md_filter_args;
+
+static grpc_mdelem *recv_md_filter(void *user_data, grpc_mdelem *md) {
+ recv_md_filter_args *a = user_data;
+ grpc_call_element *elem = a->elem;
+ call_data *calld = elem->call_data;
+
+ if (md->key == GRPC_MDSTR_PATH) {
+ calld->service_method = grpc_mdstr_as_c_string(md->value);
+ } else if (md->key == GRPC_MDSTR_LOAD_REPORTING_INITIAL) {
+ calld->initial_md_string = gpr_strdup(grpc_mdstr_as_c_string(md->value));
+ return NULL;
+ }
+
+ return md;
+}
+
+static void on_initial_md_ready(grpc_exec_ctx *exec_ctx, void *user_data,
+ grpc_error *err) {
+ grpc_call_element *elem = user_data;
+ call_data *calld = elem->call_data;
+
+ if (err == GRPC_ERROR_NONE) {
+ recv_md_filter_args a;
+ a.elem = elem;
+ a.exec_ctx = exec_ctx;
+ grpc_metadata_batch_filter(calld->recv_initial_metadata, recv_md_filter,
+ &a);
+ if (calld->service_method == NULL) {
+ err =
+ grpc_error_add_child(err, GRPC_ERROR_CREATE("Missing :path header"));
+ }
+ } else {
+ GRPC_ERROR_REF(err);
+ }
+ calld->ops_recv_initial_metadata_ready->cb(
+ exec_ctx, calld->ops_recv_initial_metadata_ready->cb_arg, err);
+ GRPC_ERROR_UNREF(err);
}
/* 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));
+
+ calld->id = (intptr_t)args->call_stack;
+ grpc_closure_init(&calld->on_initial_md_ready, on_initial_md_ready, elem);
+
+ /* TODO(dgq): do something with the data
+ channel_data *chand = elem->channel_data;
+ grpc_load_reporting_call_data lr_call_data = {GRPC_LR_POINT_CALL_CREATION,
+ (intptr_t)chand->id,
+ (intptr_t)calld->id,
+ NULL,
+ NULL,
+ NULL,
+ NULL};
+ */
+
+ return GRPC_ERROR_NONE;
}
/* Destructor for call_data */
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
- const grpc_call_stats *stats, void *ignored) {
- channel_data *chand = elem->channel_data;
+ const grpc_call_final_info *final_info,
+ void *ignored) {
call_data *calld = elem->call_data;
- grpc_load_reporting_call_data lr_call_data = {stats,
- calld->trailing_md_string};
-
- gpr_mu_lock(&chand->mu);
- invoke_lr_fn_locked(chand->lrc, &lr_call_data);
- gpr_mu_unlock(&chand->mu);
+ /* TODO(dgq): do something with the data
+ channel_data *chand = elem->channel_data;
+ grpc_load_reporting_call_data lr_call_data = {GRPC_LR_POINT_CALL_DESTRUCTION,
+ (intptr_t)chand->id,
+ (intptr_t)calld->id,
+ final_info,
+ calld->initial_md_string,
+ calld->trailing_md_string,
+ calld->service_method};
+ */
+
+ gpr_free(calld->initial_md_string);
+ gpr_free(calld->trailing_md_string);
}
/* Constructor for channel_data */
@@ -85,37 +160,40 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
channel_data *chand = elem->channel_data;
memset(chand, 0, sizeof(channel_data));
- gpr_mu_init(&chand->mu);
- for (size_t i = 0; i < args->channel_args->num_args; i++) {
- if (0 == strcmp(args->channel_args->args[i].key,
- GRPC_ARG_ENABLE_LOAD_REPORTING)) {
- grpc_load_reporting_config *arg_lrc =
- args->channel_args->args[i].value.pointer.p;
- chand->lrc = grpc_load_reporting_config_copy(arg_lrc);
- GPR_ASSERT(chand->lrc != NULL);
- break;
- }
- }
- GPR_ASSERT(chand->lrc != NULL); /* arg actually found */
-
- gpr_mu_lock(&chand->mu);
- invoke_lr_fn_locked(chand->lrc, NULL);
- gpr_mu_unlock(&chand->mu);
+ chand->id = (intptr_t)args->channel_stack;
+
+ /* TODO(dgq): do something with the data
+ grpc_load_reporting_call_data lr_call_data = {GRPC_LR_POINT_CHANNEL_CREATION,
+ (intptr_t)chand,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ NULL};
+ */
}
/* Destructor for channel data */
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {
+ /* TODO(dgq): do something with the data
channel_data *chand = elem->channel_data;
- gpr_mu_destroy(&chand->mu);
- grpc_load_reporting_config_destroy(chand->lrc);
+ grpc_load_reporting_call_data lr_call_data = {
+ GRPC_LR_POINT_CHANNEL_DESTRUCTION,
+ (intptr_t)chand->id,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ NULL};
+ */
}
static grpc_mdelem *lr_trailing_md_filter(void *user_data, grpc_mdelem *md) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
- if (md->key == GRPC_MDSTR_LOAD_REPORTING) {
+ if (md->key == GRPC_MDSTR_LOAD_REPORTING_TRAILING) {
calld->trailing_md_string = gpr_strdup(grpc_mdstr_as_c_string(md->value));
return NULL;
}
@@ -127,8 +205,14 @@ static void lr_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
grpc_transport_stream_op *op) {
GPR_TIMER_BEGIN("lr_start_transport_stream_op", 0);
+ call_data *calld = elem->call_data;
- if (op->send_trailing_metadata) {
+ if (op->recv_initial_metadata) {
+ calld->recv_initial_metadata = op->recv_initial_metadata;
+ /* substitute our callback for the higher callback */
+ calld->ops_recv_initial_metadata_ready = op->recv_initial_metadata_ready;
+ op->recv_initial_metadata_ready = &calld->on_initial_md_ready;
+ } else if (op->send_trailing_metadata) {
grpc_metadata_batch_filter(op->send_trailing_metadata,
lr_trailing_md_filter, elem);
}
diff --git a/src/core/ext/load_reporting/load_reporting_filter.h b/src/core/ext/load_reporting/load_reporting_filter.h
index f69cd6fdc6..160ed32af9 100644
--- a/src/core/ext/load_reporting/load_reporting_filter.h
+++ b/src/core/ext/load_reporting/load_reporting_filter.h
@@ -34,6 +34,7 @@
#ifndef GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_FILTER_H
#define GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_FILTER_H
+#include "src/core/ext/load_reporting/load_reporting.h"
#include "src/core/lib/channel/channel_stack.h"
extern const grpc_channel_filter grpc_load_reporting_filter;
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index d050467a02..6bd65cea02 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -46,12 +46,12 @@
#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/iomgr/workqueue.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 ebeee37f0d..2cb8205d94 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 e1fc0ddee2..482cd55c44 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, \
@@ -668,8 +668,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/writing.c b/src/core/ext/transport/chttp2/transport/writing.c
index e0d87725e9..8f7a1f55c6 100644
--- a/src/core/ext/transport/chttp2/transport/writing.c
+++ b/src/core/ext/transport/chttp2/transport/writing.c
@@ -202,6 +202,7 @@ static void finalize_outbuf(grpc_exec_ctx *exec_ctx,
GPR_TIMER_BEGIN("finalize_outbuf", 0);
+ bool is_first_data_frame = true;
while (
grpc_chttp2_list_pop_writing_stream(transport_writing, &stream_writing)) {
uint32_t max_outgoing =
@@ -266,6 +267,11 @@ static void finalize_outbuf(grpc_exec_ctx *exec_ctx,
stream_writing->id, &stream_writing->flow_controlled_buffer,
send_bytes, is_last_frame, &stream_writing->stats,
&transport_writing->outbuf);
+ if (is_first_data_frame) {
+ /* TODO(dgq): this is a hack. It'll be fix in a future refactoring */
+ stream_writing->stats.data_bytes -= 5; /* discount grpc framing */
+ is_first_data_frame = false;
+ }
GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", transport_writing,
stream_writing, outgoing_window,
send_bytes);
diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c
index 87175d7943..98f304f2da 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;
@@ -178,6 +179,7 @@ void 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;
@@ -185,10 +187,19 @@ 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) {
+ 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);
}
+ return first_error;
}
void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
@@ -217,7 +228,7 @@ void grpc_call_stack_ignore_set_pollset_or_pollset_set(
grpc_polling_entity *pollent) {}
void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack,
- const grpc_call_stats *call_stats,
+ const grpc_call_final_info *final_info,
void *and_free_memory) {
grpc_call_element *elems = CALL_ELEMS_FROM_STACK(stack);
size_t count = stack->count;
@@ -225,7 +236,7 @@ void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack,
/* destroy per-filter data */
for (i = 0; i < count; i++) {
- elems[i].filter->destroy_call_elem(exec_ctx, &elems[i], call_stats,
+ elems[i].filter->destroy_call_elem(exec_ctx, &elems[i], final_info,
i == count - 1 ? and_free_memory : NULL);
}
}
diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h
index d72c015b67..ee68701456 100644
--- a/src/core/lib/channel/channel_stack.h
+++ b/src/core/lib/channel/channel_stack.h
@@ -75,9 +75,14 @@ typedef struct {
typedef struct {
grpc_transport_stream_stats transport_stream_stats;
gpr_timespec latency; /* From call creating to enqueing of received status */
- grpc_status_code final_status;
} grpc_call_stats;
+/** Information about the call upon completion. */
+typedef struct {
+ grpc_call_stats stats;
+ grpc_status_code final_status;
+} grpc_call_final_info;
+
/* Channel filters specify:
1. the amount of memory needed in the channel & call (via the sizeof_XXX
members)
@@ -110,8 +115,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);
@@ -119,16 +125,17 @@ typedef struct {
The filter does not need to do any chaining.
The bottom filter of a stack will be passed a non-NULL pointer to
\a and_free_memory that should be passed to gpr_free when destruction
- is complete. */
+ is complete. \a final_info contains data about the completed call, mainly
+ for reporting purposes. */
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);
/* sizeof(per channel data) */
size_t sizeof_channel_data;
/* Initialize per-channel data.
- elem is initialized at the start of the call, and elem->channel_data is
- what needs initializing.
+ elem is initialized at the creating of the channel, and elem->channel_data
+ is what needs initializing.
is_first, is_last designate this elements position in the stack, and are
useful for asserting correct configuration by upper layer code.
The filter does not need to do any chaining */
@@ -209,12 +216,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,
@@ -243,7 +251,7 @@ void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
/* Destroy a call stack */
void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack,
- const grpc_call_stats *call_stats,
+ const grpc_call_final_info *final_info,
void *and_free_memory);
/* Ignore set pollset{_set} - used by filters if they don't care about pollsets
diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c
index 32ebe53ee6..134180e619 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,11 +267,14 @@ 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 */
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
- const grpc_call_stats *stats, void *ignored) {
+ const grpc_call_final_info *final_info,
+ void *ignored) {
/* grab pointers to our data from the call element */
call_data *calld = elem->call_data;
gpr_slice_buffer_destroy(&calld->slices);
diff --git a/src/core/lib/channel/connected_channel.c b/src/core/lib/channel/connected_channel.c
index 0a7d27a1dc..918379c845 100644
--- a/src/core/lib/channel/connected_channel.c
+++ b/src/core/lib/channel/connected_channel.c
@@ -81,16 +81,16 @@ 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 stream initialization failed");
}
static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
@@ -104,7 +104,7 @@ static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
/* Destructor for call_data */
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) {
call_data *calld = elem->call_data;
channel_data *chand = elem->channel_data;
diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c
index 8057e251f0..a7a775cc53 100644
--- a/src/core/lib/channel/http_client_filter.c
+++ b/src/core/lib/channel/http_client_filter.c
@@ -175,16 +175,19 @@ 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 */
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
- const grpc_call_stats *stats, void *ignored) {}
+ const grpc_call_final_info *final_info,
+ void *ignored) {}
static grpc_mdelem *scheme_from_args(const grpc_channel_args *args) {
unsigned i;
diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/lib/channel/http_server_filter.c
index d0beebd817..5ce51f9016 100644
--- a/src/core/lib/channel/http_server_filter.c
+++ b/src/core/lib/channel/http_server_filter.c
@@ -224,18 +224,21 @@ 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 */
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
- const grpc_call_stats *stats, void *ignored) {}
+ const grpc_call_final_info *final_info,
+ void *ignored) {}
/* Constructor for channel_data */
static void init_channel_elem(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h
index 13f898e31a..bc7781250e 100644
--- a/src/core/lib/iomgr/error.h
+++ b/src/core/lib/iomgr/error.h
@@ -171,6 +171,8 @@ grpc_error *grpc_error_set_time(grpc_error *src, grpc_error_times which,
gpr_timespec value) GRPC_MUST_USE_RESULT;
grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which,
const char *value) GRPC_MUST_USE_RESULT;
+/// 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
diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c
index ec21e03944..974d5ae479 100644
--- a/src/core/lib/iomgr/tcp_posix.c
+++ b/src/core/lib/iomgr/tcp_posix.c
@@ -284,7 +284,7 @@ static void tcp_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
}
/* returns true if done, false if pending; if returning true, *error is set */
-#define MAX_WRITE_IOVEC 1024
+#define MAX_WRITE_IOVEC 1000
static bool tcp_flush(grpc_tcp *tcp, grpc_error **error) {
struct msghdr msg;
struct iovec iov[MAX_WRITE_IOVEC];
diff --git a/src/core/lib/security/transport/client_auth_filter.c b/src/core/lib/security/transport/client_auth_filter.c
index ed7929aa27..2a1bf4d4e3 100644
--- a/src/core/lib/security/transport/client_auth_filter.c
+++ b/src/core/lib/security/transport/client_auth_filter.c
@@ -267,10 +267,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,
@@ -282,7 +284,8 @@ static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
/* Destructor for call_data */
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
- const grpc_call_stats *stats, void *ignored) {
+ const grpc_call_final_info *final_info,
+ void *ignored) {
call_data *calld = elem->call_data;
grpc_call_credentials_unref(calld->creds);
if (calld->host != NULL) {
diff --git a/src/core/lib/security/transport/secure_endpoint.c b/src/core/lib/security/transport/secure_endpoint.c
index bc50f9d1b0..0169ccd9ef 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);
diff --git a/src/core/lib/security/transport/server_auth_filter.c b/src/core/lib/security/transport/server_auth_filter.c
index 12e789bde9..def16c8229 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,11 +223,14 @@ 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 */
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
- const grpc_call_stats *stats, void *ignored) {}
+ const grpc_call_final_info *final_info,
+ void *ignored) {}
/* Constructor for channel_data */
static void init_channel_elem(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c
index fc9df76dc1..772681109a 100644
--- a/src/core/lib/surface/call.c
+++ b/src/core/lib/surface/call.c
@@ -154,8 +154,9 @@ struct grpc_call {
/* Received call statuses from various sources */
received_status status[STATUS_SOURCE_COUNT];
- /* Call stats: only valid after trailing metadata received */
- grpc_call_stats stats;
+ /* Call data useful used for reporting. Only valid after the call has
+ * completed */
+ grpc_call_final_info final_info;
/* Compression algorithm for *incoming* data */
grpc_compression_algorithm incoming_compression_algorithm;
@@ -263,9 +264,19 @@ grpc_call *grpc_call_create(
gpr_convert_clock_type(send_deadline, GPR_CLOCK_MONOTONIC);
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));
+ 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);
+ close_with_status(&exec_ctx, call, (grpc_status_code)status,
+ error_str == NULL ? "unknown error" : error_str);
+ GRPC_ERROR_UNREF(error);
+ }
if (cq != NULL) {
GPR_ASSERT(
pollset_set_alternative == NULL &&
@@ -361,6 +372,25 @@ void grpc_call_internal_unref(grpc_exec_ctx *exec_ctx, grpc_call *c REF_ARG) {
GRPC_CALL_STACK_UNREF(exec_ctx, CALL_STACK_FROM_CALL(c), REF_REASON);
}
+static void get_final_status(grpc_call *call,
+ void (*set_value)(grpc_status_code code,
+ void *user_data),
+ void *set_value_user_data) {
+ int i;
+ for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
+ if (call->status[i].is_set) {
+ set_value(call->status[i].code, set_value_user_data);
+ return;
+ }
+ }
+ if (call->is_client) {
+ set_value(GRPC_STATUS_UNKNOWN, set_value_user_data);
+ } else {
+ set_value(GRPC_STATUS_OK, set_value_user_data);
+ }
+}
+
+static void set_status_value_directly(grpc_status_code status, void *dest);
static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
grpc_error *error) {
size_t i;
@@ -392,7 +422,11 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
GRPC_CQ_INTERNAL_UNREF(c->cq, "bind");
}
grpc_channel *channel = c->channel;
- grpc_call_stack_destroy(exec_ctx, CALL_STACK_FROM_CALL(c), &c->stats, c);
+
+ get_final_status(call, set_status_value_directly,
+ &c->final_info.final_status);
+
+ grpc_call_stack_destroy(exec_ctx, CALL_STACK_FROM_CALL(c), &c->final_info, c);
GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel, "call");
GPR_TIMER_END("destroy_call", 0);
}
@@ -414,24 +448,6 @@ static void set_status_details(grpc_call *call, status_source source,
}
}
-static void get_final_status(grpc_call *call,
- void (*set_value)(grpc_status_code code,
- void *user_data),
- void *set_value_user_data) {
- int i;
- for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
- if (call->status[i].is_set) {
- set_value(call->status[i].code, set_value_user_data);
- return;
- }
- }
- if (call->is_client) {
- set_value(GRPC_STATUS_UNKNOWN, set_value_user_data);
- } else {
- set_value(GRPC_STATUS_OK, set_value_user_data);
- }
-}
-
static void set_status_from_error(grpc_call *call, status_source source,
grpc_error *error) {
intptr_t status;
@@ -1361,6 +1377,9 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
int num_completion_callbacks_needed = 1;
grpc_call_error error = GRPC_CALL_OK;
+ // sent_initial_metadata guards against variable reuse.
+ grpc_metadata compression_md;
+
GPR_TIMER_BEGIN("grpc_call_start_batch", 0);
GRPC_CALL_LOG_BATCH(GPR_INFO, call, ops, nops, notify_tag);
@@ -1406,8 +1425,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
goto done_with_error;
}
/* process compression level */
- grpc_metadata compression_md;
- memset(&compression_md, 0, sizeof(grpc_metadata));
+ memset(&compression_md, 0, sizeof(compression_md));
size_t additional_metadata_count = 0;
grpc_compression_level effective_compression_level;
bool level_set = false;
@@ -1608,7 +1626,8 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
bctl->recv_final_op = 1;
stream_op.recv_trailing_metadata =
&call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
- stream_op.collect_stats = &call->stats.transport_stream_stats;
+ stream_op.collect_stats =
+ &call->final_info.stats.transport_stream_stats;
break;
case GRPC_OP_RECV_CLOSE_ON_SERVER:
/* Flag validation: currently allow no flags */
@@ -1630,7 +1649,8 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
bctl->recv_final_op = 1;
stream_op.recv_trailing_metadata =
&call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
- stream_op.collect_stats = &call->stats.transport_stream_stats;
+ stream_op.collect_stats =
+ &call->final_info.stats.transport_stream_stats;
break;
}
}
diff --git a/src/core/lib/surface/lame_client.c b/src/core/lib/surface/lame_client.c
index 5ea4cba5d1..19b78369dd 100644
--- a/src/core/lib/surface/lame_client.c
+++ b/src/core/lib/surface/lame_client.c
@@ -107,11 +107,14 @@ 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,
+ const grpc_call_final_info *final_info,
void *and_free_memory) {
gpr_free(and_free_memory);
}
diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c
index 2f108af48a..1d61ec3bbb 100644
--- a/src/core/lib/surface/server.c
+++ b/src/core/lib/surface/server.c
@@ -856,8 +856,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));
@@ -869,10 +870,12 @@ 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,
- const grpc_call_stats *stats, void *ignored) {
+ const grpc_call_final_info *final_info,
+ void *ignored) {
channel_data *chand = elem->channel_data;
call_data *calld = elem->call_data;
diff --git a/src/core/lib/transport/static_metadata.c b/src/core/lib/transport/static_metadata.c
index c5f16e530d..8f3e5b5b40 100644
--- a/src/core/lib/transport/static_metadata.c
+++ b/src/core/lib/transport/static_metadata.c
@@ -45,21 +45,21 @@ grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];
grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
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, 0, 0,
- 0, 0, 0, 0, 0, 0, 4, 8, 6, 2, 4, 8, 6, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 4, 8, 6, 2, 4, 8, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 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, 40, 67, 69, 67, 72, 68, 80,
- 68, 81, 70, 35, 71, 35, 73, 35, 74, 35, 75, 35, 76, 35, 77, 41, 77, 51,
- 77, 52, 78, 35, 79, 35, 82, 3, 82, 4, 82, 5, 82, 6, 82, 7, 82, 8,
- 82, 9, 83, 35, 84, 85, 86, 35, 87, 35, 88, 35, 89, 35, 90, 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",
@@ -126,7 +126,8 @@ const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = {
"if-unmodified-since",
"last-modified",
"link",
- "load-reporting",
+ "load-reporting-initial",
+ "load-reporting-trailing",
"location",
"max-forwards",
":method",
diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h
index 5ff0d2f3bc..b51bacac50 100644
--- a/src/core/lib/transport/static_metadata.h
+++ b/src/core/lib/transport/static_metadata.h
@@ -44,7 +44,7 @@
#include "src/core/lib/transport/metadata.h"
-#define GRPC_STATIC_MDSTR_COUNT 91
+#define GRPC_STATIC_MDSTR_COUNT 92
extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];
/* "0" */
#define GRPC_MDSTR_0 (&grpc_static_mdstr_table[0])
@@ -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" */
@@ -175,62 +175,64 @@ extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];
#define GRPC_MDSTR_LAST_MODIFIED (&grpc_static_mdstr_table[62])
/* "link" */
#define GRPC_MDSTR_LINK (&grpc_static_mdstr_table[63])
-/* "load-reporting" */
-#define GRPC_MDSTR_LOAD_REPORTING (&grpc_static_mdstr_table[64])
+/* "load-reporting-initial" */
+#define GRPC_MDSTR_LOAD_REPORTING_INITIAL (&grpc_static_mdstr_table[64])
+/* "load-reporting-trailing" */
+#define GRPC_MDSTR_LOAD_REPORTING_TRAILING (&grpc_static_mdstr_table[65])
/* "location" */
-#define GRPC_MDSTR_LOCATION (&grpc_static_mdstr_table[65])
+#define GRPC_MDSTR_LOCATION (&grpc_static_mdstr_table[66])
/* "max-forwards" */
-#define GRPC_MDSTR_MAX_FORWARDS (&grpc_static_mdstr_table[66])
+#define GRPC_MDSTR_MAX_FORWARDS (&grpc_static_mdstr_table[67])
/* ":method" */
-#define GRPC_MDSTR_METHOD (&grpc_static_mdstr_table[67])
+#define GRPC_MDSTR_METHOD (&grpc_static_mdstr_table[68])
/* ":path" */
-#define GRPC_MDSTR_PATH (&grpc_static_mdstr_table[68])
+#define GRPC_MDSTR_PATH (&grpc_static_mdstr_table[69])
/* "POST" */
-#define GRPC_MDSTR_POST (&grpc_static_mdstr_table[69])
+#define GRPC_MDSTR_POST (&grpc_static_mdstr_table[70])
/* "proxy-authenticate" */
-#define GRPC_MDSTR_PROXY_AUTHENTICATE (&grpc_static_mdstr_table[70])
+#define GRPC_MDSTR_PROXY_AUTHENTICATE (&grpc_static_mdstr_table[71])
/* "proxy-authorization" */
-#define GRPC_MDSTR_PROXY_AUTHORIZATION (&grpc_static_mdstr_table[71])
+#define GRPC_MDSTR_PROXY_AUTHORIZATION (&grpc_static_mdstr_table[72])
/* "PUT" */
-#define GRPC_MDSTR_PUT (&grpc_static_mdstr_table[72])
+#define GRPC_MDSTR_PUT (&grpc_static_mdstr_table[73])
/* "range" */
-#define GRPC_MDSTR_RANGE (&grpc_static_mdstr_table[73])
+#define GRPC_MDSTR_RANGE (&grpc_static_mdstr_table[74])
/* "referer" */
-#define GRPC_MDSTR_REFERER (&grpc_static_mdstr_table[74])
+#define GRPC_MDSTR_REFERER (&grpc_static_mdstr_table[75])
/* "refresh" */
-#define GRPC_MDSTR_REFRESH (&grpc_static_mdstr_table[75])
+#define GRPC_MDSTR_REFRESH (&grpc_static_mdstr_table[76])
/* "retry-after" */
-#define GRPC_MDSTR_RETRY_AFTER (&grpc_static_mdstr_table[76])
+#define GRPC_MDSTR_RETRY_AFTER (&grpc_static_mdstr_table[77])
/* ":scheme" */
-#define GRPC_MDSTR_SCHEME (&grpc_static_mdstr_table[77])
+#define GRPC_MDSTR_SCHEME (&grpc_static_mdstr_table[78])
/* "server" */
-#define GRPC_MDSTR_SERVER (&grpc_static_mdstr_table[78])
+#define GRPC_MDSTR_SERVER (&grpc_static_mdstr_table[79])
/* "set-cookie" */
-#define GRPC_MDSTR_SET_COOKIE (&grpc_static_mdstr_table[79])
+#define GRPC_MDSTR_SET_COOKIE (&grpc_static_mdstr_table[80])
/* "/" */
-#define GRPC_MDSTR_SLASH (&grpc_static_mdstr_table[80])
+#define GRPC_MDSTR_SLASH (&grpc_static_mdstr_table[81])
/* "/index.html" */
-#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (&grpc_static_mdstr_table[81])
+#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (&grpc_static_mdstr_table[82])
/* ":status" */
-#define GRPC_MDSTR_STATUS (&grpc_static_mdstr_table[82])
+#define GRPC_MDSTR_STATUS (&grpc_static_mdstr_table[83])
/* "strict-transport-security" */
-#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (&grpc_static_mdstr_table[83])
+#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (&grpc_static_mdstr_table[84])
/* "te" */
-#define GRPC_MDSTR_TE (&grpc_static_mdstr_table[84])
+#define GRPC_MDSTR_TE (&grpc_static_mdstr_table[85])
/* "trailers" */
-#define GRPC_MDSTR_TRAILERS (&grpc_static_mdstr_table[85])
+#define GRPC_MDSTR_TRAILERS (&grpc_static_mdstr_table[86])
/* "transfer-encoding" */
-#define GRPC_MDSTR_TRANSFER_ENCODING (&grpc_static_mdstr_table[86])
+#define GRPC_MDSTR_TRANSFER_ENCODING (&grpc_static_mdstr_table[87])
/* "user-agent" */
-#define GRPC_MDSTR_USER_AGENT (&grpc_static_mdstr_table[87])
+#define GRPC_MDSTR_USER_AGENT (&grpc_static_mdstr_table[88])
/* "vary" */
-#define GRPC_MDSTR_VARY (&grpc_static_mdstr_table[88])
+#define GRPC_MDSTR_VARY (&grpc_static_mdstr_table[89])
/* "via" */
-#define GRPC_MDSTR_VIA (&grpc_static_mdstr_table[89])
+#define GRPC_MDSTR_VIA (&grpc_static_mdstr_table[90])
/* "www-authenticate" */
-#define GRPC_MDSTR_WWW_AUTHENTICATE (&grpc_static_mdstr_table[90])
+#define GRPC_MDSTR_WWW_AUTHENTICATE (&grpc_static_mdstr_table[91])
-#define GRPC_STATIC_MDELEM_COUNT 80
+#define GRPC_STATIC_MDELEM_COUNT 81
extern grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];
/* "accept-charset": "" */
@@ -335,73 +337,76 @@ extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];
#define GRPC_MDELEM_LAST_MODIFIED_EMPTY (&grpc_static_mdelem_table[45])
/* "link": "" */
#define GRPC_MDELEM_LINK_EMPTY (&grpc_static_mdelem_table[46])
-/* "load-reporting": "" */
-#define GRPC_MDELEM_LOAD_REPORTING_EMPTY (&grpc_static_mdelem_table[47])
+/* "load-reporting-initial": "" */
+#define GRPC_MDELEM_LOAD_REPORTING_INITIAL_EMPTY (&grpc_static_mdelem_table[47])
+/* "load-reporting-trailing": "" */
+#define GRPC_MDELEM_LOAD_REPORTING_TRAILING_EMPTY \
+ (&grpc_static_mdelem_table[48])
/* "location": "" */
-#define GRPC_MDELEM_LOCATION_EMPTY (&grpc_static_mdelem_table[48])
+#define GRPC_MDELEM_LOCATION_EMPTY (&grpc_static_mdelem_table[49])
/* "max-forwards": "" */
-#define GRPC_MDELEM_MAX_FORWARDS_EMPTY (&grpc_static_mdelem_table[49])
+#define GRPC_MDELEM_MAX_FORWARDS_EMPTY (&grpc_static_mdelem_table[50])
/* ":method": "GET" */
-#define GRPC_MDELEM_METHOD_GET (&grpc_static_mdelem_table[50])
+#define GRPC_MDELEM_METHOD_GET (&grpc_static_mdelem_table[51])
/* ":method": "POST" */
-#define GRPC_MDELEM_METHOD_POST (&grpc_static_mdelem_table[51])
+#define GRPC_MDELEM_METHOD_POST (&grpc_static_mdelem_table[52])
/* ":method": "PUT" */
-#define GRPC_MDELEM_METHOD_PUT (&grpc_static_mdelem_table[52])
+#define GRPC_MDELEM_METHOD_PUT (&grpc_static_mdelem_table[53])
/* ":path": "/" */
-#define GRPC_MDELEM_PATH_SLASH (&grpc_static_mdelem_table[53])
+#define GRPC_MDELEM_PATH_SLASH (&grpc_static_mdelem_table[54])
/* ":path": "/index.html" */
-#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML (&grpc_static_mdelem_table[54])
+#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML (&grpc_static_mdelem_table[55])
/* "proxy-authenticate": "" */
-#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[55])
+#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[56])
/* "proxy-authorization": "" */
-#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY (&grpc_static_mdelem_table[56])
+#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY (&grpc_static_mdelem_table[57])
/* "range": "" */
-#define GRPC_MDELEM_RANGE_EMPTY (&grpc_static_mdelem_table[57])
+#define GRPC_MDELEM_RANGE_EMPTY (&grpc_static_mdelem_table[58])
/* "referer": "" */
-#define GRPC_MDELEM_REFERER_EMPTY (&grpc_static_mdelem_table[58])
+#define GRPC_MDELEM_REFERER_EMPTY (&grpc_static_mdelem_table[59])
/* "refresh": "" */
-#define GRPC_MDELEM_REFRESH_EMPTY (&grpc_static_mdelem_table[59])
+#define GRPC_MDELEM_REFRESH_EMPTY (&grpc_static_mdelem_table[60])
/* "retry-after": "" */
-#define GRPC_MDELEM_RETRY_AFTER_EMPTY (&grpc_static_mdelem_table[60])
+#define GRPC_MDELEM_RETRY_AFTER_EMPTY (&grpc_static_mdelem_table[61])
/* ":scheme": "grpc" */
-#define GRPC_MDELEM_SCHEME_GRPC (&grpc_static_mdelem_table[61])
+#define GRPC_MDELEM_SCHEME_GRPC (&grpc_static_mdelem_table[62])
/* ":scheme": "http" */
-#define GRPC_MDELEM_SCHEME_HTTP (&grpc_static_mdelem_table[62])
+#define GRPC_MDELEM_SCHEME_HTTP (&grpc_static_mdelem_table[63])
/* ":scheme": "https" */
-#define GRPC_MDELEM_SCHEME_HTTPS (&grpc_static_mdelem_table[63])
+#define GRPC_MDELEM_SCHEME_HTTPS (&grpc_static_mdelem_table[64])
/* "server": "" */
-#define GRPC_MDELEM_SERVER_EMPTY (&grpc_static_mdelem_table[64])
+#define GRPC_MDELEM_SERVER_EMPTY (&grpc_static_mdelem_table[65])
/* "set-cookie": "" */
-#define GRPC_MDELEM_SET_COOKIE_EMPTY (&grpc_static_mdelem_table[65])
+#define GRPC_MDELEM_SET_COOKIE_EMPTY (&grpc_static_mdelem_table[66])
/* ":status": "200" */
-#define GRPC_MDELEM_STATUS_200 (&grpc_static_mdelem_table[66])
+#define GRPC_MDELEM_STATUS_200 (&grpc_static_mdelem_table[67])
/* ":status": "204" */
-#define GRPC_MDELEM_STATUS_204 (&grpc_static_mdelem_table[67])
+#define GRPC_MDELEM_STATUS_204 (&grpc_static_mdelem_table[68])
/* ":status": "206" */
-#define GRPC_MDELEM_STATUS_206 (&grpc_static_mdelem_table[68])
+#define GRPC_MDELEM_STATUS_206 (&grpc_static_mdelem_table[69])
/* ":status": "304" */
-#define GRPC_MDELEM_STATUS_304 (&grpc_static_mdelem_table[69])
+#define GRPC_MDELEM_STATUS_304 (&grpc_static_mdelem_table[70])
/* ":status": "400" */
-#define GRPC_MDELEM_STATUS_400 (&grpc_static_mdelem_table[70])
+#define GRPC_MDELEM_STATUS_400 (&grpc_static_mdelem_table[71])
/* ":status": "404" */
-#define GRPC_MDELEM_STATUS_404 (&grpc_static_mdelem_table[71])
+#define GRPC_MDELEM_STATUS_404 (&grpc_static_mdelem_table[72])
/* ":status": "500" */
-#define GRPC_MDELEM_STATUS_500 (&grpc_static_mdelem_table[72])
+#define GRPC_MDELEM_STATUS_500 (&grpc_static_mdelem_table[73])
/* "strict-transport-security": "" */
#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \
- (&grpc_static_mdelem_table[73])
+ (&grpc_static_mdelem_table[74])
/* "te": "trailers" */
-#define GRPC_MDELEM_TE_TRAILERS (&grpc_static_mdelem_table[74])
+#define GRPC_MDELEM_TE_TRAILERS (&grpc_static_mdelem_table[75])
/* "transfer-encoding": "" */
-#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY (&grpc_static_mdelem_table[75])
+#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY (&grpc_static_mdelem_table[76])
/* "user-agent": "" */
-#define GRPC_MDELEM_USER_AGENT_EMPTY (&grpc_static_mdelem_table[76])
+#define GRPC_MDELEM_USER_AGENT_EMPTY (&grpc_static_mdelem_table[77])
/* "vary": "" */
-#define GRPC_MDELEM_VARY_EMPTY (&grpc_static_mdelem_table[77])
+#define GRPC_MDELEM_VARY_EMPTY (&grpc_static_mdelem_table[78])
/* "via": "" */
-#define GRPC_MDELEM_VIA_EMPTY (&grpc_static_mdelem_table[78])
+#define GRPC_MDELEM_VIA_EMPTY (&grpc_static_mdelem_table[79])
/* "www-authenticate": "" */
-#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[79])
+#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[80])
extern const uint8_t
grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2];
diff --git a/src/core/ext/transport/chttp2/transport/timeout_encoding.c b/src/core/lib/transport/timeout_encoding.c
index b7f7912493..b58ebbd0a8 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 <stdio.h>
#include <string.h>
@@ -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
index df2324c791..92f02f6ecd 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 <grpc/support/time.h>
#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/core/plugin_registry/grpc_plugin_registry.c b/src/core/plugin_registry/grpc_plugin_registry.c
index 905cd59e23..7a7a9ce477 100644
--- a/src/core/plugin_registry/grpc_plugin_registry.c
+++ b/src/core/plugin_registry/grpc_plugin_registry.c
@@ -37,6 +37,8 @@ extern void grpc_chttp2_plugin_init(void);
extern void grpc_chttp2_plugin_shutdown(void);
extern void grpc_client_config_init(void);
extern void grpc_client_config_shutdown(void);
+extern void grpc_lb_policy_grpclb_init(void);
+extern void grpc_lb_policy_grpclb_shutdown(void);
extern void grpc_lb_policy_pick_first_init(void);
extern void grpc_lb_policy_pick_first_shutdown(void);
extern void grpc_lb_policy_round_robin_init(void);
@@ -55,6 +57,8 @@ void grpc_register_built_in_plugins(void) {
grpc_chttp2_plugin_shutdown);
grpc_register_plugin(grpc_client_config_init,
grpc_client_config_shutdown);
+ grpc_register_plugin(grpc_lb_policy_grpclb_init,
+ grpc_lb_policy_grpclb_shutdown);
grpc_register_plugin(grpc_lb_policy_pick_first_init,
grpc_lb_policy_pick_first_shutdown);
grpc_register_plugin(grpc_lb_policy_round_robin_init,
diff --git a/src/core/plugin_registry/grpc_unsecure_plugin_registry.c b/src/core/plugin_registry/grpc_unsecure_plugin_registry.c
index 7995078725..ad4ddf0ff4 100644
--- a/src/core/plugin_registry/grpc_unsecure_plugin_registry.c
+++ b/src/core/plugin_registry/grpc_unsecure_plugin_registry.c
@@ -43,6 +43,8 @@ extern void grpc_resolver_sockaddr_init(void);
extern void grpc_resolver_sockaddr_shutdown(void);
extern void grpc_load_reporting_plugin_init(void);
extern void grpc_load_reporting_plugin_shutdown(void);
+extern void grpc_lb_policy_grpclb_init(void);
+extern void grpc_lb_policy_grpclb_shutdown(void);
extern void grpc_lb_policy_pick_first_init(void);
extern void grpc_lb_policy_pick_first_shutdown(void);
extern void grpc_lb_policy_round_robin_init(void);
@@ -61,6 +63,8 @@ void grpc_register_built_in_plugins(void) {
grpc_resolver_sockaddr_shutdown);
grpc_register_plugin(grpc_load_reporting_plugin_init,
grpc_load_reporting_plugin_shutdown);
+ grpc_register_plugin(grpc_lb_policy_grpclb_init,
+ grpc_lb_policy_grpclb_shutdown);
grpc_register_plugin(grpc_lb_policy_pick_first_init,
grpc_lb_policy_pick_first_shutdown);
grpc_register_plugin(grpc_lb_policy_round_robin_init,
diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc
index 43117fd1e9..1ca6a2b906 100644
--- a/src/cpp/server/server_context.cc
+++ b/src/cpp/server/server_context.cc
@@ -129,7 +129,8 @@ ServerContext::ServerContext()
deadline_(gpr_inf_future(GPR_CLOCK_REALTIME)),
call_(nullptr),
cq_(nullptr),
- sent_initial_metadata_(false) {}
+ sent_initial_metadata_(false),
+ compression_level_set_(false) {}
ServerContext::ServerContext(gpr_timespec deadline, grpc_metadata* metadata,
size_t metadata_count)
@@ -139,7 +140,8 @@ ServerContext::ServerContext(gpr_timespec deadline, grpc_metadata* metadata,
deadline_(deadline),
call_(nullptr),
cq_(nullptr),
- sent_initial_metadata_(false) {
+ sent_initial_metadata_(false),
+ compression_level_set_(false) {
for (size_t i = 0; i < metadata_count; i++) {
client_metadata_.insert(std::pair<grpc::string_ref, grpc::string_ref>(
metadata[i].key,
@@ -194,15 +196,6 @@ bool ServerContext::IsCancelled() const {
}
}
-void ServerContext::set_compression_level(grpc_compression_level level) {
- // TODO(dgq): get rid of grpc_call_compression_for_level and propagate the
- // compression level by adding a new argument to
- // CallOpSendInitialMetadata::SendInitialMetadata.
- const grpc_compression_algorithm algorithm_for_level =
- grpc_call_compression_for_level(call_, level);
- set_compression_algorithm(algorithm_for_level);
-}
-
void ServerContext::set_compression_algorithm(
grpc_compression_algorithm algorithm) {
char* algorithm_name = NULL;
diff --git a/src/csharp/.nuget/packages.config b/src/csharp/.nuget/packages.config
deleted file mode 100644
index 6154b3561f..0000000000
--- a/src/csharp/.nuget/packages.config
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
- <package id="NUnit.ConsoleRunner" version="3.2.0" />
- <package id="OpenCover" version="4.6.519" />
- <package id="ReportGenerator" version="2.4.4.0" />
-</packages> \ No newline at end of file
diff --git a/src/csharp/Grpc.Core.Tests/SanityTest.cs b/src/csharp/Grpc.Core.Tests/SanityTest.cs
index 501992c569..9d069fa432 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<string, List<string>> discoveredTests = DiscoverAllTestClasses();
+ Dictionary<string, List<string>> testsFromFile
+ = JsonConvert.DeserializeObject<Dictionary<string, List<string>>>(ReadTestsJson());
- Assert.AreEqual(discoveredTestsJson, ReadTestsJson());
+ Assert.AreEqual(discoveredTests, testsFromFile);
}
/// <summary>
diff --git a/src/csharp/Grpc.Core.Tests/packages.config b/src/csharp/Grpc.Core.Tests/packages.config
index aa7d951fdc..6a930c17ee 100644
--- a/src/csharp/Grpc.Core.Tests/packages.config
+++ b/src/csharp/Grpc.Core.Tests/packages.config
@@ -4,4 +4,7 @@
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
<package id="NUnit" version="3.2.0" targetFramework="net45" />
<package id="NUnitLite" version="3.2.0" targetFramework="net45" />
-</packages> \ No newline at end of file
+ <package id="NUnit.ConsoleRunner" version="3.2.0" />
+ <package id="OpenCover" version="4.6.519" />
+ <package id="ReportGenerator" version="2.4.4.0" />
+</packages>
diff --git a/src/csharp/Grpc.Core.Tests/project.json b/src/csharp/Grpc.Core.Tests/project.json
index d4c9a2ef31..4a682d927e 100644
--- a/src/csharp/Grpc.Core.Tests/project.json
+++ b/src/csharp/Grpc.Core.Tests/project.json
@@ -54,7 +54,10 @@
},
"Newtonsoft.Json": "8.0.3",
"NUnit": "3.2.0",
- "NUnitLite": "3.2.0-*"
+ "NUnitLite": "3.2.0-*",
+ "NUnit.ConsoleRunner": "3.2.0",
+ "OpenCover": "4.6.519",
+ "ReportGenerator": "2.4.4.0"
},
"frameworks": {
"net45": { },
diff --git a/src/csharp/Grpc.Examples.MathClient/packages.config b/src/csharp/Grpc.Examples.MathClient/packages.config
new file mode 100644
index 0000000000..79ece06bef
--- /dev/null
+++ b/src/csharp/Grpc.Examples.MathClient/packages.config
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+</packages>
diff --git a/src/csharp/Grpc.Examples.MathServer/packages.config b/src/csharp/Grpc.Examples.MathServer/packages.config
new file mode 100644
index 0000000000..79ece06bef
--- /dev/null
+++ b/src/csharp/Grpc.Examples.MathServer/packages.config
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+</packages>
diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/packages.config b/src/csharp/Grpc.IntegrationTesting.QpsWorker/packages.config
new file mode 100644
index 0000000000..79ece06bef
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/packages.config
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+</packages>
diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/packages.config b/src/csharp/Grpc.IntegrationTesting.StressClient/packages.config
new file mode 100644
index 0000000000..79ece06bef
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting.StressClient/packages.config
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+</packages>
diff --git a/src/node/ext/call_credentials.cc b/src/node/ext/call_credentials.cc
index 3c8f0c56da..81fc552fd1 100644
--- a/src/node/ext/call_credentials.cc
+++ b/src/node/ext/call_credentials.cc
@@ -68,6 +68,8 @@ using v8::Value;
Nan::Callback *CallCredentials::constructor;
Persistent<FunctionTemplate> CallCredentials::fun_tpl;
+static Callback *plugin_callback;
+
CallCredentials::CallCredentials(grpc_call_credentials *credentials)
: wrapped_credentials(credentials) {}
@@ -88,6 +90,11 @@ void CallCredentials::Init(Local<Object> exports) {
Nan::New<FunctionTemplate>(CreateFromPlugin)).ToLocalChecked());
Nan::Set(exports, Nan::New("CallCredentials").ToLocalChecked(), ctr);
constructor = new Nan::Callback(ctr);
+
+ Local<FunctionTemplate> callback_tpl =
+ Nan::New<FunctionTemplate>(PluginCallback);
+ plugin_callback = new Callback(
+ Nan::GetFunction(callback_tpl).ToLocalChecked());
}
bool CallCredentials::HasInstance(Local<Value> val) {
@@ -195,23 +202,28 @@ NAN_METHOD(PluginCallback) {
return Nan::ThrowTypeError(
"The callback's third argument must be an object");
}
+ if (!info[3]->IsObject()) {
+ return Nan::ThrowTypeError(
+ "The callback's fourth argument must be an object");
+ }
shared_ptr<Resources> resources(new Resources);
grpc_status_code code = static_cast<grpc_status_code>(
Nan::To<uint32_t>(info[0]).FromJust());
Utf8String details_utf8_str(info[1]);
char *details = *details_utf8_str;
grpc_metadata_array array;
+ Local<Object> callback_data = Nan::To<Object>(info[3]).ToLocalChecked();
if (!CreateMetadataArray(Nan::To<Object>(info[2]).ToLocalChecked(),
&array, resources)){
return Nan::ThrowError("Failed to parse metadata");
}
grpc_credentials_plugin_metadata_cb cb =
reinterpret_cast<grpc_credentials_plugin_metadata_cb>(
- Nan::Get(info.Callee(),
+ Nan::Get(callback_data,
Nan::New("cb").ToLocalChecked()
).ToLocalChecked().As<External>()->Value());
void *user_data =
- Nan::Get(info.Callee(),
+ Nan::Get(callback_data,
Nan::New("user_data").ToLocalChecked()
).ToLocalChecked().As<External>()->Value();
cb(user_data, array.metadata, array.count, code, details);
@@ -227,17 +239,17 @@ NAUV_WORK_CB(SendPluginCallback) {
while (!callbacks.empty()) {
plugin_callback_data *data = callbacks.front();
callbacks.pop_front();
- // Attach cb and user_data to plugin_callback so that it can access them later
- v8::Local<v8::Function> plugin_callback = Nan::GetFunction(
- Nan::New<v8::FunctionTemplate>(PluginCallback)).ToLocalChecked();
- Nan::Set(plugin_callback, Nan::New("cb").ToLocalChecked(),
+ Local<Object> callback_data = Nan::New<Object>();
+ Nan::Set(callback_data, Nan::New("cb").ToLocalChecked(),
Nan::New<v8::External>(reinterpret_cast<void*>(data->cb)));
- Nan::Set(plugin_callback, Nan::New("user_data").ToLocalChecked(),
+ Nan::Set(callback_data, Nan::New("user_data").ToLocalChecked(),
Nan::New<v8::External>(data->user_data));
- const int argc = 2;
+ const int argc = 3;
v8::Local<v8::Value> argv[argc] = {
Nan::New(data->service_url).ToLocalChecked(),
- plugin_callback
+ callback_data,
+ // Get Local<Function> from Nan::Callback*
+ **plugin_callback
};
Nan::Callback *callback = state->callback;
callback->Call(argc, argv);
diff --git a/src/node/health_check/package.json b/src/node/health_check/package.json
index 67f5301df7..40e276055b 100644
--- a/src/node/health_check/package.json
+++ b/src/node/health_check/package.json
@@ -19,11 +19,11 @@
"lodash": "^3.9.3",
"google-protobuf": "^3.0.0-alpha.5"
},
- "files": {
+ "files": [
"LICENSE",
"health.js",
"v1"
- },
+ ],
"main": "src/node/index.js",
"license": "BSD-3-Clause"
}
diff --git a/src/node/src/credentials.js b/src/node/src/credentials.js
index b746d0625d..043df06a66 100644
--- a/src/node/src/credentials.js
+++ b/src/node/src/credentials.js
@@ -92,7 +92,8 @@ exports.createSsl = ChannelCredentials.createSsl;
* @return {CallCredentials} The credentials object
*/
exports.createFromMetadataGenerator = function(metadata_generator) {
- return CallCredentials.createFromPlugin(function(service_url, callback) {
+ return CallCredentials.createFromPlugin(function(service_url, cb_data,
+ callback) {
metadata_generator({service_url: service_url}, function(error, metadata) {
var code = grpc.status.OK;
var message = '';
@@ -107,7 +108,7 @@ exports.createFromMetadataGenerator = function(metadata_generator) {
metadata = new Metadata();
}
}
- callback(code, message, metadata._getCoreRepresentation());
+ callback(code, message, metadata._getCoreRepresentation(), cb_data);
});
});
};
diff --git a/src/php/README.md b/src/php/README.md
index 8abedc40a3..7e9819b256 100644
--- a/src/php/README.md
+++ b/src/php/README.md
@@ -9,23 +9,12 @@ GA
## Environment
-Prerequisite: `php` >=5.5, `phpize`, `pecl`, `phpunit`
-
-**Linux (Debian):**
-
-```sh
-$ sudo apt-get install php5 php5-dev php-pear
-```
-
-**Linux (CentOS):**
-
-```sh
-$ yum install php55w
-$ yum --enablerepo=remi,remi-php55 install php-devel php-pear
-```
-
-**Mac OS X:**
+Prerequisite:
+* `php` 5.5 or above, 7.0 or above
+* `pear` and `pecl`
+* `phpunit`
+**PEAR:**
```sh
$ curl -O http://pear.php.net/go-pear.phar
$ sudo php -d detect_unicode=0 go-pear.phar
@@ -72,13 +61,7 @@ $ sudo make install
### gRPC PHP extension
-Install the gRPC PHP extension from PECL
-
-```sh
-$ sudo pecl install grpc
-```
-
-Or, compile from source
+Compile the gRPC PHP extension
```sh
$ cd grpc/src/php/ext/grpc
@@ -148,12 +131,8 @@ Alternatively, you can download `protoc` binaries from [the protocol buffers Git
You need to install `protoc-gen-php` to generate stub class `.php` files from service definition `.proto` files.
```sh
-$ cd grpc/src/php/vendor/stanley-cheung/protobuf-php # if you had run `composer install` in the previous step
-
-OR
-
-$ git clone https://github.com/stanley-cheung/Protobuf-PHP # clone from github repo
-
+$ git clone https://github.com/stanley-cheung/Protobuf-PHP
+$ cd Protobuf-PHP
$ gem install rake ronn
$ rake pear:package version=1.0
$ sudo pear install Protobuf-1.0.tgz
@@ -175,7 +154,7 @@ Run a local server serving the math services. Please see [Node][] for how to run
```sh
$ cd grpc
$ npm install
-$ nodejs src/node/test/math/math_server.js
+$ node src/node/test/math/math_server.js
```
### Run test client
@@ -212,7 +191,7 @@ Make sure the Node math server is still running, as above.
```sh
$ cd grpc
$ npm install
-$ nodejs src/node/test/math/math_server.js
+$ node src/node/test/math/math_server.js
```
Make sure you have run `composer install` to generate the `vendor/autoload.php` file
@@ -282,7 +261,7 @@ Make sure the Node math server is still running, as above.
```sh
$ cd grpc
$ npm install
-$ nodejs src/node/test/math/math_server.js
+$ node src/node/test/math/math_server.js
```
Make sure you have run `composer install` to generate the `vendor/autoload.php` file
diff --git a/src/php/composer.json b/src/php/composer.json
index 88418206e8..1eacc643a2 100644
--- a/src/php/composer.json
+++ b/src/php/composer.json
@@ -8,7 +8,9 @@
"version": "1.0.0",
"require": {
"php": ">=5.5.0",
- "stanley-cheung/protobuf-php": "v0.6",
+ "stanley-cheung/protobuf-php": "v0.6"
+ },
+ "require-dev": {
"google/auth": "v0.9"
},
"autoload": {
diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c
index d455002de6..66ca1513ed 100644
--- a/src/php/ext/grpc/call.c
+++ b/src/php/ext/grpc/call.c
@@ -58,66 +58,44 @@
#include "byte_buffer.h"
zend_class_entry *grpc_ce_call;
-
-#if PHP_MAJOR_VERSION < 7
+#if PHP_MAJOR_VERSION >= 7
+static zend_object_handlers call_ce_handlers;
+#endif
/* Frees and destroys an instance of wrapped_grpc_call */
-void free_wrapped_grpc_call(void *object TSRMLS_DC) {
- wrapped_grpc_call *call = (wrapped_grpc_call *)object;
- if (call->owned && call->wrapped != NULL) {
- grpc_call_destroy(call->wrapped);
+PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_call)
+ if (p->owned && p->wrapped != NULL) {
+ grpc_call_destroy(p->wrapped);
}
- zend_object_std_dtor(&call->std TSRMLS_CC);
- efree(call);
-}
+PHP_GRPC_FREE_WRAPPED_FUNC_END()
/* Initializes an instance of wrapped_grpc_call to be associated with an object
* of a class specified by class_type */
-zend_object_value create_wrapped_grpc_call(zend_class_entry *class_type
- TSRMLS_DC) {
- zend_object_value retval;
- wrapped_grpc_call *intern;
-
- intern = (wrapped_grpc_call *)emalloc(sizeof(wrapped_grpc_call));
- memset(intern, 0, sizeof(wrapped_grpc_call));
-
+php_grpc_zend_object create_wrapped_grpc_call(zend_class_entry *class_type
+ TSRMLS_DC) {
+ PHP_GRPC_ALLOC_CLASS_OBJECT(wrapped_grpc_call);
zend_object_std_init(&intern->std, class_type TSRMLS_CC);
object_properties_init(&intern->std, class_type);
- retval.handle = zend_objects_store_put(
- intern, (zend_objects_store_dtor_t)zend_objects_destroy_object,
- free_wrapped_grpc_call, NULL TSRMLS_CC);
- retval.handlers = zend_get_std_object_handlers();
- return retval;
-}
-
-/* Wraps a grpc_call struct in a PHP object. Owned indicates whether the struct
- should be destroyed at the end of the object's lifecycle */
-zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned TSRMLS_DC) {
- zval *call_object;
- MAKE_STD_ZVAL(call_object);
- object_init_ex(call_object, grpc_ce_call);
- wrapped_grpc_call *call =
- (wrapped_grpc_call *)zend_object_store_get_object(call_object TSRMLS_CC);
- call->wrapped = wrapped;
- call->owned = owned;
- return call_object;
+ PHP_GRPC_FREE_CLASS_OBJECT(wrapped_grpc_call, call_ce_handlers);
}
/* Creates and returns a PHP array object with the data in a
* grpc_metadata_array. Returns NULL on failure */
-zval *grpc_parse_metadata_array(grpc_metadata_array *metadata_array TSRMLS_DC) {
+zval *grpc_parse_metadata_array(grpc_metadata_array
+ *metadata_array TSRMLS_DC) {
int count = metadata_array->count;
grpc_metadata *elements = metadata_array->metadata;
- int i;
zval *array;
- zval **data = NULL;
+ PHP_GRPC_MAKE_STD_ZVAL(array);
+ array_init(array);
+ int i;
HashTable *array_hash;
zval *inner_array;
char *str_key;
char *str_val;
size_t key_len;
- MAKE_STD_ZVAL(array);
- array_init(array);
+ zval *data = NULL;
+
array_hash = Z_ARRVAL_P(array);
grpc_metadata *elem;
for (i = 0; i < count; i++) {
@@ -127,9 +105,9 @@ zval *grpc_parse_metadata_array(grpc_metadata_array *metadata_array TSRMLS_DC) {
memcpy(str_key, elem->key, key_len);
str_val = ecalloc(elem->value_length + 1, sizeof(char));
memcpy(str_val, elem->value, elem->value_length);
- if (zend_hash_find(array_hash, str_key, key_len, (void **)data) ==
- SUCCESS) {
- if (Z_TYPE_P(*data) != IS_ARRAY) {
+ if (php_grpc_zend_hash_find(array_hash, str_key, key_len, (void **)&data)
+ == SUCCESS) {
+ if (Z_TYPE_P(data) != IS_ARRAY) {
zend_throw_exception(zend_exception_get_default(TSRMLS_C),
"Metadata hash somehow contains wrong types.",
1 TSRMLS_CC);
@@ -137,11 +115,13 @@ zval *grpc_parse_metadata_array(grpc_metadata_array *metadata_array TSRMLS_DC) {
efree(str_val);
return NULL;
}
- add_next_index_stringl(*data, str_val, elem->value_length, false);
+ php_grpc_add_next_index_stringl(data, str_val, elem->value_length,
+ false);
} else {
- MAKE_STD_ZVAL(inner_array);
+ PHP_GRPC_MAKE_STD_ZVAL(inner_array);
array_init(inner_array);
- add_next_index_stringl(inner_array, str_val, elem->value_length, false);
+ php_grpc_add_next_index_stringl(inner_array, str_val,
+ elem->value_length, false);
add_assoc_zval(array, str_key, inner_array);
}
}
@@ -151,185 +131,64 @@ zval *grpc_parse_metadata_array(grpc_metadata_array *metadata_array TSRMLS_DC) {
/* Populates a grpc_metadata_array with the data in a PHP array object.
Returns true on success and false on failure */
bool create_metadata_array(zval *array, grpc_metadata_array *metadata) {
- zval **inner_array;
- zval **value;
HashTable *array_hash;
- HashPosition array_pointer;
HashTable *inner_array_hash;
- HashPosition inner_array_pointer;
- char *key;
- uint key_len;
- ulong index;
- if (Z_TYPE_P(array) != IS_ARRAY) {
- return false;
- }
- grpc_metadata_array_init(metadata);
- array_hash = Z_ARRVAL_P(array);
- for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer);
- zend_hash_get_current_data_ex(array_hash, (void**)&inner_array,
- &array_pointer) == SUCCESS;
- zend_hash_move_forward_ex(array_hash, &array_pointer)) {
- if (zend_hash_get_current_key_ex(array_hash, &key, &key_len, &index, 0,
- &array_pointer) != HASH_KEY_IS_STRING) {
- return false;
- }
- if (Z_TYPE_P(*inner_array) != IS_ARRAY) {
- return false;
- }
- inner_array_hash = Z_ARRVAL_P(*inner_array);
- metadata->capacity += zend_hash_num_elements(inner_array_hash);
- }
- metadata->metadata = gpr_malloc(metadata->capacity * sizeof(grpc_metadata));
- for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer);
- zend_hash_get_current_data_ex(array_hash, (void**)&inner_array,
- &array_pointer) == SUCCESS;
- zend_hash_move_forward_ex(array_hash, &array_pointer)) {
- if (zend_hash_get_current_key_ex(array_hash, &key, &key_len, &index, 0,
- &array_pointer) != HASH_KEY_IS_STRING) {
- return false;
- }
- inner_array_hash = Z_ARRVAL_P(*inner_array);
- for (zend_hash_internal_pointer_reset_ex(inner_array_hash,
- &inner_array_pointer);
- zend_hash_get_current_data_ex(inner_array_hash, (void**)&value,
- &inner_array_pointer) == SUCCESS;
- zend_hash_move_forward_ex(inner_array_hash, &inner_array_pointer)) {
- if (Z_TYPE_P(*value) != IS_STRING) {
- return false;
- }
- metadata->metadata[metadata->count].key = key;
- metadata->metadata[metadata->count].value = Z_STRVAL_P(*value);
- metadata->metadata[metadata->count].value_length = Z_STRLEN_P(*value);
- metadata->count += 1;
- }
- }
- return true;
-}
-
-#else
-
-static zend_object_handlers call_ce_handlers;
-
-/* Frees and destroys an instance of wrapped_grpc_call */
-static void free_wrapped_grpc_call(zend_object *object) {
- wrapped_grpc_call *call = wrapped_grpc_call_from_obj(object);
- if (call->owned && call->wrapped != NULL) {
- grpc_call_destroy(call->wrapped);
- }
- zend_object_std_dtor(&call->std);
-}
-
-/* Initializes an instance of wrapped_grpc_call to be associated with an
- * object of a class specified by class_type */
-zend_object *create_wrapped_grpc_call(zend_class_entry *class_type) {
- wrapped_grpc_call *intern;
- intern = ecalloc(1, sizeof(wrapped_grpc_call) +
- zend_object_properties_size(class_type));
- zend_object_std_init(&intern->std, class_type);
- object_properties_init(&intern->std, class_type);
- intern->std.handlers = &call_ce_handlers;
- return &intern->std;
-}
-
-/* Wraps a grpc_call struct in a PHP object. Owned indicates whether the
- struct should be destroyed at the end of the object's lifecycle */
-void grpc_php_wrap_call(grpc_call *wrapped, bool owned, zval *call_object) {
- object_init_ex(call_object, grpc_ce_call);
- wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(call_object);
- call->wrapped = wrapped;
- call->owned = owned;
-}
-
-/* Creates and returns a PHP array object with the data in a
- * grpc_metadata_array. Returns NULL on failure */
-void grpc_parse_metadata_array(grpc_metadata_array *metadata_array,
- zval *array) {
- int count = metadata_array->count;
- grpc_metadata *elements = metadata_array->metadata;
- int i;
- zval *data;
- HashTable *array_hash;
- zval inner_array;
- char *str_key;
- char *str_val;
- size_t key_len;
-
- array_init(array);
- array_hash = HASH_OF(array);
- grpc_metadata *elem;
- for (i = 0; i < count; i++) {
- elem = &elements[i];
- key_len = strlen(elem->key);
- str_key = ecalloc(key_len + 1, sizeof(char));
- memcpy(str_key, elem->key, key_len);
- str_val = ecalloc(elem->value_length + 1, sizeof(char));
- memcpy(str_val, elem->value, elem->value_length);
- if ((data = zend_hash_str_find(array_hash, str_key, key_len)) != NULL) {
- if (Z_TYPE_P(data) != IS_ARRAY) {
- zend_throw_exception(zend_exception_get_default(),
- "Metadata hash somehow contains wrong types.",
- 1);
- efree(str_key);
- efree(str_val);
- return;
- }
- add_next_index_stringl(data, str_val, elem->value_length);
- } else {
- array_init(&inner_array);
- add_next_index_stringl(&inner_array, str_val, elem->value_length);
- add_assoc_zval(array, str_key, &inner_array);
- }
- }
-}
-
-/* Populates a grpc_metadata_array with the data in a PHP array object.
- Returns true on success and false on failure */
-bool create_metadata_array(zval *array, grpc_metadata_array *metadata) {
- zval *inner_array;
zval *value;
- HashTable *array_hash;
- HashTable *inner_array_hash;
- zend_string *key;
+ zval *inner_array;
if (Z_TYPE_P(array) != IS_ARRAY) {
return false;
}
grpc_metadata_array_init(metadata);
- array_hash = HASH_OF(array);
+ array_hash = Z_ARRVAL_P(array);
- ZEND_HASH_FOREACH_STR_KEY_VAL(array_hash, key, inner_array) {
- if (key == NULL) {
+ char *key;
+ int key_type;
+ PHP_GRPC_HASH_FOREACH_STR_KEY_VAL_START(array_hash, key, key_type,
+ inner_array)
+ if (key_type != HASH_KEY_IS_STRING || key == NULL) {
return false;
}
if (Z_TYPE_P(inner_array) != IS_ARRAY) {
return false;
}
- inner_array_hash = HASH_OF(inner_array);
+ inner_array_hash = Z_ARRVAL_P(inner_array);
metadata->capacity += zend_hash_num_elements(inner_array_hash);
- }
- ZEND_HASH_FOREACH_END();
+ PHP_GRPC_HASH_FOREACH_END()
metadata->metadata = gpr_malloc(metadata->capacity * sizeof(grpc_metadata));
- ZEND_HASH_FOREACH_STR_KEY_VAL(array_hash, key, inner_array) {
- if (key == NULL) {
+ char *key1 = NULL;
+ int key_type1;
+ PHP_GRPC_HASH_FOREACH_STR_KEY_VAL_START(array_hash, key1, key_type1,
+ inner_array)
+ if (key_type1 != HASH_KEY_IS_STRING) {
return false;
}
- inner_array_hash = HASH_OF(inner_array);
-
- ZEND_HASH_FOREACH_VAL(inner_array_hash, value) {
+ inner_array_hash = Z_ARRVAL_P(inner_array);
+ PHP_GRPC_HASH_FOREACH_VAL_START(inner_array_hash, value)
if (Z_TYPE_P(value) != IS_STRING) {
return false;
}
- metadata->metadata[metadata->count].key = ZSTR_VAL(key);
+ metadata->metadata[metadata->count].key = key1;
metadata->metadata[metadata->count].value = Z_STRVAL_P(value);
metadata->metadata[metadata->count].value_length = Z_STRLEN_P(value);
metadata->count += 1;
- } ZEND_HASH_FOREACH_END();
- } ZEND_HASH_FOREACH_END();
+ PHP_GRPC_HASH_FOREACH_END()
+ PHP_GRPC_HASH_FOREACH_END()
return true;
}
-#endif
+/* Wraps a grpc_call struct in a PHP object. Owned indicates whether the
+ struct should be destroyed at the end of the object's lifecycle */
+zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned TSRMLS_DC) {
+ zval *call_object;
+ PHP_GRPC_MAKE_STD_ZVAL(call_object);
+ object_init_ex(call_object, grpc_ce_call);
+ wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(call_object);
+ call->wrapped = wrapped;
+ call->owned = owned;
+ return call_object;
+}
/**
* Constructs a new instance of the Call class.
@@ -379,29 +238,17 @@ PHP_METHOD(Call, __construct) {
* @return object Object with results of all actions
*/
PHP_METHOD(Call, startBatch) {
-#if PHP_MAJOR_VERSION < 7
- zval **value;
- zval **inner_value;
- HashPosition array_pointer;
- zval **message_value;
- zval **message_flags;
- char *key;
- uint key_len;
- ulong index;
zval *result;
- zval *recv_status;
- MAKE_STD_ZVAL(result);
+ PHP_GRPC_MAKE_STD_ZVAL(result);
object_init(result);
-#else
+ php_grpc_ulong index;
+ zval *recv_status;
+ PHP_GRPC_MAKE_STD_ZVAL(recv_status);
+ object_init(recv_status);
zval *value;
zval *inner_value;
zval *message_value;
zval *message_flags;
- zend_string *key;
- zend_ulong index;
- zval recv_status;
- object_init(return_value);
-#endif
wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis());
grpc_op ops[8];
@@ -424,7 +271,6 @@ PHP_METHOD(Call, startBatch) {
char *message_str;
size_t message_len;
-
grpc_metadata_array_init(&metadata);
grpc_metadata_array_init(&trailing_metadata);
grpc_metadata_array_init(&recv_metadata);
@@ -439,67 +285,63 @@ PHP_METHOD(Call, startBatch) {
goto cleanup;
}
-#if PHP_MAJOR_VERSION < 7
-
array_hash = Z_ARRVAL_P(array);
- for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer);
- zend_hash_get_current_data_ex(array_hash, (void**)&value,
- &array_pointer) == SUCCESS;
- zend_hash_move_forward_ex(array_hash, &array_pointer)) {
- if (zend_hash_get_current_key_ex(array_hash, &key, &key_len, &index, 0,
- &array_pointer) != HASH_KEY_IS_LONG) {
+
+ char *key = NULL;
+ int key_type;
+ PHP_GRPC_HASH_FOREACH_LONG_KEY_VAL_START(array_hash, key, key_type, index,
+ value)
+ if (key_type != HASH_KEY_IS_LONG || key != NULL) {
zend_throw_exception(spl_ce_InvalidArgumentException,
"batch keys must be integers", 1 TSRMLS_CC);
goto cleanup;
}
switch(index) {
case GRPC_OP_SEND_INITIAL_METADATA:
- if (!create_metadata_array(*value, &metadata)) {
+ if (!create_metadata_array(value, &metadata)) {
zend_throw_exception(spl_ce_InvalidArgumentException,
"Bad metadata value given", 1 TSRMLS_CC);
goto cleanup;
}
- ops[op_num].data.send_initial_metadata.count =
- metadata.count;
- ops[op_num].data.send_initial_metadata.metadata =
- metadata.metadata;
+ ops[op_num].data.send_initial_metadata.count = metadata.count;
+ ops[op_num].data.send_initial_metadata.metadata = metadata.metadata;
break;
case GRPC_OP_SEND_MESSAGE:
- if (Z_TYPE_PP(value) != IS_ARRAY) {
+ if (Z_TYPE_P(value) != IS_ARRAY) {
zend_throw_exception(spl_ce_InvalidArgumentException,
"Expected an array for send message",
1 TSRMLS_CC);
goto cleanup;
}
- message_hash = Z_ARRVAL_PP(value);
- if (zend_hash_find(message_hash, "flags", sizeof("flags"),
+ message_hash = Z_ARRVAL_P(value);
+ if (php_grpc_zend_hash_find(message_hash, "flags", sizeof("flags"),
(void **)&message_flags) == SUCCESS) {
- if (Z_TYPE_PP(message_flags) != IS_LONG) {
+ if (Z_TYPE_P(message_flags) != IS_LONG) {
zend_throw_exception(spl_ce_InvalidArgumentException,
"Expected an int for message flags",
1 TSRMLS_CC);
}
- ops[op_num].flags = Z_LVAL_PP(message_flags) & GRPC_WRITE_USED_MASK;
+ ops[op_num].flags = Z_LVAL_P(message_flags) & GRPC_WRITE_USED_MASK;
}
- if (zend_hash_find(message_hash, "message", sizeof("message"),
+ if (php_grpc_zend_hash_find(message_hash, "message", sizeof("message"),
(void **)&message_value) != SUCCESS ||
- Z_TYPE_PP(message_value) != IS_STRING) {
+ Z_TYPE_P(message_value) != IS_STRING) {
zend_throw_exception(spl_ce_InvalidArgumentException,
"Expected a string for send message",
1 TSRMLS_CC);
goto cleanup;
}
ops[op_num].data.send_message =
- string_to_byte_buffer(Z_STRVAL_PP(message_value),
- Z_STRLEN_PP(message_value));
+ string_to_byte_buffer(Z_STRVAL_P(message_value),
+ Z_STRLEN_P(message_value));
break;
case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
break;
case GRPC_OP_SEND_STATUS_FROM_SERVER:
- status_hash = Z_ARRVAL_PP(value);
- if (zend_hash_find(status_hash, "metadata", sizeof("metadata"),
+ status_hash = Z_ARRVAL_P(value);
+ if (php_grpc_zend_hash_find(status_hash, "metadata", sizeof("metadata"),
(void **)&inner_value) == SUCCESS) {
- if (!create_metadata_array(*inner_value, &trailing_metadata)) {
+ if (!create_metadata_array(inner_value, &trailing_metadata)) {
zend_throw_exception(spl_ce_InvalidArgumentException,
"Bad trailing metadata value given",
1 TSRMLS_CC);
@@ -510,32 +352,32 @@ PHP_METHOD(Call, startBatch) {
ops[op_num].data.send_status_from_server.trailing_metadata_count =
trailing_metadata.count;
}
- if (zend_hash_find(status_hash, "code", sizeof("code"),
+ if (php_grpc_zend_hash_find(status_hash, "code", sizeof("code"),
(void**)&inner_value) == SUCCESS) {
- if (Z_TYPE_PP(inner_value) != IS_LONG) {
+ if (Z_TYPE_P(inner_value) != IS_LONG) {
zend_throw_exception(spl_ce_InvalidArgumentException,
"Status code must be an integer",
1 TSRMLS_CC);
goto cleanup;
}
ops[op_num].data.send_status_from_server.status =
- Z_LVAL_PP(inner_value);
+ Z_LVAL_P(inner_value);
} else {
zend_throw_exception(spl_ce_InvalidArgumentException,
"Integer status code is required",
1 TSRMLS_CC);
goto cleanup;
}
- if (zend_hash_find(status_hash, "details", sizeof("details"),
+ if (php_grpc_zend_hash_find(status_hash, "details", sizeof("details"),
(void**)&inner_value) == SUCCESS) {
- if (Z_TYPE_PP(inner_value) != IS_STRING) {
+ if (Z_TYPE_P(inner_value) != IS_STRING) {
zend_throw_exception(spl_ce_InvalidArgumentException,
"Status details must be a string",
1 TSRMLS_CC);
goto cleanup;
}
ops[op_num].data.send_status_from_server.status_details =
- Z_STRVAL_PP(inner_value);
+ Z_STRVAL_P(inner_value);
} else {
zend_throw_exception(spl_ce_InvalidArgumentException,
"String status details is required",
@@ -570,132 +412,7 @@ PHP_METHOD(Call, startBatch) {
ops[op_num].flags = 0;
ops[op_num].reserved = NULL;
op_num++;
- }
-
-#else
-
-array_hash = HASH_OF(array);
- ZEND_HASH_FOREACH_KEY_VAL(array_hash, index, key, value) {
- if (key) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "batch keys must be integers", 1);
- goto cleanup;
- }
-
- switch(index) {
- case GRPC_OP_SEND_INITIAL_METADATA:
- if (!create_metadata_array(value, &metadata)) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "Bad metadata value given", 1);
- goto cleanup;
- }
- ops[op_num].data.send_initial_metadata.count = metadata.count;
- ops[op_num].data.send_initial_metadata.metadata = metadata.metadata;
- break;
- case GRPC_OP_SEND_MESSAGE:
- if (Z_TYPE_P(value) != IS_ARRAY) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "Expected an array for send message", 1);
- goto cleanup;
- }
- message_hash = HASH_OF(value);
- if ((message_flags =
- zend_hash_str_find(message_hash, "flags",
- sizeof("flags") - 1)) != NULL) {
- if (Z_TYPE_P(message_flags) != IS_LONG) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "Expected an int for message flags", 1);
- }
- ops[op_num].flags = Z_LVAL_P(message_flags) & GRPC_WRITE_USED_MASK;
- }
- if ((message_value = zend_hash_str_find(message_hash, "message",
- sizeof("message") - 1))
- == NULL || Z_TYPE_P(message_value) != IS_STRING) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "Expected a string for send message", 1);
- goto cleanup;
- }
- ops[op_num].data.send_message =
- string_to_byte_buffer(Z_STRVAL_P(message_value),
- Z_STRLEN_P(message_value));
- break;
- case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
- break;
- case GRPC_OP_SEND_STATUS_FROM_SERVER:
- status_hash = HASH_OF(value);
- if ((inner_value = zend_hash_str_find(status_hash, "metadata",
- sizeof("metadata") - 1))
- != NULL) {
- if (!create_metadata_array(inner_value, &trailing_metadata)) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "Bad trailing metadata value given", 1);
- goto cleanup;
- }
- ops[op_num].data.send_status_from_server.trailing_metadata =
- trailing_metadata.metadata;
- ops[op_num].data.send_status_from_server.trailing_metadata_count =
- trailing_metadata.count;
- }
- if ((inner_value = zend_hash_str_find(status_hash, "code",
- sizeof("code") - 1)) != NULL) {
- if (Z_TYPE_P(inner_value) != IS_LONG) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "Status code must be an integer", 1);
- goto cleanup;
- }
- ops[op_num].data.send_status_from_server.status =
- Z_LVAL_P(inner_value);
- } else {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "Integer status code is required", 1);
- goto cleanup;
- }
- if ((inner_value = zend_hash_str_find(status_hash, "details",
- sizeof("details") - 1)) != NULL) {
- if (Z_TYPE_P(inner_value) != IS_STRING) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "Status details must be a string", 1);
- goto cleanup;
- }
- ops[op_num].data.send_status_from_server.status_details =
- Z_STRVAL_P(inner_value);
- } else {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "String status details is required", 1);
- goto cleanup;
- }
- break;
- case GRPC_OP_RECV_INITIAL_METADATA:
- ops[op_num].data.recv_initial_metadata = &recv_metadata;
- break;
- case GRPC_OP_RECV_MESSAGE:
- ops[op_num].data.recv_message = &message;
- break;
- case GRPC_OP_RECV_STATUS_ON_CLIENT:
- ops[op_num].data.recv_status_on_client.trailing_metadata =
- &recv_trailing_metadata;
- ops[op_num].data.recv_status_on_client.status = &status;
- ops[op_num].data.recv_status_on_client.status_details =
- &status_details;
- ops[op_num].data.recv_status_on_client.status_details_capacity =
- &status_details_capacity;
- break;
- case GRPC_OP_RECV_CLOSE_ON_SERVER:
- ops[op_num].data.recv_close_on_server.cancelled = &cancelled;
- break;
- default:
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "Unrecognized key in batch", 1);
- goto cleanup;
- }
- ops[op_num].op = (grpc_op_type)index;
- ops[op_num].flags = 0;
- ops[op_num].reserved = NULL;
- op_num++;
- }
- ZEND_HASH_FOREACH_END();
-
-#endif
+ PHP_GRPC_HASH_FOREACH_END()
error = grpc_call_start_batch(call->wrapped, ops, op_num, call->wrapped,
NULL);
@@ -707,7 +424,9 @@ array_hash = HASH_OF(array);
}
grpc_completion_queue_pluck(completion_queue, call->wrapped,
gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
-#if PHP_MAJOR_VERSION < 7
+#if PHP_MAJOR_VERSION >= 7
+ zval recv_md;
+#endif
for (int i = 0; i < op_num; i++) {
switch(ops[i].op) {
case GRPC_OP_SEND_INITIAL_METADATA:
@@ -723,29 +442,38 @@ array_hash = HASH_OF(array);
add_property_bool(result, "send_status", true);
break;
case GRPC_OP_RECV_INITIAL_METADATA:
+#if PHP_MAJOR_VERSION < 7
array = grpc_parse_metadata_array(&recv_metadata TSRMLS_CC);
add_property_zval(result, "metadata", array);
- Z_DELREF_P(array);
+#else
+ recv_md = *grpc_parse_metadata_array(&recv_metadata);
+ add_property_zval(result, "metadata", &recv_md);
+#endif
+ PHP_GRPC_DELREF(array);
break;
case GRPC_OP_RECV_MESSAGE:
byte_buffer_to_string(message, &message_str, &message_len);
if (message_str == NULL) {
add_property_null(result, "message");
} else {
- add_property_stringl(result, "message", message_str, message_len,
- false);
+ php_grpc_add_property_stringl(result, "message", message_str,
+ message_len, false);
}
break;
case GRPC_OP_RECV_STATUS_ON_CLIENT:
- MAKE_STD_ZVAL(recv_status);
- object_init(recv_status);
+#if PHP_MAJOR_VERSION < 7
array = grpc_parse_metadata_array(&recv_trailing_metadata TSRMLS_CC);
add_property_zval(recv_status, "metadata", array);
- Z_DELREF_P(array);
+#else
+ recv_md = *grpc_parse_metadata_array(&recv_trailing_metadata);
+ add_property_zval(recv_status, "metadata", &recv_md);
+#endif
+ PHP_GRPC_DELREF(array);
add_property_long(recv_status, "code", status);
- add_property_string(recv_status, "details", status_details, true);
+ php_grpc_add_property_string(recv_status, "details", status_details,
+ true);
add_property_zval(result, "status", recv_status);
- Z_DELREF_P(recv_status);
+ PHP_GRPC_DELREF(recv_status);
break;
case GRPC_OP_RECV_CLOSE_ON_SERVER:
add_property_bool(result, "cancelled", cancelled);
@@ -754,50 +482,6 @@ array_hash = HASH_OF(array);
break;
}
}
-#else
- for (int i = 0; i < op_num; i++) {
- switch(ops[i].op) {
- case GRPC_OP_SEND_INITIAL_METADATA:
- add_property_bool(return_value, "send_metadata", true);
- break;
- case GRPC_OP_SEND_MESSAGE:
- add_property_bool(return_value, "send_message", true);
- break;
- case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
- add_property_bool(return_value, "send_close", true);
- break;
- case GRPC_OP_SEND_STATUS_FROM_SERVER:
- add_property_bool(return_value, "send_status", true);
- break;
- case GRPC_OP_RECV_INITIAL_METADATA:
- grpc_parse_metadata_array(&recv_metadata, array);
- add_property_zval(return_value, "metadata", array);
- break;
- case GRPC_OP_RECV_MESSAGE:
- byte_buffer_to_string(message, &message_str, &message_len);
- if (message_str == NULL) {
- add_property_null(return_value, "message");
- } else {
- add_property_stringl(return_value, "message", message_str,
- message_len);
- }
- break;
- case GRPC_OP_RECV_STATUS_ON_CLIENT:
- object_init(&recv_status);
- grpc_parse_metadata_array(&recv_trailing_metadata, array);
- add_property_zval(&recv_status, "metadata", array);
- add_property_long(&recv_status, "code", status);
- add_property_string(&recv_status, "details", status_details);
- add_property_zval(return_value, "status", &recv_status);
- break;
- case GRPC_OP_RECV_CLOSE_ON_SERVER:
- add_property_bool(return_value, "cancelled", cancelled);
- break;
- default:
- break;
- }
- }
-#endif
cleanup:
grpc_metadata_array_destroy(&metadata);
@@ -815,11 +499,7 @@ cleanup:
grpc_byte_buffer_destroy(message);
}
}
-#if PHP_MAJOR_VERSION < 7
RETURN_DESTROY_ZVAL(result);
-#else
- RETURN_DESTROY_ZVAL(return_value);
-#endif
}
/**
@@ -880,10 +560,5 @@ void grpc_init_call(TSRMLS_D) {
INIT_CLASS_ENTRY(ce, "Grpc\\Call", call_methods);
ce.create_object = create_wrapped_grpc_call;
grpc_ce_call = zend_register_internal_class(&ce TSRMLS_CC);
-#if PHP_MAJOR_VERSION >= 7
- memcpy(&call_ce_handlers, zend_get_std_object_handlers(),
- sizeof(zend_object_handlers));
- call_ce_handlers.offset = XtOffsetOf(wrapped_grpc_call, std);
- call_ce_handlers.free_obj = free_wrapped_grpc_call;
-#endif
+ PHP_GRPC_INIT_HANDLER(wrapped_grpc_call, call_ce_handlers);
}
diff --git a/src/php/ext/grpc/call.h b/src/php/ext/grpc/call.h
index 4931bf392e..e49f9b382a 100644
--- a/src/php/ext/grpc/call.h
+++ b/src/php/ext/grpc/call.h
@@ -48,34 +48,19 @@
/* Class entry for the Call PHP class */
extern zend_class_entry *grpc_ce_call;
-#if PHP_MAJOR_VERSION < 7
-
/* Wrapper struct for grpc_call that can be associated with a PHP object */
-typedef struct wrapped_grpc_call {
- zend_object std;
+PHP_GRPC_WRAP_OBJECT_START(wrapped_grpc_call)
bool owned;
grpc_call *wrapped;
-} wrapped_grpc_call;
-
-/* Creates a Call object that wraps the given grpc_call struct */
-zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned TSRMLS_DC);
+PHP_GRPC_WRAP_OBJECT_END(wrapped_grpc_call)
-/* Creates and returns a PHP associative array of metadata from a C array of
- * call metadata */
-zval *grpc_parse_metadata_array(grpc_metadata_array *metadata_array TSRMLS_DC);
+#if PHP_MAJOR_VERSION < 7
#define Z_WRAPPED_GRPC_CALL_P(zv) \
(wrapped_grpc_call *)zend_object_store_get_object(zv TSRMLS_CC)
#else
-/* Wrapper struct for grpc_call that can be associated with a PHP object */
-typedef struct wrapped_grpc_call {
- bool owned;
- grpc_call *wrapped;
- zend_object std;
-} wrapped_grpc_call;
-
static inline wrapped_grpc_call
*wrapped_grpc_call_from_obj(zend_object *obj) {
return (wrapped_grpc_call*)((char*)(obj) -
@@ -84,15 +69,14 @@ static inline wrapped_grpc_call
#define Z_WRAPPED_GRPC_CALL_P(zv) wrapped_grpc_call_from_obj(Z_OBJ_P((zv)))
-/* Creates a Call object that wraps the given grpc_call struct */
-void grpc_php_wrap_call(grpc_call *wrapped, bool owned, zval *call_object);
+#endif /* PHP_MAJOR_VERSION */
/* Creates and returns a PHP associative array of metadata from a C array of
* call metadata */
-void grpc_parse_metadata_array(grpc_metadata_array *metadata_array,
- zval *array);
+zval *grpc_parse_metadata_array(grpc_metadata_array *metadata_array TSRMLS_DC);
-#endif /* PHP_MAJOR_VERSION */
+/* Creates a Call object that wraps the given grpc_call struct */
+zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned TSRMLS_DC);
/* Initializes the Call PHP class */
void grpc_init_call(TSRMLS_D);
diff --git a/src/php/ext/grpc/call_credentials.c b/src/php/ext/grpc/call_credentials.c
index 24ee0a465e..6921a5df17 100644
--- a/src/php/ext/grpc/call_credentials.c
+++ b/src/php/ext/grpc/call_credentials.c
@@ -52,88 +52,39 @@
#include <grpc/grpc_security.h>
zend_class_entry *grpc_ce_call_credentials;
-
-#if PHP_MAJOR_VERSION < 7
+#if PHP_MAJOR_VERSION >= 7
+static zend_object_handlers call_credentials_ce_handlers;
+#endif
/* Frees and destroys an instance of wrapped_grpc_call_credentials */
-void free_wrapped_grpc_call_credentials(void *object TSRMLS_DC) {
- wrapped_grpc_call_credentials *creds =
- (wrapped_grpc_call_credentials *)object;
- if (creds->wrapped != NULL) {
- grpc_call_credentials_release(creds->wrapped);
+PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_call_credentials)
+ if (p->wrapped != NULL) {
+ grpc_call_credentials_release(p->wrapped);
}
- zend_object_std_dtor(&creds->std TSRMLS_CC);
- efree(creds);
-}
+PHP_GRPC_FREE_WRAPPED_FUNC_END()
/* Initializes an instance of wrapped_grpc_call_credentials to be
* associated with an object of a class specified by class_type */
-zend_object_value create_wrapped_grpc_call_credentials(
+php_grpc_zend_object create_wrapped_grpc_call_credentials(
zend_class_entry *class_type TSRMLS_DC) {
- zend_object_value retval;
- wrapped_grpc_call_credentials *intern;
-
- intern = (wrapped_grpc_call_credentials *)emalloc(
- sizeof(wrapped_grpc_call_credentials));
- memset(intern, 0, sizeof(wrapped_grpc_call_credentials));
-
+ PHP_GRPC_ALLOC_CLASS_OBJECT(wrapped_grpc_call_credentials);
zend_object_std_init(&intern->std, class_type TSRMLS_CC);
object_properties_init(&intern->std, class_type);
- retval.handle = zend_objects_store_put(
- intern, (zend_objects_store_dtor_t)zend_objects_destroy_object,
- free_wrapped_grpc_call_credentials, NULL TSRMLS_CC);
- retval.handlers = zend_get_std_object_handlers();
- return retval;
+ PHP_GRPC_FREE_CLASS_OBJECT(wrapped_grpc_call_credentials,
+ call_credentials_ce_handlers);
}
-zval *grpc_php_wrap_call_credentials(grpc_call_credentials *wrapped TSRMLS_DC) {
+zval *grpc_php_wrap_call_credentials(grpc_call_credentials
+ *wrapped TSRMLS_DC) {
zval *credentials_object;
- MAKE_STD_ZVAL(credentials_object);
- object_init_ex(credentials_object, grpc_ce_call_credentials);
- wrapped_grpc_call_credentials *credentials =
- (wrapped_grpc_call_credentials *)zend_object_store_get_object(
- credentials_object TSRMLS_CC);
- credentials->wrapped = wrapped;
- return credentials_object;
-}
-
-#else
-
-static zend_object_handlers call_credentials_ce_handlers;
-
-/* Frees and destroys an instance of wrapped_grpc_call_credentials */
-static void free_wrapped_grpc_call_credentials(zend_object *object) {
- wrapped_grpc_call_credentials *creds =
- wrapped_grpc_call_creds_from_obj(object);
- if (creds->wrapped != NULL) {
- grpc_call_credentials_release(creds->wrapped);
- }
- zend_object_std_dtor(&creds->std);
-}
-
-/* Initializes an instance of wrapped_grpc_call_credentials to be
- * associated with an object of a class specified by class_type */
-zend_object *create_wrapped_grpc_call_credentials(zend_class_entry
- *class_type) {
- wrapped_grpc_call_credentials *intern;
- intern = ecalloc(1, sizeof(wrapped_grpc_call_credentials) +
- zend_object_properties_size(class_type));
- zend_object_std_init(&intern->std, class_type);
- object_properties_init(&intern->std, class_type);
- intern->std.handlers = &call_credentials_ce_handlers;
- return &intern->std;
-}
-
-void grpc_php_wrap_call_credentials(grpc_call_credentials *wrapped,
- zval *credentials_object) {
+ PHP_GRPC_MAKE_STD_ZVAL(credentials_object);
object_init_ex(credentials_object, grpc_ce_call_credentials);
wrapped_grpc_call_credentials *credentials =
Z_WRAPPED_GRPC_CALL_CREDS_P(credentials_object);
credentials->wrapped = wrapped;
+ return credentials_object;
}
-#endif
-
/**
* Create composite credentials from two existing credentials.
* @param CallCredentials cred1 The first credential
@@ -160,13 +111,10 @@ PHP_METHOD(CallCredentials, createComposite) {
grpc_call_credentials *creds =
grpc_composite_call_credentials_create(cred1->wrapped, cred2->wrapped,
NULL);
-#if PHP_MAJOR_VERSION < 7
- zval *creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC);
+ zval *creds_object;
+ PHP_GRPC_MAKE_STD_ZVAL(creds_object);
+ creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC);
RETURN_DESTROY_ZVAL(creds_object);
-#else
- grpc_php_wrap_call_credentials(creds, return_value);
- RETURN_DESTROY_ZVAL(return_value);
-#endif
}
/**
@@ -207,13 +155,10 @@ PHP_METHOD(CallCredentials, createFromPlugin) {
grpc_call_credentials *creds =
grpc_metadata_credentials_create_from_plugin(plugin, NULL);
-#if PHP_MAJOR_VERSION < 7
- zval *creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC);
+ zval *creds_object;
+ PHP_GRPC_MAKE_STD_ZVAL(creds_object);
+ creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC);
RETURN_DESTROY_ZVAL(creds_object);
-#else
- grpc_php_wrap_call_credentials(creds, return_value);
- RETURN_DESTROY_ZVAL(return_value);
-#endif
}
/* Callback function for plugin creds API */
@@ -226,37 +171,28 @@ void plugin_get_metadata(void *ptr, grpc_auth_metadata_context context,
/* prepare to call the user callback function with info from the
* grpc_auth_metadata_context */
-#if PHP_MAJOR_VERSION < 7
- zval **params[1];
zval *arg;
- zval *retval;
- MAKE_STD_ZVAL(arg);
+ PHP_GRPC_MAKE_STD_ZVAL(arg);
object_init(arg);
- add_property_string(arg, "service_url", context.service_url, true);
- add_property_string(arg, "method_name", context.method_name, true);
+ php_grpc_add_property_string(arg, "service_url", context.service_url, true);
+ php_grpc_add_property_string(arg, "method_name", context.method_name, true);
+ zval *retval;
+ PHP_GRPC_MAKE_STD_ZVAL(retval);
+#if PHP_MAJOR_VERSION < 7
+ zval **params[1];
params[0] = &arg;
- state->fci->param_count = 1;
state->fci->params = params;
state->fci->retval_ptr_ptr = &retval;
#else
- zval arg;
- zval retval;
- object_init(&arg);
- add_property_string(&arg, "service_url", context.service_url);
- add_property_string(&arg, "method_name", context.method_name);
- state->fci->param_count = 1;
- state->fci->params = &arg;
- state->fci->retval = &retval;
+ state->fci->params = arg;
+ state->fci->retval = retval;
#endif
+ state->fci->param_count = 1;
/* call the user callback function */
zend_call_function(state->fci, state->fci_cache TSRMLS_CC);
-#if PHP_MAJOR_VERSION < 7
if (Z_TYPE_P(retval) != IS_ARRAY) {
-#else
- if (Z_TYPE_P(&retval) != IS_ARRAY) {
-#endif
zend_throw_exception(spl_ce_InvalidArgumentException,
"plugin callback must return metadata array",
1 TSRMLS_CC);
@@ -264,11 +200,7 @@ void plugin_get_metadata(void *ptr, grpc_auth_metadata_context context,
}
grpc_metadata_array metadata;
-#if PHP_MAJOR_VERSION < 7
if (!create_metadata_array(retval, &metadata)) {
-#else
- if (!create_metadata_array(&retval, &metadata)) {
-#endif
zend_throw_exception(spl_ce_InvalidArgumentException,
"invalid metadata", 1 TSRMLS_CC);
grpc_metadata_array_destroy(&metadata);
@@ -303,13 +235,6 @@ void grpc_init_call_credentials(TSRMLS_D) {
INIT_CLASS_ENTRY(ce, "Grpc\\CallCredentials", call_credentials_methods);
ce.create_object = create_wrapped_grpc_call_credentials;
grpc_ce_call_credentials = zend_register_internal_class(&ce TSRMLS_CC);
-#if PHP_MAJOR_VERSION >= 7
- memcpy(&call_credentials_ce_handlers,
- zend_get_std_object_handlers(),
- sizeof(zend_object_handlers));
- call_credentials_ce_handlers.offset =
- XtOffsetOf(wrapped_grpc_call_credentials, std);
- call_credentials_ce_handlers.free_obj =
- free_wrapped_grpc_call_credentials;
-#endif
+ PHP_GRPC_INIT_HANDLER(wrapped_grpc_call_credentials,
+ call_credentials_ce_handlers);
}
diff --git a/src/php/ext/grpc/call_credentials.h b/src/php/ext/grpc/call_credentials.h
index e9688288de..c1d85c0fb2 100755
--- a/src/php/ext/grpc/call_credentials.h
+++ b/src/php/ext/grpc/call_credentials.h
@@ -49,36 +49,27 @@
/* Class entry for the CallCredentials PHP class */
extern zend_class_entry *grpc_ce_call_credentials;
-#if PHP_MAJOR_VERSION < 7
-
/* Wrapper struct for grpc_call_credentials that can be associated
* with a PHP object */
-typedef struct wrapped_grpc_call_credentials {
- zend_object std;
+PHP_GRPC_WRAP_OBJECT_START(wrapped_grpc_call_credentials)
grpc_call_credentials *wrapped;
-} wrapped_grpc_call_credentials;
+PHP_GRPC_WRAP_OBJECT_END(wrapped_grpc_call_credentials)
+
+#if PHP_MAJOR_VERSION < 7
#define Z_WRAPPED_GRPC_CALL_CREDS_P(zv) \
(wrapped_grpc_call_credentials *)zend_object_store_get_object(zv TSRMLS_CC)
-#else
-/* Wrapper struct for grpc_call_credentials that can be associated
- * with a PHP object */
-typedef struct wrapped_grpc_call_credentials {
- grpc_call_credentials *wrapped;
- zend_object std;
-} wrapped_grpc_call_credentials;
+#else
static inline wrapped_grpc_call_credentials
-*wrapped_grpc_call_creds_from_obj(zend_object *obj) {
- return
- (wrapped_grpc_call_credentials*)((char*)(obj) -
- XtOffsetOf(wrapped_grpc_call_credentials,
- std));
+*wrapped_grpc_call_credentials_from_obj(zend_object *obj) {
+ return (wrapped_grpc_call_credentials*)(
+ (char*)(obj) - XtOffsetOf(wrapped_grpc_call_credentials, std));
}
-#define Z_WRAPPED_GRPC_CALL_CREDS_P(zv) \
- wrapped_grpc_call_creds_from_obj(Z_OBJ_P((zv)))
+#define Z_WRAPPED_GRPC_CALL_CREDS_P(zv) \
+ wrapped_grpc_call_credentials_from_obj(Z_OBJ_P((zv)))
#endif /* PHP_MAJOR_VERSION */
diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c
index 085a51b560..b5a2c9f6ba 100644
--- a/src/php/ext/grpc/channel.c
+++ b/src/php/ext/grpc/channel.c
@@ -56,123 +56,52 @@
#include "timeval.h"
zend_class_entry *grpc_ce_channel;
-
-#if PHP_MAJOR_VERSION < 7
+#if PHP_MAJOR_VERSION >= 7
+static zend_object_handlers channel_ce_handlers;
+#endif
/* Frees and destroys an instance of wrapped_grpc_channel */
-void free_wrapped_grpc_channel(void *object TSRMLS_DC) {
- wrapped_grpc_channel *channel = (wrapped_grpc_channel *)object;
- if (channel->wrapped != NULL) {
- grpc_channel_destroy(channel->wrapped);
+PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_channel)
+ if (p->wrapped != NULL) {
+ grpc_channel_destroy(p->wrapped);
}
- zend_object_std_dtor(&channel->std TSRMLS_CC);
- efree(channel);
-}
+PHP_GRPC_FREE_WRAPPED_FUNC_END()
/* Initializes an instance of wrapped_grpc_channel to be associated with an
* object of a class specified by class_type */
-zend_object_value create_wrapped_grpc_channel(zend_class_entry *class_type
- TSRMLS_DC) {
- zend_object_value retval;
- wrapped_grpc_channel *intern;
- intern = (wrapped_grpc_channel *)emalloc(sizeof(wrapped_grpc_channel));
- memset(intern, 0, sizeof(wrapped_grpc_channel));
+php_grpc_zend_object create_wrapped_grpc_channel(zend_class_entry *class_type
+ TSRMLS_DC) {
+ PHP_GRPC_ALLOC_CLASS_OBJECT(wrapped_grpc_channel);
zend_object_std_init(&intern->std, class_type TSRMLS_CC);
object_properties_init(&intern->std, class_type);
- retval.handle = zend_objects_store_put(
- intern, (zend_objects_store_dtor_t)zend_objects_destroy_object,
- free_wrapped_grpc_channel, NULL TSRMLS_CC);
- retval.handlers = zend_get_std_object_handlers();
- return retval;
+ PHP_GRPC_FREE_CLASS_OBJECT(wrapped_grpc_channel, channel_ce_handlers);
}
void php_grpc_read_args_array(zval *args_array,
grpc_channel_args *args TSRMLS_DC) {
HashTable *array_hash;
- HashPosition array_pointer;
int args_index;
- zval **data;
- char *key;
- uint key_len;
- ulong index;
array_hash = Z_ARRVAL_P(args_array);
- args->num_args = zend_hash_num_elements(array_hash);
- args->args = ecalloc(args->num_args, sizeof(grpc_arg));
- args_index = 0;
- for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer);
- zend_hash_get_current_data_ex(array_hash, (void **)&data,
- &array_pointer) == SUCCESS;
- zend_hash_move_forward_ex(array_hash, &array_pointer)) {
- if (zend_hash_get_current_key_ex(array_hash, &key, &key_len, &index, 0,
- &array_pointer) != HASH_KEY_IS_STRING) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "args keys must be strings", 1 TSRMLS_CC);
- return;
- }
- args->args[args_index].key = key;
- switch (Z_TYPE_P(*data)) {
- case IS_LONG:
- args->args[args_index].value.integer = (int)Z_LVAL_P(*data);
- args->args[args_index].type = GRPC_ARG_INTEGER;
- break;
- case IS_STRING:
- args->args[args_index].value.string = Z_STRVAL_P(*data);
- args->args[args_index].type = GRPC_ARG_STRING;
- break;
- default:
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "args values must be int or string", 1 TSRMLS_CC);
- return;
- }
- args_index++;
- }
-}
-
-#else
-
-static zend_object_handlers channel_ce_handlers;
-
-/* Frees and destroys an instance of wrapped_grpc_channel */
-static void free_wrapped_grpc_channel(zend_object *object) {
- wrapped_grpc_channel *channel = wrapped_grpc_channel_from_obj(object);
- if (channel->wrapped != NULL) {
- grpc_channel_destroy(channel->wrapped);
- }
- zend_object_std_dtor(&channel->std);
-}
-
-/* Initializes an instance of wrapped_grpc_channel to be associated with an
- * object of a class specified by class_type */
-zend_object *create_wrapped_grpc_channel(zend_class_entry *class_type) {
- wrapped_grpc_channel *intern;
- intern = ecalloc(1, sizeof(wrapped_grpc_channel) +
- zend_object_properties_size(class_type));
- zend_object_std_init(&intern->std, class_type);
- object_properties_init(&intern->std, class_type);
- intern->std.handlers = &channel_ce_handlers;
- return &intern->std;
-}
-
-void php_grpc_read_args_array(zval *args_array, grpc_channel_args *args) {
- HashTable *array_hash;
- int args_index;
- zval *data;
- zend_string *key;
- array_hash = HASH_OF(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);
args->args = ecalloc(args->num_args, sizeof(grpc_arg));
args_index = 0;
- ZEND_HASH_FOREACH_STR_KEY_VAL(array_hash, key, data) {
- if (key == NULL) {
+
+ char *key = NULL;
+ zval *data;
+ int key_type;
+
+ PHP_GRPC_HASH_FOREACH_STR_KEY_VAL_START(array_hash, key, key_type, data)
+ if (key_type != HASH_KEY_IS_STRING) {
zend_throw_exception(spl_ce_InvalidArgumentException,
- "args keys must be strings", 1);
+ "args keys must be strings", 1 TSRMLS_CC);
+ return;
}
- args->args[args_index].key = ZSTR_VAL(key);
+ args->args[args_index].key = key;
switch (Z_TYPE_P(data)) {
case IS_LONG:
args->args[args_index].value.integer = (int)Z_LVAL_P(data);
@@ -184,15 +113,13 @@ void php_grpc_read_args_array(zval *args_array, grpc_channel_args *args) {
break;
default:
zend_throw_exception(spl_ce_InvalidArgumentException,
- "args values must be int or string", 1);
+ "args values must be int or string", 1 TSRMLS_CC);
return;
}
args_index++;
- } ZEND_HASH_FOREACH_END();
+ PHP_GRPC_HASH_FOREACH_END()
}
-#endif
-
/**
* Construct an instance of the Channel class. If the $args array contains a
* "credentials" key mapping to a ChannelCredentials object, a secure channel
@@ -202,11 +129,7 @@ void php_grpc_read_args_array(zval *args_array, grpc_channel_args *args) {
*/
PHP_METHOD(Channel, __construct) {
wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis());
-#if PHP_MAJOR_VERSION < 7
- zval **creds_obj = NULL;
-#else
zval *creds_obj = NULL;
-#endif
char *target;
php_grpc_int target_length;
zval *args_array = NULL;
@@ -221,43 +144,23 @@ PHP_METHOD(Channel, __construct) {
"Channel expects a string and an array", 1 TSRMLS_CC);
return;
}
-#if PHP_MAJOR_VERSION < 7
array_hash = Z_ARRVAL_P(args_array);
- if (zend_hash_find(array_hash, "credentials", sizeof("credentials"),
+ if (php_grpc_zend_hash_find(array_hash, "credentials", sizeof("credentials"),
(void **)&creds_obj) == SUCCESS) {
- if (Z_TYPE_P(*creds_obj) == IS_NULL) {
- creds = NULL;
- zend_hash_del(array_hash, "credentials", 12);
- } else if (zend_get_class_entry(*creds_obj TSRMLS_CC) !=
- grpc_ce_channel_credentials) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "credentials must be a ChannelCredentials object",
- 1 TSRMLS_CC);
- return;
- } else {
- creds = (wrapped_grpc_channel_credentials *)zend_object_store_get_object(
- *creds_obj TSRMLS_CC);
- zend_hash_del(array_hash, "credentials", 12);
- }
- }
-#else
- array_hash = HASH_OF(args_array);
- if ((creds_obj = zend_hash_str_find(array_hash, "credentials",
- sizeof("credentials") - 1)) != NULL) {
if (Z_TYPE_P(creds_obj) == IS_NULL) {
creds = NULL;
- zend_hash_str_del(array_hash, "credentials", sizeof("credentials") - 1);
- } else if (Z_OBJ_P(creds_obj)->ce != grpc_ce_channel_credentials) {
+ php_grpc_zend_hash_del(array_hash, "credentials", sizeof("credentials"));
+ } else if (PHP_GRPC_GET_CLASS_ENTRY(creds_obj) !=
+ grpc_ce_channel_credentials) {
zend_throw_exception(spl_ce_InvalidArgumentException,
"credentials must be a ChannelCredentials object",
- 1);
+ 1 TSRMLS_CC);
return;
} else {
creds = Z_WRAPPED_GRPC_CHANNEL_CREDS_P(creds_obj);
- zend_hash_str_del(array_hash, "credentials", sizeof("credentials") - 1);
+ php_grpc_zend_hash_del(array_hash, "credentials", sizeof("credentials"));
}
}
-#endif
php_grpc_read_args_array(args_array, &args TSRMLS_CC);
if (creds == NULL) {
channel->wrapped = grpc_insecure_channel_create(target, &args, NULL);
@@ -313,8 +216,7 @@ PHP_METHOD(Channel, watchConnectivityState) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lO",
&last_state, &deadline_obj, grpc_ce_timeval) == FAILURE) {
zend_throw_exception(spl_ce_InvalidArgumentException,
- "watchConnectivityState expects 1 long 1 timeval",
- 1 TSRMLS_CC);
+ "watchConnectivityState expects 1 long 1 timeval", 1 TSRMLS_CC);
return;
}
@@ -354,11 +256,5 @@ void grpc_init_channel(TSRMLS_D) {
INIT_CLASS_ENTRY(ce, "Grpc\\Channel", channel_methods);
ce.create_object = create_wrapped_grpc_channel;
grpc_ce_channel = zend_register_internal_class(&ce TSRMLS_CC);
-#if PHP_MAJOR_VERSION >= 7
- memcpy(&channel_ce_handlers, zend_get_std_object_handlers(),
- sizeof(zend_object_handlers));
- channel_ce_handlers.offset =
- XtOffsetOf(wrapped_grpc_channel, std);
- channel_ce_handlers.free_obj = free_wrapped_grpc_channel;
-#endif
+ PHP_GRPC_INIT_HANDLER(wrapped_grpc_channel, channel_ce_handlers);
}
diff --git a/src/php/ext/grpc/channel.h b/src/php/ext/grpc/channel.h
index 94c633408e..0b815657d3 100755
--- a/src/php/ext/grpc/channel.h
+++ b/src/php/ext/grpc/channel.h
@@ -48,32 +48,25 @@
/* Class entry for the PHP Channel class */
extern zend_class_entry *grpc_ce_channel;
-#if PHP_MAJOR_VERSION < 7
-
/* Wrapper struct for grpc_channel that can be associated with a PHP object */
-typedef struct wrapped_grpc_channel {
- zend_object std;
+PHP_GRPC_WRAP_OBJECT_START(wrapped_grpc_channel)
grpc_channel *wrapped;
-} wrapped_grpc_channel;
+PHP_GRPC_WRAP_OBJECT_END(wrapped_grpc_channel)
+
+#if PHP_MAJOR_VERSION < 7
#define Z_WRAPPED_GRPC_CHANNEL_P(zv) \
(wrapped_grpc_channel *)zend_object_store_get_object(zv TSRMLS_CC)
#else
-/* Wrapper struct for grpc_channel that can be associated with a PHP object */
-typedef struct wrapped_grpc_channel {
- grpc_channel *wrapped;
- zend_object std;
-} wrapped_grpc_channel;
-
static inline wrapped_grpc_channel
*wrapped_grpc_channel_from_obj(zend_object *obj) {
return (wrapped_grpc_channel*)((char*)(obj) -
XtOffsetOf(wrapped_grpc_channel, std));
}
-#define Z_WRAPPED_GRPC_CHANNEL_P(zv) \
+#define Z_WRAPPED_GRPC_CHANNEL_P(zv) \
wrapped_grpc_channel_from_obj(Z_OBJ_P((zv)))
#endif /* PHP_MAJOR_VERSION */
diff --git a/src/php/ext/grpc/channel_credentials.c b/src/php/ext/grpc/channel_credentials.c
index e255b3004b..0b356aa25f 100644
--- a/src/php/ext/grpc/channel_credentials.c
+++ b/src/php/ext/grpc/channel_credentials.c
@@ -52,6 +52,9 @@
#include <grpc/grpc_security.h>
zend_class_entry *grpc_ce_channel_credentials;
+#if PHP_MAJOR_VERSION >= 7
+static zend_object_handlers channel_credentials_ce_handlers;
+#endif
static char *default_pem_root_certs = NULL;
static grpc_ssl_roots_override_result get_ssl_roots_override(
@@ -63,88 +66,35 @@ static grpc_ssl_roots_override_result get_ssl_roots_override(
return GRPC_SSL_ROOTS_OVERRIDE_OK;
}
-#if PHP_MAJOR_VERSION < 7
-
/* Frees and destroys an instance of wrapped_grpc_channel_credentials */
-void free_wrapped_grpc_channel_credentials(void *object TSRMLS_DC) {
- wrapped_grpc_channel_credentials *creds =
- (wrapped_grpc_channel_credentials *)object;
- if (creds->wrapped != NULL) {
- grpc_channel_credentials_release(creds->wrapped);
+PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_channel_credentials)
+ if (p->wrapped != NULL) {
+ grpc_channel_credentials_release(p->wrapped);
}
- zend_object_std_dtor(&creds->std TSRMLS_CC);
- efree(creds);
-}
+PHP_GRPC_FREE_WRAPPED_FUNC_END()
/* Initializes an instance of wrapped_grpc_channel_credentials to be
* associated with an object of a class specified by class_type */
-zend_object_value create_wrapped_grpc_channel_credentials(
+php_grpc_zend_object create_wrapped_grpc_channel_credentials(
zend_class_entry *class_type TSRMLS_DC) {
- zend_object_value retval;
- wrapped_grpc_channel_credentials *intern;
-
- intern = (wrapped_grpc_channel_credentials *)emalloc(
- sizeof(wrapped_grpc_channel_credentials));
- memset(intern, 0, sizeof(wrapped_grpc_channel_credentials));
-
+ PHP_GRPC_ALLOC_CLASS_OBJECT(wrapped_grpc_channel_credentials);
zend_object_std_init(&intern->std, class_type TSRMLS_CC);
object_properties_init(&intern->std, class_type);
- retval.handle = zend_objects_store_put(
- intern, (zend_objects_store_dtor_t)zend_objects_destroy_object,
- free_wrapped_grpc_channel_credentials, NULL TSRMLS_CC);
- retval.handlers = zend_get_std_object_handlers();
- return retval;
+ PHP_GRPC_FREE_CLASS_OBJECT(wrapped_grpc_channel_credentials,
+ channel_credentials_ce_handlers);
}
zval *grpc_php_wrap_channel_credentials(grpc_channel_credentials
*wrapped TSRMLS_DC) {
zval *credentials_object;
- MAKE_STD_ZVAL(credentials_object);
- object_init_ex(credentials_object, grpc_ce_channel_credentials);
- wrapped_grpc_channel_credentials *credentials =
- (wrapped_grpc_channel_credentials *)zend_object_store_get_object(
- credentials_object TSRMLS_CC);
- credentials->wrapped = wrapped;
- return credentials_object;
-}
-
-#else
-
-static zend_object_handlers channel_credentials_ce_handlers;
-
-/* Frees and destroys an instance of wrapped_grpc_channel_credentials */
-static void free_wrapped_grpc_channel_credentials(zend_object *object) {
- wrapped_grpc_channel_credentials *creds =
- wrapped_grpc_channel_creds_from_obj(object);
- if (creds->wrapped != NULL) {
- grpc_channel_credentials_release(creds->wrapped);
- }
- zend_object_std_dtor(&creds->std);
-}
-
-/* Initializes an instance of wrapped_grpc_channel_credentials to be
- * associated with an object of a class specified by class_type */
-zend_object *create_wrapped_grpc_channel_credentials(zend_class_entry
- *class_type) {
- wrapped_grpc_channel_credentials *intern;
- intern = ecalloc(1, sizeof(wrapped_grpc_channel_credentials) +
- zend_object_properties_size(class_type));
- zend_object_std_init(&intern->std, class_type);
- object_properties_init(&intern->std, class_type);
- intern->std.handlers = &channel_credentials_ce_handlers;
- return &intern->std;
-}
-
-void grpc_php_wrap_channel_credentials(grpc_channel_credentials *wrapped,
- zval *credentials_object) {
+ PHP_GRPC_MAKE_STD_ZVAL(credentials_object);
object_init_ex(credentials_object, grpc_ce_channel_credentials);
wrapped_grpc_channel_credentials *credentials =
Z_WRAPPED_GRPC_CHANNEL_CREDS_P(credentials_object);
credentials->wrapped = wrapped;
+ return credentials_object;
}
-#endif
-
/**
* Set default roots pem.
* @param string pem_roots PEM encoding of the server root certificates
@@ -171,13 +121,10 @@ PHP_METHOD(ChannelCredentials, setDefaultRootsPem) {
*/
PHP_METHOD(ChannelCredentials, createDefault) {
grpc_channel_credentials *creds = grpc_google_default_credentials_create();
-#if PHP_MAJOR_VERSION < 7
- zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC);
+ zval *creds_object;
+ PHP_GRPC_MAKE_STD_ZVAL(creds_object);
+ creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC);
RETURN_DESTROY_ZVAL(creds_object);
-#else
- grpc_php_wrap_channel_credentials(creds, return_value);
- RETURN_DESTROY_ZVAL(return_value);
-#endif
}
/**
@@ -213,13 +160,10 @@ PHP_METHOD(ChannelCredentials, createSsl) {
grpc_channel_credentials *creds = grpc_ssl_credentials_create(
pem_root_certs,
pem_key_cert_pair.private_key == NULL ? NULL : &pem_key_cert_pair, NULL);
-#if PHP_MAJOR_VERSION < 7
- zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC);
+ zval *creds_object;
+ PHP_GRPC_MAKE_STD_ZVAL(creds_object);
+ creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC);
RETURN_DESTROY_ZVAL(creds_object);
-#else
- grpc_php_wrap_channel_credentials(creds, return_value);
- RETURN_DESTROY_ZVAL(return_value);
-#endif
}
/**
@@ -244,19 +188,13 @@ PHP_METHOD(ChannelCredentials, createComposite) {
Z_WRAPPED_GRPC_CHANNEL_CREDS_P(cred1_obj);
wrapped_grpc_call_credentials *cred2 =
Z_WRAPPED_GRPC_CALL_CREDS_P(cred2_obj);
-#if PHP_MAJOR_VERSION < 7
grpc_channel_credentials *creds =
grpc_composite_channel_credentials_create(cred1->wrapped, cred2->wrapped,
NULL);
- zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC);
+ zval *creds_object;
+ PHP_GRPC_MAKE_STD_ZVAL(creds_object);
+ creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC);
RETURN_DESTROY_ZVAL(creds_object);
-#else
- grpc_channel_credentials *creds =
- grpc_composite_channel_credentials_create(cred1->wrapped,
- cred2->wrapped, NULL);
- grpc_php_wrap_channel_credentials(creds, return_value);
- RETURN_DESTROY_ZVAL(return_value);
-#endif
}
/**
@@ -288,13 +226,6 @@ void grpc_init_channel_credentials(TSRMLS_D) {
grpc_set_ssl_roots_override_callback(get_ssl_roots_override);
ce.create_object = create_wrapped_grpc_channel_credentials;
grpc_ce_channel_credentials = zend_register_internal_class(&ce TSRMLS_CC);
-#if PHP_MAJOR_VERSION >= 7
- memcpy(&channel_credentials_ce_handlers,
- zend_get_std_object_handlers(),
- sizeof(zend_object_handlers));
- channel_credentials_ce_handlers.offset =
- XtOffsetOf(wrapped_grpc_channel_credentials, std);
- channel_credentials_ce_handlers.free_obj =
- free_wrapped_grpc_channel_credentials;
-#endif
+ PHP_GRPC_INIT_HANDLER(wrapped_grpc_channel_credentials,
+ channel_credentials_ce_handlers);
}
diff --git a/src/php/ext/grpc/channel_credentials.h b/src/php/ext/grpc/channel_credentials.h
index 0f7759daa6..b043d91fa6 100755
--- a/src/php/ext/grpc/channel_credentials.h
+++ b/src/php/ext/grpc/channel_credentials.h
@@ -49,37 +49,27 @@
/* Class entry for the ChannelCredentials PHP class */
extern zend_class_entry *grpc_ce_channel_credentials;
-#if PHP_MAJOR_VERSION < 7
-
/* Wrapper struct for grpc_channel_credentials that can be associated
* with a PHP object */
-typedef struct wrapped_grpc_channel_credentials {
- zend_object std;
+PHP_GRPC_WRAP_OBJECT_START(wrapped_grpc_channel_credentials)
grpc_channel_credentials *wrapped;
-} wrapped_grpc_channel_credentials;
+PHP_GRPC_WRAP_OBJECT_END(wrapped_grpc_channel_credentials)
+
+#if PHP_MAJOR_VERSION < 7
#define Z_WRAPPED_GRPC_CHANNEL_CREDS_P(zv) \
(wrapped_grpc_channel_credentials *)zend_object_store_get_object(zv TSRMLS_CC)
#else
-/* Wrapper struct for grpc_channel_credentials that can be associated
- * with a PHP object */
-typedef struct wrapped_grpc_channel_credentials {
- grpc_channel_credentials *wrapped;
- zend_object std;
-} wrapped_grpc_channel_credentials;
-
static inline wrapped_grpc_channel_credentials
-*wrapped_grpc_channel_creds_from_obj(zend_object *obj) {
- return
- (wrapped_grpc_channel_credentials *)
- ((char*)(obj) -
- XtOffsetOf(wrapped_grpc_channel_credentials, std));
+*wrapped_grpc_channel_credentials_from_obj(zend_object *obj) {
+ return (wrapped_grpc_channel_credentials *)(
+ (char*)(obj) - XtOffsetOf(wrapped_grpc_channel_credentials, std));
}
-#define Z_WRAPPED_GRPC_CHANNEL_CREDS_P(zv) \
- wrapped_grpc_channel_creds_from_obj(Z_OBJ_P((zv)))
+#define Z_WRAPPED_GRPC_CHANNEL_CREDS_P(zv) \
+ wrapped_grpc_channel_credentials_from_obj(Z_OBJ_P((zv)))
#endif /* PHP_MAJOR_VERSION */
diff --git a/src/php/ext/grpc/package.xml b/src/php/ext/grpc/package.xml
deleted file mode 100644
index daf2ee5a53..0000000000
--- a/src/php/ext/grpc/package.xml
+++ /dev/null
@@ -1,156 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<package packagerversion="1.9.5" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
- <name>grpc</name>
- <channel>pecl.php.net</channel>
- <summary>A high performance, open source, general RPC framework that puts mobile and HTTP/2 first.</summary>
- <description>Remote Procedure Calls (RPCs) provide a useful abstraction for building distributed applications and services. The libraries in this repository provide a concrete implementation of the gRPC protocol, layered over HTTP/2. These libraries enable communication between clients and servers using any combination of the supported languages.</description>
- <lead>
- <name>Stanley Cheung</name>
- <user>stanleycheung</user>
- <email>grpc-packages@google.com</email>
- <active>yes</active>
- </lead>
- <date>2016-01-13</date>
- <time>16:06:07</time>
- <version>
- <release>0.7.0</release>
- <api>0.7.0</api>
- </version>
- <stability>
- <release>beta</release>
- <api>beta</api>
- </stability>
- <license>BSD</license>
- <notes>
-- Breaking change to Credentials class (removed) #3765
-- Replaced by ChannelCredentials and CallCredentials class #3765
-- New plugin based metadata auth API #4394
-- Explicit ChannelCredentials::createInsecure() call
- </notes>
- <contents>
- <dir baseinstalldir="/" name="/">
- <file baseinstalldir="/" md5sum="f201d644fdbd8228ffd1d4a69cc44f1f" name="tests/grpc-basic.phpt" role="test" />
- <file baseinstalldir="/" md5sum="6f19828fb869b7b8a590cbb76b4f996d" name="byte_buffer.c" role="src" />
- <file baseinstalldir="/" md5sum="c8de0f819499c48adfc8d7f472c0196b" name="byte_buffer.h" role="src" />
- <file baseinstalldir="/" md5sum="ee7eb7757f9e6f0e36f8f616b6bd0af5" name="call.c" role="src" />
- <file baseinstalldir="/" md5sum="44c56bd9912d2538cbd6059e3e0452b6" name="call.h" role="src" />
- <file baseinstalldir="/" md5sum="ff90f6c03ed44b5f4170bf3259a6704e" name="call_credentials.c" role="src" />
- <file baseinstalldir="/" md5sum="3c3860e1d84f43cb6b2fbaa8d2ae1ab7" name="call_credentials.h" role="src" />
- <file baseinstalldir="/" md5sum="aee9b63f790522aec2c682055240cc61" name="channel.c" role="src" />
- <file baseinstalldir="/" md5sum="ed4b00c0cf3702b115d0cfa87450dc09" name="channel.h" role="src" />
- <file baseinstalldir="/" md5sum="1a51c76d0b7b7d3ab570ed7d60c2ea46" name="channel_credentials.c" role="src" />
- <file baseinstalldir="/" md5sum="a86250e03f610ce6c2c7595a84e08821" name="channel_credentials.h" role="src" />
- <file baseinstalldir="/" md5sum="55ab7a42f9dd9bfc7e28a61cfc5fca63" name="completion_queue.c" role="src" />
- <file baseinstalldir="/" md5sum="f10b5bb232d74a6878e829e2e76cdaa2" name="completion_queue.h" role="src" />
- <file baseinstalldir="/" md5sum="cafed254127007ff2271dad7d56a06c8" name="config.m4" role="src" />
- <file baseinstalldir="/" md5sum="38a1bc979d810c36ebc2a52d4b7b5319" name="CREDITS" role="doc" />
- <file baseinstalldir="/" md5sum="8847cf67b1b54c981d47ecbb0d139a0c" name="LICENSE" role="doc" />
- <file baseinstalldir="/" md5sum="3131a8af38fe5918e5409016b89d6cdb" name="php_grpc.c" role="src" />
- <file baseinstalldir="/" md5sum="673b07859d9f69232f8a754c56780686" name="php_grpc.h" role="src" />
- <file baseinstalldir="/" md5sum="7533a6d3ea02c78cad23a9651de0825d" name="README.md" role="doc" />
- <file baseinstalldir="/" md5sum="3e4e960454ebb2fc7b78a840493f5315" name="server.c" role="src" />
- <file baseinstalldir="/" md5sum="4b730f06d14cbbb0642bdbd194749595" name="server.h" role="src" />
- <file baseinstalldir="/" md5sum="34ea881f1fe960d190d0713422cf8916" name="server_credentials.c" role="src" />
- <file baseinstalldir="/" md5sum="9c4b4cc06356a8a39a16a085a9b85996" name="server_credentials.h" role="src" />
- <file baseinstalldir="/" md5sum="7646ec78cb133f66ba59e03c6f451e39" name="timeval.c" role="src" />
- <file baseinstalldir="/" md5sum="496e27a100b4d93ca3fb35c924c5e163" name="timeval.h" role="src" />
- </dir>
- </contents>
- <dependencies>
- <required>
- <php>
- <min>5.5.0</min>
- </php>
- <pearinstaller>
- <min>1.4.0</min>
- </pearinstaller>
- </required>
- </dependencies>
- <providesextension>grpc</providesextension>
- <extsrcrelease />
- <changelog>
- <release>
- <version>
- <release>0.5.0</release>
- <api>0.5.0</api>
- </version>
- <stability>
- <release>alpha</release>
- <api>alpha</api>
- </stability>
- <date>2015-06-16</date>
- <license>BSD</license>
- <notes>
-First alpha release
- </notes>
- </release>
- <release>
- <version>
- <release>0.5.1</release>
- <api>0.5.1</api>
- </version>
- <stability>
- <release>alpha</release>
- <api>alpha</api>
- </stability>
- <date>2015-07-09</date>
- <license>BSD</license>
- <notes>
-Update to wrap gRPC C Core version 0.10.0
- </notes>
- </release>
- <release>
- <version>
- <release>0.6.0</release>
- <api>0.6.0</api>
- </version>
- <stability>
- <release>beta</release>
- <api>beta</api>
- </stability>
- <date>2015-09-24</date>
- <license>BSD</license>
- <notes>
-- support per message compression disable
-- expose per-call host override option
-- expose connectivity API
-- expose channel target and call peer
-- add user-agent
-- update to wrap gRPC C core library beta version 0.11.0
- </notes>
- </release>
- <release>
- <version>
- <release>0.6.1</release>
- <api>0.6.0</api>
- </version>
- <stability>
- <release>beta</release>
- <api>beta</api>
- </stability>
- <date>2015-10-21</date>
- <license>BSD</license>
- <notes>
-- fixed undefined constant fatal error when run with apache/nginx #2275
- </notes>
- </release>
- <release>
- <version>
- <release>0.7.0</release>
- <api>0.7.0</api>
- </version>
- <stability>
- <release>beta</release>
- <api>beta</api>
- </stability>
- <date>2016-01-13</date>
- <license>BSD</license>
- <notes>
-- Breaking change to Credentials class (removed) #3765
-- Replaced by ChannelCredentials and CallCredentials class #3765
-- New plugin based metadata auth API #4394
-- Explicit ChannelCredentials::createInsecure() call
- </notes>
- </release>
- </changelog>
-</package>
diff --git a/src/php/ext/grpc/php7_wrapper.h b/src/php/ext/grpc/php7_wrapper.h
index e4d0d4c90b..fd8d35636f 100644
--- a/src/php/ext/grpc/php7_wrapper.h
+++ b/src/php/ext/grpc/php7_wrapper.h
@@ -39,13 +39,179 @@
#define php_grpc_int int
#define php_grpc_long long
+#define php_grpc_ulong ulong
+#define php_grpc_zend_object zend_object_value
+#define php_grpc_add_property_string(arg, name, context, b) \
+ add_property_string(arg, name, context, b)
+#define php_grpc_add_property_stringl(res, name, str, len, b) \
+ add_property_stringl(res, name, str, len, b)
+#define php_grpc_add_next_index_stringl(data, str, len, b) \
+ add_next_index_stringl(data, str, len, b)
+
#define PHP_GRPC_RETURN_STRING(val, dup) RETURN_STRING(val, dup)
+#define PHP_GRPC_MAKE_STD_ZVAL(pzv) MAKE_STD_ZVAL(pzv)
+#define PHP_GRPC_DELREF(zv) Z_DELREF_P(zv)
+
+#define PHP_GRPC_WRAP_OBJECT_START(name) \
+ typedef struct name { \
+ zend_object std;
+#define PHP_GRPC_WRAP_OBJECT_END(name) \
+ } name;
+
+#define PHP_GRPC_FREE_WRAPPED_FUNC_START(class_object) \
+ void free_##class_object(void *object TSRMLS_DC) { \
+ class_object *p = (class_object *)object;
+#define PHP_GRPC_FREE_WRAPPED_FUNC_END() \
+ zend_object_std_dtor(&p->std TSRMLS_CC); \
+ efree(p); \
+ }
+
+#define PHP_GRPC_ALLOC_CLASS_OBJECT(class_object) \
+ class_object *intern; \
+ zend_object_value retval; \
+ intern = (class_object *)emalloc(sizeof(class_object)); \
+ memset(intern, 0, sizeof(class_object));
+
+#define PHP_GRPC_FREE_CLASS_OBJECT(class_object, handler) \
+ retval.handle = zend_objects_store_put( \
+ intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, \
+ free_##class_object, NULL TSRMLS_CC); \
+ retval.handlers = zend_get_std_object_handlers(); \
+ return retval;
+
+#define PHP_GRPC_HASH_FOREACH_VAL_START(ht, data) \
+ zval **tmp_data = NULL; \
+ for (zend_hash_internal_pointer_reset(ht); \
+ zend_hash_get_current_data(ht, (void**)&tmp_data) == SUCCESS; \
+ zend_hash_move_forward(ht)) { \
+ data = *tmp_data;
+
+#define PHP_GRPC_HASH_FOREACH_STR_KEY_VAL_START(ht, key, key_type, data) \
+ zval **tmp##key = NULL; \
+ ulong index##key; \
+ uint len##key; \
+ for (zend_hash_internal_pointer_reset(ht); \
+ zend_hash_get_current_data(ht, (void**)&tmp##key) == SUCCESS; \
+ zend_hash_move_forward(ht)) { \
+ key_type = zend_hash_get_current_key_ex(ht, &key, &len##key, &index##key,\
+ 0, NULL); \
+ data = *tmp##key;
+
+#define PHP_GRPC_HASH_FOREACH_LONG_KEY_VAL_START(ht, key, key_type, index,\
+ data) \
+ zval **tmp##key = NULL; \
+ uint len##key; \
+ for (zend_hash_internal_pointer_reset(ht); \
+ zend_hash_get_current_data(ht, (void**)&tmp##key) == SUCCESS; \
+ zend_hash_move_forward(ht)) { \
+ key_type = zend_hash_get_current_key_ex(ht, &key, &len##key, &index,\
+ 0, NULL); \
+ data = *tmp##key;
+
+#define PHP_GRPC_HASH_FOREACH_END() }
+
+static inline int php_grpc_zend_hash_find(HashTable *ht, char *key, int len,
+ void **value) {
+ zval **data = NULL;
+ if (zend_hash_find(ht, key, len, (void **)&data) == SUCCESS) {
+ *value = *data;
+ return SUCCESS;
+ } else {
+ *value = NULL;
+ return FAILURE;
+ }
+}
+
+#define php_grpc_zend_hash_del zend_hash_del
+
+#define PHP_GRPC_GET_CLASS_ENTRY(object) zend_get_class_entry(object TSRMLS_CC)
+
+#define PHP_GRPC_INIT_HANDLER(class_object, handler_name)
#else
#define php_grpc_int size_t
#define php_grpc_long zend_long
+#define php_grpc_ulong zend_ulong
+#define php_grpc_zend_object zend_object*
+#define php_grpc_add_property_string(arg, name, context, b) \
+ add_property_string(arg, name, context)
+#define php_grpc_add_property_stringl(res, name, str, len, b) \
+ add_property_stringl(res, name, str, len)
+#define php_grpc_add_next_index_stringl(data, str, len, b) \
+ add_next_index_stringl(data, str, len)
+
#define PHP_GRPC_RETURN_STRING(val, dup) RETURN_STRING(val)
+#define PHP_GRPC_MAKE_STD_ZVAL(pzv) \
+ zval _stack_zval_##pzv; \
+ pzv = &(_stack_zval_##pzv)
+#define PHP_GRPC_DELREF(zv)
+
+#define PHP_GRPC_WRAP_OBJECT_START(name) \
+ typedef struct name {
+#define PHP_GRPC_WRAP_OBJECT_END(name) \
+ zend_object std; \
+ } name;
+
+#define WRAPPED_OBJECT_FROM_OBJ(class_object, obj) \
+ class_object##_from_obj(obj);
+
+#define PHP_GRPC_FREE_WRAPPED_FUNC_START(class_object) \
+ static void free_##class_object(zend_object *object) { \
+ class_object *p = WRAPPED_OBJECT_FROM_OBJ(class_object, object)
+#define PHP_GRPC_FREE_WRAPPED_FUNC_END() \
+ zend_object_std_dtor(&p->std); \
+ }
+
+#define PHP_GRPC_ALLOC_CLASS_OBJECT(class_object) \
+ class_object *intern; \
+ intern = ecalloc(1, sizeof(class_object) + \
+ zend_object_properties_size(class_type));
+
+#define PHP_GRPC_FREE_CLASS_OBJECT(class_object, handler) \
+ intern->std.handlers = &handler; \
+ return &intern->std;
+
+#define PHP_GRPC_HASH_FOREACH_VAL_START(ht, data) \
+ ZEND_HASH_FOREACH_VAL(ht, data) {
+
+#define PHP_GRPC_HASH_FOREACH_STR_KEY_VAL_START(ht, key, key_type, data) \
+ zend_string *(zs_##key); \
+ ZEND_HASH_FOREACH_STR_KEY_VAL(ht, (zs_##key), data) { \
+ if ((zs_##key) == NULL) {key = NULL; key_type = HASH_KEY_IS_LONG;} \
+ else {key = (zs_##key)->val; key_type = HASH_KEY_IS_STRING;}
+
+#define PHP_GRPC_HASH_FOREACH_LONG_KEY_VAL_START(ht, key, key_type, index, \
+ data) \
+ zend_string *(zs_##key); \
+ ZEND_HASH_FOREACH_KEY_VAL(ht, index, zs_##key, data) { \
+ if ((zs_##key) == NULL) {key = NULL; key_type = HASH_KEY_IS_LONG;} \
+ else {key = (zs_##key)->val; key_type = HASH_KEY_IS_STRING;}
+
+#define PHP_GRPC_HASH_FOREACH_END() } ZEND_HASH_FOREACH_END();
+
+static inline int php_grpc_zend_hash_find(HashTable *ht, char *key, int len,
+ void **value) {
+ zval *value_tmp = zend_hash_str_find(ht, key, len -1);
+ if (value_tmp == NULL) {
+ return FAILURE;
+ } else {
+ *value = (void *)value_tmp;
+ return SUCCESS;
+ }
+}
+
+static inline int php_grpc_zend_hash_del(HashTable *ht, char *key, int len) {
+ return zend_hash_str_del(ht, key, len - 1);
+}
+
+#define PHP_GRPC_GET_CLASS_ENTRY(object) Z_OBJ_P(object)->ce
+
+#define PHP_GRPC_INIT_HANDLER(class_object, handler_name) \
+ memcpy(&handler_name, zend_get_std_object_handlers(), \
+ sizeof(zend_object_handlers)); \
+ handler_name.offset = XtOffsetOf(class_object, std); \
+ handler_name.free_obj = free_##class_object
#endif /* PHP_MAJOR_VERSION */
diff --git a/src/php/ext/grpc/server.c b/src/php/ext/grpc/server.c
index e67e62c34e..fc20c42b16 100644
--- a/src/php/ext/grpc/server.c
+++ b/src/php/ext/grpc/server.c
@@ -57,73 +57,31 @@
#include "timeval.h"
zend_class_entry *grpc_ce_server;
-
-#if PHP_MAJOR_VERSION < 7
-
-/* Frees and destroys an instance of wrapped_grpc_server */
-void free_wrapped_grpc_server(void *object TSRMLS_DC) {
- wrapped_grpc_server *server = (wrapped_grpc_server *)object;
- if (server->wrapped != NULL) {
- grpc_server_shutdown_and_notify(server->wrapped, completion_queue, NULL);
- grpc_server_cancel_all_calls(server->wrapped);
- grpc_completion_queue_pluck(completion_queue, NULL,
- gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
- grpc_server_destroy(server->wrapped);
- }
- zend_object_std_dtor(&server->std TSRMLS_CC);
- efree(server);
-}
-
-/* Initializes an instance of wrapped_grpc_call to be associated with an object
- * of a class specified by class_type */
-zend_object_value create_wrapped_grpc_server(zend_class_entry *class_type
- TSRMLS_DC) {
- zend_object_value retval;
- wrapped_grpc_server *intern;
-
- intern = (wrapped_grpc_server *)emalloc(sizeof(wrapped_grpc_server));
- memset(intern, 0, sizeof(wrapped_grpc_server));
-
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
- object_properties_init(&intern->std, class_type);
- retval.handle = zend_objects_store_put(
- intern, (zend_objects_store_dtor_t)zend_objects_destroy_object,
- free_wrapped_grpc_server, NULL TSRMLS_CC);
- retval.handlers = zend_get_std_object_handlers();
- return retval;
-}
-
-#else
-
+#if PHP_MAJOR_VERSION >= 7
static zend_object_handlers server_ce_handlers;
+#endif
/* Frees and destroys an instance of wrapped_grpc_server */
-static void free_wrapped_grpc_server(zend_object *object) {
- wrapped_grpc_server *server = wrapped_grpc_server_from_obj(object);
- if (server->wrapped != NULL) {
- grpc_server_shutdown_and_notify(server->wrapped, completion_queue, NULL);
- grpc_server_cancel_all_calls(server->wrapped);
+PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_server)
+ if (p->wrapped != NULL) {
+ grpc_server_shutdown_and_notify(p->wrapped, completion_queue, NULL);
+ grpc_server_cancel_all_calls(p->wrapped);
grpc_completion_queue_pluck(completion_queue, NULL,
gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
- grpc_server_destroy(server->wrapped);
+ grpc_server_destroy(p->wrapped);
}
- zend_object_std_dtor(&server->std);
-}
+PHP_GRPC_FREE_WRAPPED_FUNC_END()
/* Initializes an instance of wrapped_grpc_call to be associated with an object
* of a class specified by class_type */
-zend_object *create_wrapped_grpc_server(zend_class_entry *class_type) {
- wrapped_grpc_server *intern;
- intern = ecalloc(1, sizeof(wrapped_grpc_server) +
- zend_object_properties_size(class_type));
- zend_object_std_init(&intern->std, class_type);
+php_grpc_zend_object create_wrapped_grpc_server(zend_class_entry *class_type
+ TSRMLS_DC) {
+ PHP_GRPC_ALLOC_CLASS_OBJECT(wrapped_grpc_server);
+ zend_object_std_init(&intern->std, class_type TSRMLS_CC);
object_properties_init(&intern->std, class_type);
- intern->std.handlers = &server_ce_handlers;
- return &intern->std;
+ PHP_GRPC_FREE_CLASS_OBJECT(wrapped_grpc_server, server_ce_handlers);
}
-#endif
-
/**
* Constructs a new instance of the Server class
* @param array $args The arguments to pass to the server (optional)
@@ -168,13 +126,9 @@ PHP_METHOD(Server, requestCall) {
grpc_event event;
wrapped_grpc_server *server = Z_WRAPPED_GRPC_SERVER_P(getThis());
-#if PHP_MAJOR_VERSION < 7
zval *result;
- MAKE_STD_ZVAL(result);
+ PHP_GRPC_MAKE_STD_ZVAL(result);
object_init(result);
-#else
- object_init(return_value);
-#endif
grpc_call_details_init(&details);
grpc_metadata_array_init(&metadata);
@@ -195,40 +149,32 @@ PHP_METHOD(Server, requestCall) {
1 TSRMLS_CC);
goto cleanup;
}
+ php_grpc_add_property_string(result, "method", details.method, true);
+ php_grpc_add_property_string(result, "host", details.host, true);
#if PHP_MAJOR_VERSION < 7
add_property_zval(result, "call", grpc_php_wrap_call(call, true TSRMLS_CC));
- add_property_string(result, "method", details.method, true);
- add_property_string(result, "host", details.host, true);
add_property_zval(result, "absolute_deadline",
grpc_php_wrap_timeval(details.deadline TSRMLS_CC));
add_property_zval(result, "metadata", grpc_parse_metadata_array(&metadata
TSRMLS_CC));
-
-cleanup:
- grpc_call_details_destroy(&details);
- grpc_metadata_array_destroy(&metadata);
- RETURN_DESTROY_ZVAL(result);
-
#else
-
zval zv_call;
zval zv_timeval;
zval zv_md;
- grpc_php_wrap_call(call, true, &zv_call);
- grpc_php_wrap_timeval(details.deadline, &zv_timeval);
- grpc_parse_metadata_array(&metadata, &zv_md);
-
- add_property_zval(return_value, "call", &zv_call);
- add_property_string(return_value, "method", details.method);
- add_property_string(return_value, "host", details.host);
- add_property_zval(return_value, "absolute_deadline", &zv_timeval);
- add_property_zval(return_value, "metadata", &zv_md);
+ //TODO(thinkerou): why use zval* to unit test error?
+ zv_call = *grpc_php_wrap_call(call, true);
+ zv_timeval = *grpc_php_wrap_timeval(details.deadline);
+ zv_md = *grpc_parse_metadata_array(&metadata);
+
+ add_property_zval(result, "call", &zv_call);
+ add_property_zval(result, "absolute_deadline", &zv_timeval);
+ add_property_zval(result, "metadata", &zv_md);
+#endif
cleanup:
grpc_call_details_destroy(&details);
grpc_metadata_array_destroy(&metadata);
- RETURN_DESTROY_ZVAL(return_value);
-#endif
+ RETURN_DESTROY_ZVAL(result);
}
/**
@@ -287,7 +233,7 @@ static zend_function_entry server_methods[] = {
PHP_ME(Server, addHttp2Port, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Server, addSecureHttp2Port, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Server, start, NULL, ZEND_ACC_PUBLIC)
- PHP_FE_END
+ PHP_FE_END
};
void grpc_init_server(TSRMLS_D) {
@@ -295,10 +241,5 @@ void grpc_init_server(TSRMLS_D) {
INIT_CLASS_ENTRY(ce, "Grpc\\Server", server_methods);
ce.create_object = create_wrapped_grpc_server;
grpc_ce_server = zend_register_internal_class(&ce TSRMLS_CC);
-#if PHP_MAJOR_VERSION >= 7
- memcpy(&server_ce_handlers, zend_get_std_object_handlers(),
- sizeof(zend_object_handlers));
- server_ce_handlers.offset = XtOffsetOf(wrapped_grpc_server, std);
- server_ce_handlers.free_obj = free_wrapped_grpc_server;
-#endif
+ PHP_GRPC_INIT_HANDLER(wrapped_grpc_server, server_ce_handlers);
}
diff --git a/src/php/ext/grpc/server.h b/src/php/ext/grpc/server.h
index 603b9a7102..a635bc11df 100755
--- a/src/php/ext/grpc/server.h
+++ b/src/php/ext/grpc/server.h
@@ -48,33 +48,25 @@
/* Class entry for the Server PHP class */
extern zend_class_entry *grpc_ce_server;
-#if PHP_MAJOR_VERSION < 7
-
/* Wrapper struct for grpc_server that can be associated with a PHP object */
-typedef struct wrapped_grpc_server {
- zend_object std;
+PHP_GRPC_WRAP_OBJECT_START(wrapped_grpc_server)
grpc_server *wrapped;
-} wrapped_grpc_server;
+PHP_GRPC_WRAP_OBJECT_END(wrapped_grpc_server)
+
+#if PHP_MAJOR_VERSION < 7
#define Z_WRAPPED_GRPC_SERVER_P(zv) \
(wrapped_grpc_server *)zend_object_store_get_object(zv TSRMLS_CC)
#else
-/* Wrapper struct for grpc_server that can be associated with a PHP object */
-typedef struct wrapped_grpc_server {
- grpc_server *wrapped;
- zend_object std;
-} wrapped_grpc_server;
-
static inline wrapped_grpc_server
*wrapped_grpc_server_from_obj(zend_object *obj) {
return (wrapped_grpc_server*)((char*)(obj) -
XtOffsetOf(wrapped_grpc_server, std));
}
-#define Z_WRAPPED_GRPC_SERVER_P(zv) \
- wrapped_grpc_server_from_obj(Z_OBJ_P((zv)))
+#define Z_WRAPPED_GRPC_SERVER_P(zv) wrapped_grpc_server_from_obj(Z_OBJ_P((zv)))
#endif /* PHP_MAJOR_VERSION */
diff --git a/src/php/ext/grpc/server_credentials.c b/src/php/ext/grpc/server_credentials.c
index e61fc5b4a1..b05896af4a 100644
--- a/src/php/ext/grpc/server_credentials.c
+++ b/src/php/ext/grpc/server_credentials.c
@@ -50,89 +50,39 @@
#include <grpc/grpc_security.h>
zend_class_entry *grpc_ce_server_credentials;
-
-#if PHP_MAJOR_VERSION < 7
+#if PHP_MAJOR_VERSION >= 7
+static zend_object_handlers server_credentials_ce_handlers;
+#endif
/* Frees and destroys an instace of wrapped_grpc_server_credentials */
-void free_wrapped_grpc_server_credentials(void *object TSRMLS_DC) {
- wrapped_grpc_server_credentials *creds =
- (wrapped_grpc_server_credentials *)object;
- if (creds->wrapped != NULL) {
- grpc_server_credentials_release(creds->wrapped);
+PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_server_credentials)
+ if (p->wrapped != NULL) {
+ grpc_server_credentials_release(p->wrapped);
}
- zend_object_std_dtor(&creds->std TSRMLS_CC);
- efree(creds);
-}
+PHP_GRPC_FREE_WRAPPED_FUNC_END()
/* Initializes an instace of wrapped_grpc_server_credentials to be associated
* with an object of a class specified by class_type */
-zend_object_value create_wrapped_grpc_server_credentials(
+php_grpc_zend_object create_wrapped_grpc_server_credentials(
zend_class_entry *class_type TSRMLS_DC) {
- zend_object_value retval;
- wrapped_grpc_server_credentials *intern;
-
- intern = (wrapped_grpc_server_credentials *)emalloc(
- sizeof(wrapped_grpc_server_credentials));
- memset(intern, 0, sizeof(wrapped_grpc_server_credentials));
-
+ PHP_GRPC_ALLOC_CLASS_OBJECT(wrapped_grpc_server_credentials);
zend_object_std_init(&intern->std, class_type TSRMLS_CC);
object_properties_init(&intern->std, class_type);
- retval.handle = zend_objects_store_put(
- intern, (zend_objects_store_dtor_t)zend_objects_destroy_object,
- free_wrapped_grpc_server_credentials, NULL TSRMLS_CC);
- retval.handlers = zend_get_std_object_handlers();
- return retval;
+ PHP_GRPC_FREE_CLASS_OBJECT(wrapped_grpc_server_credentials,
+ server_credentials_ce_handlers);
}
zval *grpc_php_wrap_server_credentials(grpc_server_credentials
*wrapped TSRMLS_DC) {
zval *server_credentials_object;
- MAKE_STD_ZVAL(server_credentials_object);
- object_init_ex(server_credentials_object, grpc_ce_server_credentials);
- wrapped_grpc_server_credentials *server_credentials =
- (wrapped_grpc_server_credentials *)zend_object_store_get_object(
- server_credentials_object TSRMLS_CC);
- server_credentials->wrapped = wrapped;
- return server_credentials_object;
-}
-
-#else
-
-static zend_object_handlers server_credentials_ce_handlers;
-
-/* Frees and destroys an instace of wrapped_grpc_server_credentials */
-static void free_wrapped_grpc_server_credentials(zend_object *object) {
- wrapped_grpc_server_credentials *creds =
- wrapped_grpc_server_creds_from_obj(object);
- if (creds->wrapped != NULL) {
- grpc_server_credentials_release(creds->wrapped);
- }
- zend_object_std_dtor(&creds->std);
-}
-
-/* Initializes an instace of wrapped_grpc_server_credentials to be associated
- * with an object of a class specified by class_type */
-zend_object *create_wrapped_grpc_server_credentials(zend_class_entry
- *class_type) {
- wrapped_grpc_server_credentials *intern;
- intern = ecalloc(1, sizeof(wrapped_grpc_server_credentials) +
- zend_object_properties_size(class_type));
- zend_object_std_init(&intern->std, class_type);
- object_properties_init(&intern->std, class_type);
- intern->std.handlers = &server_credentials_ce_handlers;
- return &intern->std;
-}
-
-void grpc_php_wrap_server_credentials(grpc_server_credentials *wrapped,
- zval *server_credentials_object) {
+ PHP_GRPC_MAKE_STD_ZVAL(server_credentials_object);
object_init_ex(server_credentials_object, grpc_ce_server_credentials);
wrapped_grpc_server_credentials *server_credentials =
Z_WRAPPED_GRPC_SERVER_CREDS_P(server_credentials_object);
server_credentials->wrapped = wrapped;
+ return server_credentials_object;
}
-#endif
-
/**
* Create SSL credentials.
* @param string pem_root_certs PEM encoding of the server root certificates
@@ -163,19 +113,16 @@ PHP_METHOD(ServerCredentials, createSsl) {
grpc_server_credentials *creds = grpc_ssl_server_credentials_create_ex(
pem_root_certs, &pem_key_cert_pair, 1,
GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, NULL);
-#if PHP_MAJOR_VERSION < 7
- zval *creds_object = grpc_php_wrap_server_credentials(creds TSRMLS_CC);
+ zval *creds_object;
+ PHP_GRPC_MAKE_STD_ZVAL(creds_object);
+ creds_object = grpc_php_wrap_server_credentials(creds TSRMLS_CC);
RETURN_DESTROY_ZVAL(creds_object);
-#else
- grpc_php_wrap_server_credentials(creds, return_value);
- RETURN_DESTROY_ZVAL(return_value);
-#endif
}
static zend_function_entry server_credentials_methods[] = {
PHP_ME(ServerCredentials, createSsl, NULL,
ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
- PHP_FE_END
+ PHP_FE_END
};
void grpc_init_server_credentials(TSRMLS_D) {
@@ -183,13 +130,6 @@ void grpc_init_server_credentials(TSRMLS_D) {
INIT_CLASS_ENTRY(ce, "Grpc\\ServerCredentials", server_credentials_methods);
ce.create_object = create_wrapped_grpc_server_credentials;
grpc_ce_server_credentials = zend_register_internal_class(&ce TSRMLS_CC);
-#if PHP_MAJOR_VERSION >= 7
- memcpy(&server_credentials_ce_handlers,
- zend_get_std_object_handlers(),
- sizeof(zend_object_handlers));
- server_credentials_ce_handlers.offset =
- XtOffsetOf(wrapped_grpc_server_credentials, std);
- server_credentials_ce_handlers.free_obj =
- free_wrapped_grpc_server_credentials;
-#endif
+ PHP_GRPC_INIT_HANDLER(wrapped_grpc_server_credentials,
+ server_credentials_ce_handlers);
}
diff --git a/src/php/ext/grpc/server_credentials.h b/src/php/ext/grpc/server_credentials.h
index 9df5950fa7..6781a614b1 100755
--- a/src/php/ext/grpc/server_credentials.h
+++ b/src/php/ext/grpc/server_credentials.h
@@ -49,34 +49,27 @@
/* Class entry for the Server_Credentials PHP class */
extern zend_class_entry *grpc_ce_server_credentials;
-#if PHP_MAJOR_VERSION < 7
-
/* Wrapper struct for grpc_server_credentials that can be associated with a PHP
* object */
-typedef struct wrapped_grpc_server_credentials {
- zend_object std;
+PHP_GRPC_WRAP_OBJECT_START(wrapped_grpc_server_credentials)
grpc_server_credentials *wrapped;
-} wrapped_grpc_server_credentials;
+PHP_GRPC_WRAP_OBJECT_END(wrapped_grpc_server_credentials)
+
+#if PHP_MAJOR_VERSION < 7
#define Z_WRAPPED_GRPC_SERVER_CREDS_P(zv) \
(wrapped_grpc_server_credentials *)zend_object_store_get_object(zv TSRMLS_CC)
#else
-typedef struct wrapped_grpc_server_credentials {
- grpc_server_credentials *wrapped;
- zend_object std;
-} wrapped_grpc_server_credentials;
-
static inline wrapped_grpc_server_credentials
-*wrapped_grpc_server_creds_from_obj(zend_object *obj) {
- return (wrapped_grpc_server_credentials*)
- ((char*)(obj) -
- XtOffsetOf(wrapped_grpc_server_credentials, std));
+*wrapped_grpc_server_credentials_from_obj(zend_object *obj) {
+ return (wrapped_grpc_server_credentials*)(
+ (char*)(obj) - XtOffsetOf(wrapped_grpc_server_credentials, std));
}
-#define Z_WRAPPED_GRPC_SERVER_CREDS_P(zv) \
- wrapped_grpc_server_creds_from_obj(Z_OBJ_P((zv)))
+#define Z_WRAPPED_GRPC_SERVER_CREDS_P(zv) \
+ wrapped_grpc_server_credentials_from_obj(Z_OBJ_P((zv)))
#endif /* PHP_MAJOR_VERSION */
diff --git a/src/php/ext/grpc/timeval.c b/src/php/ext/grpc/timeval.c
index a3ec62f13f..e145d96772 100644
--- a/src/php/ext/grpc/timeval.c
+++ b/src/php/ext/grpc/timeval.c
@@ -51,74 +51,33 @@
#include <grpc/support/time.h>
zend_class_entry *grpc_ce_timeval;
-
-#if PHP_MAJOR_VERSION < 7
+#if PHP_MAJOR_VERSION >= 7
+static zend_object_handlers timeval_ce_handlers;
+#endif
/* Frees and destroys an instance of wrapped_grpc_call */
-void free_wrapped_grpc_timeval(void *object TSRMLS_DC) {
- wrapped_grpc_timeval *timeval = (wrapped_grpc_timeval *)object;
- zend_object_std_dtor(&timeval->std TSRMLS_CC);
- efree(timeval);
-}
+PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_timeval)
+PHP_GRPC_FREE_WRAPPED_FUNC_END()
/* Initializes an instance of wrapped_grpc_timeval to be associated with an
* object of a class specified by class_type */
-zend_object_value create_wrapped_grpc_timeval(zend_class_entry *class_type
- TSRMLS_DC) {
- zend_object_value retval;
- wrapped_grpc_timeval *intern;
- intern = (wrapped_grpc_timeval *)emalloc(sizeof(wrapped_grpc_timeval));
- memset(intern, 0, sizeof(wrapped_grpc_timeval));
+php_grpc_zend_object create_wrapped_grpc_timeval(zend_class_entry *class_type
+ TSRMLS_DC) {
+ PHP_GRPC_ALLOC_CLASS_OBJECT(wrapped_grpc_timeval);
zend_object_std_init(&intern->std, class_type TSRMLS_CC);
object_properties_init(&intern->std, class_type);
- retval.handle = zend_objects_store_put(
- intern, (zend_objects_store_dtor_t)zend_objects_destroy_object,
- free_wrapped_grpc_timeval, NULL TSRMLS_CC);
- retval.handlers = zend_get_std_object_handlers();
- return retval;
+ PHP_GRPC_FREE_CLASS_OBJECT(wrapped_grpc_timeval, timeval_ce_handlers);
}
zval *grpc_php_wrap_timeval(gpr_timespec wrapped TSRMLS_DC) {
zval *timeval_object;
- MAKE_STD_ZVAL(timeval_object);
- object_init_ex(timeval_object, grpc_ce_timeval);
- wrapped_grpc_timeval *timeval =
- (wrapped_grpc_timeval *)zend_object_store_get_object(
- timeval_object TSRMLS_CC);
- memcpy(&timeval->wrapped, &wrapped, sizeof(gpr_timespec));
- return timeval_object;
-}
-
-#else
-
-static zend_object_handlers timeval_ce_handlers;
-
-/* Frees and destroys an instance of wrapped_grpc_call */
-static void free_wrapped_grpc_timeval(zend_object *object) {
- wrapped_grpc_timeval *timeval = wrapped_grpc_timeval_from_obj(object);
- zend_object_std_dtor(&timeval->std);
-}
-
-/* Initializes an instance of wrapped_grpc_timeval to be associated with an
- * object of a class specified by class_type */
-zend_object *create_wrapped_grpc_timeval(zend_class_entry *class_type) {
- wrapped_grpc_timeval *intern;
- intern = ecalloc(1, sizeof(wrapped_grpc_timeval) +
- zend_object_properties_size(class_type));
- zend_object_std_init(&intern->std, class_type);
- object_properties_init(&intern->std, class_type);
- intern->std.handlers = &timeval_ce_handlers;
- return &intern->std;
-}
-
-void grpc_php_wrap_timeval(gpr_timespec wrapped, zval *timeval_object) {
+ PHP_GRPC_MAKE_STD_ZVAL(timeval_object);
object_init_ex(timeval_object, grpc_ce_timeval);
wrapped_grpc_timeval *timeval = Z_WRAPPED_GRPC_TIMEVAL_P(timeval_object);
memcpy(&timeval->wrapped, &wrapped, sizeof(gpr_timespec));
+ return timeval_object;
}
-#endif
-
/**
* Constructs a new instance of the Timeval class
* @param long $usec The number of microseconds in the interval
@@ -156,16 +115,12 @@ PHP_METHOD(Timeval, add) {
}
wrapped_grpc_timeval *self = Z_WRAPPED_GRPC_TIMEVAL_P(getThis());
wrapped_grpc_timeval *other = Z_WRAPPED_GRPC_TIMEVAL_P(other_obj);
-#if PHP_MAJOR_VERSION < 7
- zval *sum =
+ zval *sum;
+ PHP_GRPC_MAKE_STD_ZVAL(sum);
+ sum =
grpc_php_wrap_timeval(gpr_time_add(self->wrapped, other->wrapped)
TSRMLS_CC);
RETURN_DESTROY_ZVAL(sum);
-#else
- grpc_php_wrap_timeval(gpr_time_add(self->wrapped, other->wrapped),
- return_value);
- RETURN_DESTROY_ZVAL(return_value);
-#endif
}
/**
@@ -186,16 +141,12 @@ PHP_METHOD(Timeval, subtract) {
}
wrapped_grpc_timeval *self = Z_WRAPPED_GRPC_TIMEVAL_P(getThis());
wrapped_grpc_timeval *other = Z_WRAPPED_GRPC_TIMEVAL_P(other_obj);
-#if PHP_MAJOR_VERSION < 7
- zval *diff =
+ zval *diff;
+ PHP_GRPC_MAKE_STD_ZVAL(diff);
+ diff =
grpc_php_wrap_timeval(gpr_time_sub(self->wrapped, other->wrapped)
TSRMLS_CC);
RETURN_DESTROY_ZVAL(diff);
-#else
- grpc_php_wrap_timeval(gpr_time_sub(self->wrapped, other->wrapped),
- return_value);
- RETURN_DESTROY_ZVAL(return_value);
-#endif
}
/**
@@ -255,13 +206,10 @@ PHP_METHOD(Timeval, similar) {
* @return Timeval The current time
*/
PHP_METHOD(Timeval, now) {
-#if PHP_MAJOR_VERSION < 7
- zval *now = grpc_php_wrap_timeval(gpr_now(GPR_CLOCK_REALTIME) TSRMLS_CC);
+ zval *now;
+ PHP_GRPC_MAKE_STD_ZVAL(now);
+ now = grpc_php_wrap_timeval(gpr_now(GPR_CLOCK_REALTIME) TSRMLS_CC);
RETURN_DESTROY_ZVAL(now);
-#else
- grpc_php_wrap_timeval(gpr_now(GPR_CLOCK_REALTIME), return_value);
- RETURN_DESTROY_ZVAL(return_value);
-#endif
}
/**
@@ -269,18 +217,13 @@ PHP_METHOD(Timeval, now) {
* @return Timeval Zero length time interval
*/
PHP_METHOD(Timeval, zero) {
-#if PHP_MAJOR_VERSION < 7
- zval *grpc_php_timeval_zero =
+ zval *grpc_php_timeval_zero;
+ PHP_GRPC_MAKE_STD_ZVAL(grpc_php_timeval_zero);
+ grpc_php_timeval_zero =
grpc_php_wrap_timeval(gpr_time_0(GPR_CLOCK_REALTIME) TSRMLS_CC);
RETURN_ZVAL(grpc_php_timeval_zero,
false, /* Copy original before returning? */
true /* Destroy original before returning */);
-#else
- grpc_php_wrap_timeval(gpr_time_0(GPR_CLOCK_REALTIME), return_value);
- RETURN_ZVAL(return_value,
- false, /* Copy original before returning? */
- true /* Destroy original before returning */);
-#endif
}
/**
@@ -288,14 +231,11 @@ PHP_METHOD(Timeval, zero) {
* @return Timeval Infinite future time value
*/
PHP_METHOD(Timeval, infFuture) {
-#if PHP_MAJOR_VERSION < 7
- zval *grpc_php_timeval_inf_future =
+ zval *grpc_php_timeval_inf_future;
+ PHP_GRPC_MAKE_STD_ZVAL(grpc_php_timeval_inf_future);
+ grpc_php_timeval_inf_future =
grpc_php_wrap_timeval(gpr_inf_future(GPR_CLOCK_REALTIME) TSRMLS_CC);
RETURN_DESTROY_ZVAL(grpc_php_timeval_inf_future);
-#else
- grpc_php_wrap_timeval(gpr_inf_future(GPR_CLOCK_REALTIME), return_value);
- RETURN_DESTROY_ZVAL(return_value);
-#endif
}
/**
@@ -303,14 +243,11 @@ PHP_METHOD(Timeval, infFuture) {
* @return Timeval Infinite past time value
*/
PHP_METHOD(Timeval, infPast) {
-#if PHP_MAJOR_VERSION < 7
- zval *grpc_php_timeval_inf_past =
+ zval *grpc_php_timeval_inf_past;
+ PHP_GRPC_MAKE_STD_ZVAL(grpc_php_timeval_inf_past);
+ grpc_php_timeval_inf_past =
grpc_php_wrap_timeval(gpr_inf_past(GPR_CLOCK_REALTIME) TSRMLS_CC);
RETURN_DESTROY_ZVAL(grpc_php_timeval_inf_past);
-#else
- grpc_php_wrap_timeval(gpr_inf_past(GPR_CLOCK_REALTIME), return_value);
- RETURN_DESTROY_ZVAL(return_value);
-#endif
}
/**
@@ -341,13 +278,7 @@ void grpc_init_timeval(TSRMLS_D) {
INIT_CLASS_ENTRY(ce, "Grpc\\Timeval", timeval_methods);
ce.create_object = create_wrapped_grpc_timeval;
grpc_ce_timeval = zend_register_internal_class(&ce TSRMLS_CC);
-#if PHP_MAJOR_VERSION >= 7
- memcpy(&timeval_ce_handlers, zend_get_std_object_handlers(),
- sizeof(zend_object_handlers));
- timeval_ce_handlers.offset =
- XtOffsetOf(wrapped_grpc_timeval, std);
- timeval_ce_handlers.free_obj = free_wrapped_grpc_timeval;
-#endif
+ PHP_GRPC_INIT_HANDLER(wrapped_grpc_timeval, timeval_ce_handlers);
}
void grpc_shutdown_timeval(TSRMLS_D) {}
diff --git a/src/php/ext/grpc/timeval.h b/src/php/ext/grpc/timeval.h
index d362460c05..63a1d702f3 100755
--- a/src/php/ext/grpc/timeval.h
+++ b/src/php/ext/grpc/timeval.h
@@ -50,30 +50,24 @@
extern zend_class_entry *grpc_ce_timeval;
/* Wrapper struct for timeval that can be associated with a PHP object */
-#if PHP_MAJOR_VERSION < 7
-
-typedef struct wrapped_grpc_timeval {
- zend_object std;
+PHP_GRPC_WRAP_OBJECT_START(wrapped_grpc_timeval)
gpr_timespec wrapped;
-} wrapped_grpc_timeval;
+PHP_GRPC_WRAP_OBJECT_END(wrapped_grpc_timeval)
+
+#if PHP_MAJOR_VERSION < 7
#define Z_WRAPPED_GRPC_TIMEVAL_P(zv) \
(wrapped_grpc_timeval *)zend_object_store_get_object(zv TSRMLS_CC)
#else
-typedef struct wrapped_grpc_timeval {
- gpr_timespec wrapped;
- zend_object std;
-} wrapped_grpc_timeval;
-
static inline wrapped_grpc_timeval
*wrapped_grpc_timeval_from_obj(zend_object *obj) {
return (wrapped_grpc_timeval*)((char*)(obj) -
XtOffsetOf(wrapped_grpc_timeval, std));
}
-#define Z_WRAPPED_GRPC_TIMEVAL_P(zv) \
+#define Z_WRAPPED_GRPC_TIMEVAL_P(zv) \
wrapped_grpc_timeval_from_obj(Z_OBJ_P((zv)))
#endif /* PHP_MAJOR_VERSION */
@@ -85,10 +79,6 @@ void grpc_init_timeval(TSRMLS_D);
void grpc_shutdown_timeval(TSRMLS_D);
/* Creates a Timeval object that wraps the given timeval struct */
-#if PHP_MAJOR_VERSION < 7
zval *grpc_php_wrap_timeval(gpr_timespec wrapped TSRMLS_DC);
-#else
-void grpc_php_wrap_timeval(gpr_timespec wrapped, zval *timeval_object);
-#endif /* PHP_MAJOR_VERSION */
#endif /* NET_GRPC_PHP_GRPC_TIMEVAL_H_ */
diff --git a/src/proto/census/census.proto b/src/proto/census/census.proto
index c869d851ff..c2a594b641 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
@@ -124,7 +121,7 @@ message Metric {
// 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):
@@ -141,32 +138,40 @@ 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
- // 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
@@ -196,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
@@ -243,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;
@@ -251,7 +256,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 +269,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;
@@ -291,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 ViewAggregations represents all the Aggregations for a particular view.
-message ViewAggregations {
+// 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 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;
- Timestamp end = 3;
+ Timestamp start = 3;
+ Timestamp end = 4;
}
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index fc0908b2f1..7ae76f52c1 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -162,6 +162,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',
@@ -184,7 +185,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',
@@ -240,6 +240,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c',
'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c',
+ 'src/core/ext/lb_policy/grpclb/grpclb.c',
'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
'third_party/nanopb/pb_common.c',
@@ -251,6 +252,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/resolver/sockaddr/sockaddr_resolver.c',
'src/core/ext/load_reporting/load_reporting.c',
'src/core/ext/load_reporting/load_reporting_filter.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',
@@ -260,6 +262,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/.rubocop.yml b/src/ruby/.rubocop.yml
index 34bb477543..0f61ccfa81 100644
--- a/src/ruby/.rubocop.yml
+++ b/src/ruby/.rubocop.yml
@@ -5,8 +5,8 @@ inherit_from: .rubocop_todo.yml
AllCops:
Exclude:
- 'bin/apis/**/*'
- - 'bin/math.rb'
- - 'bin/math_services.rb'
+ - 'bin/math_pb.rb'
+ - 'bin/math_services_pb.rb'
- 'pb/grpc/health/v1/*'
- 'pb/test/**/*'
diff --git a/src/ruby/bin/math_client.rb b/src/ruby/bin/math_client.rb
index d7e00e4293..1f238a798b 100755
--- a/src/ruby/bin/math_client.rb
+++ b/src/ruby/bin/math_client.rb
@@ -40,7 +40,7 @@ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
require 'grpc'
-require 'math_services'
+require 'math_services_pb'
require 'optparse'
include GRPC::Core::TimeConsts
diff --git a/src/ruby/bin/math.rb b/src/ruby/bin/math_pb.rb
index 60429a1505..60429a1505 100755..100644
--- a/src/ruby/bin/math.rb
+++ b/src/ruby/bin/math_pb.rb
diff --git a/src/ruby/bin/math_server.rb b/src/ruby/bin/math_server.rb
index 1ee4c5632d..751a6ebcab 100755
--- a/src/ruby/bin/math_server.rb
+++ b/src/ruby/bin/math_server.rb
@@ -42,7 +42,7 @@ $LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
require 'forwardable'
require 'grpc'
require 'logger'
-require 'math_services'
+require 'math_services_pb'
require 'optparse'
# RubyLogger defines a logger for gRPC based on the standard ruby logger.
diff --git a/src/ruby/bin/math_services.rb b/src/ruby/bin/math_services_pb.rb
index 2b97602b6f..2ba1825d4f 100755..100644
--- a/src/ruby/bin/math_services.rb
+++ b/src/ruby/bin/math_services_pb.rb
@@ -32,7 +32,7 @@
#
require 'grpc'
-require 'math'
+require 'math_pb'
module Math
module Math
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
index d7f862cd9c..aee57b11aa 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;
@@ -334,15 +329,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 14da63780c..3bb76fbb97 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/src/ruby/pb/grpc/health/checker.rb b/src/ruby/pb/grpc/health/checker.rb
index f7310d9289..4bce1744c4 100644
--- a/src/ruby/pb/grpc/health/checker.rb
+++ b/src/ruby/pb/grpc/health/checker.rb
@@ -28,7 +28,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
require 'grpc'
-require 'grpc/health/v1/health_services'
+require 'grpc/health/v1/health_services_pb'
require 'thread'
module Grpc
diff --git a/src/ruby/pb/grpc/health/v1/health.rb b/src/ruby/pb/grpc/health/v1/health_pb.rb
index aa87a93918..aa87a93918 100644
--- a/src/ruby/pb/grpc/health/v1/health.rb
+++ b/src/ruby/pb/grpc/health/v1/health_pb.rb
diff --git a/src/ruby/pb/grpc/health/v1/health_services.rb b/src/ruby/pb/grpc/health/v1/health_services_pb.rb
index 68a3956f54..8cc01e91dc 100644
--- a/src/ruby/pb/grpc/health/v1/health_services.rb
+++ b/src/ruby/pb/grpc/health/v1/health_services_pb.rb
@@ -32,7 +32,7 @@
#
require 'grpc'
-require 'grpc/health/v1/health'
+require 'grpc/health/v1/health_pb'
module Grpc
module Health
diff --git a/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services.rb b/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services_pb.rb
index eb523ffa6f..e51c2f087a 100644
--- a/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services.rb
+++ b/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services_pb.rb
@@ -1,5 +1,5 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
-# Source: grpc/testing/duplicate/echo_duplicate.proto for package 'grpc.testing.duplicate'
+# Source: src/proto/grpc/testing/duplicate/echo_duplicate.proto for package 'grpc.testing.duplicate'
# Original file comments:
# Copyright 2015, Google Inc.
# All rights reserved.
@@ -34,7 +34,7 @@
#
require 'grpc'
-require 'grpc/testing/duplicate/echo_duplicate'
+require 'src/proto/grpc/testing/duplicate/echo_duplicate_pb'
module Grpc
module Testing
diff --git a/src/ruby/pb/grpc/testing/metrics.rb b/src/ruby/pb/grpc/testing/metrics_pb.rb
index 3b3c8cd61b..77b6c90970 100644
--- a/src/ruby/pb/grpc/testing/metrics.rb
+++ b/src/ruby/pb/grpc/testing/metrics_pb.rb
@@ -1,5 +1,5 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
-# source: grpc/testing/metrics.proto
+# source: src/proto/grpc/testing/metrics.proto
require 'google/protobuf'
diff --git a/src/ruby/pb/grpc/testing/metrics_services.rb b/src/ruby/pb/grpc/testing/metrics_services_pb.rb
index 467b7b3ee5..e46366b1fb 100644
--- a/src/ruby/pb/grpc/testing/metrics_services.rb
+++ b/src/ruby/pb/grpc/testing/metrics_services_pb.rb
@@ -1,5 +1,5 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
-# Source: grpc/testing/metrics.proto for package 'grpc.testing'
+# Source: src/proto/grpc/testing/metrics.proto for package 'grpc.testing'
# Original file comments:
# Copyright 2015-2016, Google Inc.
# All rights reserved.
@@ -38,7 +38,7 @@
# service.
require 'grpc'
-require 'grpc/testing/metrics'
+require 'src/proto/grpc/testing/metrics_pb'
module Grpc
module Testing
diff --git a/src/ruby/pb/src/proto/grpc/testing/empty.rb b/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb
index 9c2568d605..9c2568d605 100644
--- a/src/ruby/pb/src/proto/grpc/testing/empty.rb
+++ b/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb
diff --git a/src/ruby/pb/src/proto/grpc/testing/messages.rb b/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb
index e27ccd0dc0..e27ccd0dc0 100644
--- a/src/ruby/pb/src/proto/grpc/testing/messages.rb
+++ b/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb
diff --git a/src/ruby/pb/src/proto/grpc/testing/test.rb b/src/ruby/pb/src/proto/grpc/testing/test_pb.rb
index 245b5ce00c..2cc9863031 100644
--- a/src/ruby/pb/src/proto/grpc/testing/test.rb
+++ b/src/ruby/pb/src/proto/grpc/testing/test_pb.rb
@@ -3,8 +3,8 @@
require 'google/protobuf'
-require 'src/proto/grpc/testing/empty'
-require 'src/proto/grpc/testing/messages'
+require 'src/proto/grpc/testing/empty_pb'
+require 'src/proto/grpc/testing/messages_pb'
Google::Protobuf::DescriptorPool.generated_pool.build do
end
diff --git a/src/ruby/pb/src/proto/grpc/testing/test_services.rb b/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb
index 2652de5e6d..fde328e4c5 100644
--- a/src/ruby/pb/src/proto/grpc/testing/test_services.rb
+++ b/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb
@@ -35,7 +35,7 @@
#
require 'grpc'
-require 'src/proto/grpc/testing/test'
+require 'src/proto/grpc/testing/test_pb'
module Grpc
module Testing
diff --git a/src/ruby/pb/test/client.rb b/src/ruby/pb/test/client.rb
index 4c6d441dcb..1e3ae65630 100755
--- a/src/ruby/pb/test/client.rb
+++ b/src/ruby/pb/test/client.rb
@@ -52,9 +52,9 @@ require_relative '../../lib/grpc'
require 'googleauth'
require 'google/protobuf'
-require_relative '../src/proto/grpc/testing/empty'
-require_relative '../src/proto/grpc/testing/messages'
-require_relative '../src/proto/grpc/testing/test_services'
+require_relative '../src/proto/grpc/testing/empty_pb'
+require_relative '../src/proto/grpc/testing/messages_pb'
+require_relative '../src/proto/grpc/testing/test_services_pb'
AUTH_ENV = Google::Auth::CredentialsLoader::ENV_VAR
diff --git a/src/ruby/pb/test/server.rb b/src/ruby/pb/test/server.rb
index 11ee3d465d..0808121661 100755
--- a/src/ruby/pb/test/server.rb
+++ b/src/ruby/pb/test/server.rb
@@ -50,9 +50,9 @@ require 'optparse'
require 'grpc'
-require_relative '../src/proto/grpc/testing/empty'
-require_relative '../src/proto/grpc/testing/messages'
-require_relative '../src/proto/grpc/testing/test_services'
+require_relative '../src/proto/grpc/testing/empty_pb'
+require_relative '../src/proto/grpc/testing/messages_pb'
+require_relative '../src/proto/grpc/testing/test_services_pb'
# DebugIsTruncated extends the default Logger to truncate debug messages
class DebugIsTruncated < Logger
diff --git a/src/ruby/qps/client.rb b/src/ruby/qps/client.rb
index 917b01271e..7ed648acef 100644
--- a/src/ruby/qps/client.rb
+++ b/src/ruby/qps/client.rb
@@ -38,7 +38,7 @@ $LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
require 'grpc'
require 'histogram'
-require 'src/proto/grpc/testing/services_services'
+require 'src/proto/grpc/testing/services_services_pb'
class Poisson
def interarrival
diff --git a/src/ruby/qps/server.rb b/src/ruby/qps/server.rb
index 52a89ce847..cd98ee1fd9 100644
--- a/src/ruby/qps/server.rb
+++ b/src/ruby/qps/server.rb
@@ -38,9 +38,9 @@ $LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
require 'grpc'
require 'qps-common'
-require 'src/proto/grpc/testing/messages'
-require 'src/proto/grpc/testing/services_services'
-require 'src/proto/grpc/testing/stats'
+require 'src/proto/grpc/testing/messages_pb'
+require 'src/proto/grpc/testing/services_services_pb'
+require 'src/proto/grpc/testing/stats_pb'
class BenchmarkServiceImpl < Grpc::Testing::BenchmarkService::Service
def unary_call(req, _call)
diff --git a/src/ruby/qps/src/proto/grpc/testing/control.rb b/src/ruby/qps/src/proto/grpc/testing/control_pb.rb
index 958fca320b..02207a2b5d 100644
--- a/src/ruby/qps/src/proto/grpc/testing/control.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/control_pb.rb
@@ -3,8 +3,8 @@
require 'google/protobuf'
-require 'src/proto/grpc/testing/payloads'
-require 'src/proto/grpc/testing/stats'
+require 'src/proto/grpc/testing/payloads_pb'
+require 'src/proto/grpc/testing/stats_pb'
Google::Protobuf::DescriptorPool.generated_pool.build do
add_message "grpc.testing.PoissonParams" do
optional :offered_load, :double, 1
@@ -109,6 +109,8 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
repeated :server_stats, :message, 4, "grpc.testing.ServerStats"
repeated :server_cores, :int32, 5
optional :summary, :message, 6, "grpc.testing.ScenarioResultSummary"
+ repeated :client_success, :bool, 7
+ repeated :server_success, :bool, 8
end
add_enum "grpc.testing.ClientType" do
value :SYNC_CLIENT, 0
diff --git a/src/ruby/qps/src/proto/grpc/testing/messages.rb b/src/ruby/qps/src/proto/grpc/testing/messages_pb.rb
index e27ccd0dc0..e27ccd0dc0 100644
--- a/src/ruby/qps/src/proto/grpc/testing/messages.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/messages_pb.rb
diff --git a/src/ruby/qps/src/proto/grpc/testing/payloads.rb b/src/ruby/qps/src/proto/grpc/testing/payloads_pb.rb
index ae8855f685..ae8855f685 100644
--- a/src/ruby/qps/src/proto/grpc/testing/payloads.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/payloads_pb.rb
diff --git a/src/ruby/qps/src/proto/grpc/testing/services.rb b/src/ruby/qps/src/proto/grpc/testing/services_pb.rb
index b2675c2afe..5ce13bf8b0 100644
--- a/src/ruby/qps/src/proto/grpc/testing/services.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/services_pb.rb
@@ -3,8 +3,8 @@
require 'google/protobuf'
-require 'src/proto/grpc/testing/messages'
-require 'src/proto/grpc/testing/control'
+require 'src/proto/grpc/testing/messages_pb'
+require 'src/proto/grpc/testing/control_pb'
Google::Protobuf::DescriptorPool.generated_pool.build do
end
diff --git a/src/ruby/qps/src/proto/grpc/testing/services_services.rb b/src/ruby/qps/src/proto/grpc/testing/services_services_pb.rb
index 94b9a1e164..bdbb9c86d0 100644
--- a/src/ruby/qps/src/proto/grpc/testing/services_services.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/services_services_pb.rb
@@ -34,7 +34,7 @@
# of unary/streaming requests/responses.
require 'grpc'
-require 'src/proto/grpc/testing/services'
+require 'src/proto/grpc/testing/services_pb'
module Grpc
module Testing
diff --git a/src/ruby/qps/src/proto/grpc/testing/stats.rb b/src/ruby/qps/src/proto/grpc/testing/stats_pb.rb
index 41f75bedf0..41f75bedf0 100644
--- a/src/ruby/qps/src/proto/grpc/testing/stats.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/stats_pb.rb
diff --git a/src/ruby/qps/worker.rb b/src/ruby/qps/worker.rb
index 665fb86352..12b8087ca0 100755
--- a/src/ruby/qps/worker.rb
+++ b/src/ruby/qps/worker.rb
@@ -44,7 +44,7 @@ require 'facter'
require 'client'
require 'qps-common'
require 'server'
-require 'src/proto/grpc/testing/services_services'
+require 'src/proto/grpc/testing/services_services_pb'
class WorkerServiceImpl < Grpc::Testing::WorkerService::Service
def cpu_cores
diff --git a/src/ruby/spec/pb/duplicate/codegen_spec.rb b/src/ruby/spec/pb/duplicate/codegen_spec.rb
index 54c136c510..ea0240965c 100644
--- a/src/ruby/spec/pb/duplicate/codegen_spec.rb
+++ b/src/ruby/spec/pb/duplicate/codegen_spec.rb
@@ -44,7 +44,7 @@ describe 'Ping protobuf code generation' do
# Get the current content
service_path = File.join(root_dir, 'src', 'ruby', 'pb', 'grpc',
'testing', 'duplicate',
- 'echo_duplicate_services.rb')
+ 'echo_duplicate_services_pb.rb')
want = nil
File.open(service_path) { |f| want = f.read }
@@ -54,7 +54,7 @@ describe 'Ping protobuf code generation' do
got = nil
Dir.mktmpdir do |tmp_dir|
gen_out = File.join(tmp_dir, 'src', 'proto', 'grpc', 'testing',
- 'duplicate', 'echo_duplicate_services.rb')
+ 'duplicate', 'echo_duplicate_services_pb.rb')
pid = spawn(
'protoc',
'-I.',
diff --git a/src/ruby/spec/pb/health/checker_spec.rb b/src/ruby/spec/pb/health/checker_spec.rb
index de11c9fedf..1b2fa96827 100644
--- a/src/ruby/spec/pb/health/checker_spec.rb
+++ b/src/ruby/spec/pb/health/checker_spec.rb
@@ -28,7 +28,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
require 'grpc'
-require 'grpc/health/v1/health'
+require 'grpc/health/v1/health_pb'
require 'grpc/health/checker'
require 'open3'
require 'tmpdir'
@@ -43,7 +43,7 @@ describe 'Health protobuf code generation' do
skip 'protoc || grpc_ruby_plugin missing, cannot verify health code-gen'
else
it 'should already be loaded indirectly i.e, used by the other specs' do
- expect(require('grpc/health/v1/health_services')).to be(false)
+ expect(require('grpc/health/v1/health_services_pb')).to be(false)
end
it 'should have the same content as created by code generation' do
@@ -52,7 +52,7 @@ describe 'Health protobuf code generation' do
# Get the current content
service_path = File.join(root_dir, 'ruby', 'pb', 'grpc',
- 'health', 'v1', 'health_services.rb')
+ 'health', 'v1', 'health_services_pb.rb')
want = nil
File.open(service_path) { |f| want = f.read }
@@ -62,7 +62,7 @@ describe 'Health protobuf code generation' do
got = nil
Dir.mktmpdir do |tmp_dir|
gen_out = File.join(tmp_dir, 'grpc', 'health', 'v1',
- 'health_services.rb')
+ 'health_services_pb.rb')
pid = spawn(
'protoc',
'-I.',
diff --git a/src/ruby/stress/metrics_server.rb b/src/ruby/stress/metrics_server.rb
index 13638c4d21..2b7f78577d 100644
--- a/src/ruby/stress/metrics_server.rb
+++ b/src/ruby/stress/metrics_server.rb
@@ -27,8 +27,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-require_relative '../pb/grpc/testing/metrics.rb'
-require_relative '../pb/grpc/testing/metrics_services.rb'
+require_relative '../pb/grpc/testing/metrics_pb.rb'
+require_relative '../pb/grpc/testing/metrics_services_pb.rb'
class Gauge
def get_name
diff --git a/src/ruby/tools/bin/grpc_tools_ruby_protoc.rb b/src/ruby/tools/bin/grpc_tools_ruby_protoc
index 3a2a5b8dc9..dab06e7958 100755
--- a/src/ruby/tools/bin/grpc_tools_ruby_protoc.rb
+++ b/src/ruby/tools/bin/grpc_tools_ruby_protoc
@@ -32,10 +32,17 @@ require 'rbconfig'
require_relative '../os_check'
-protoc_name = 'protoc' + RbConfig::CONFIG['EXEEXT']
+ext = RbConfig::CONFIG['EXEEXT']
-protoc_path = File.join(File.dirname(__FILE__),
- RbConfig::CONFIG['host_cpu'] + '-' + OS.os_name,
- protoc_name)
+protoc_name = 'protoc' + ext
-exec([ protoc_path, protoc_path ], *ARGV)
+plugin_name = 'grpc_ruby_plugin' + ext
+
+protoc_dir = File.join(File.dirname(__FILE__),
+ RbConfig::CONFIG['host_cpu'] + '-' + OS.os_name)
+
+protoc_path = File.join(protoc_dir, protoc_name)
+
+plugin_path = File.join(protoc_dir, plugin_name)
+
+exec([ protoc_path, protoc_path ], "--plugin=protoc-gen-grpc=#{plugin_path}", *ARGV)
diff --git a/src/ruby/tools/bin/grpc_tools_ruby_protoc_plugin.rb b/src/ruby/tools/bin/grpc_tools_ruby_protoc_plugin
index 4b296dedc7..4b296dedc7 100755
--- a/src/ruby/tools/bin/grpc_tools_ruby_protoc_plugin.rb
+++ b/src/ruby/tools/bin/grpc_tools_ruby_protoc_plugin
diff --git a/src/ruby/tools/grpc-tools.gemspec b/src/ruby/tools/grpc-tools.gemspec
index 9fa4b66392..68e2a7a113 100644
--- a/src/ruby/tools/grpc-tools.gemspec
+++ b/src/ruby/tools/grpc-tools.gemspec
@@ -18,5 +18,5 @@ Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
- s.executables = %w( grpc_tools_ruby_protoc.rb grpc_tools_ruby_protoc_plugin.rb )
+ s.executables = %w( grpc_tools_ruby_protoc grpc_tools_ruby_protoc_plugin )
end