Merge github.com:grpc/grpc into compress

pull/5052/head
Craig Tiller 9 years ago
commit 97cb41cfaf
  1. 6
      BUILD
  2. 404
      Makefile
  3. 1
      binding.gyp
  4. 19
      build.yaml
  5. 2
      examples/cpp/helloworld/Makefile
  6. 4
      examples/cpp/route_guide/Makefile
  7. 3
      gRPC.podspec
  8. 18
      grpc.def
  9. 2
      grpc.gemspec
  10. 13
      include/grpc++/impl/codegen/server_context.h
  11. 314
      include/grpc/census.h
  12. 2
      include/grpc/impl/codegen/compression_types.h
  13. 17
      include/grpc/impl/codegen/port_platform.h
  14. 2
      include/grpc/impl/codegen/propagation_bits.h
  15. 3
      package.json
  16. 39
      setup.py
  17. 500
      src/core/census/context.c
  18. 9
      src/core/census/placeholders.c
  19. 535
      src/core/census/tag_set.c
  20. 12
      src/core/support/stack_lockfree.c
  21. 16
      src/cpp/server/server_context.cc
  22. 2
      src/csharp/Grpc.Core/Internal/NativeExtension.cs
  23. 10
      src/node/performance/worker_service_impl.js
  24. 3
      src/proto/grpc/testing/control.proto
  25. 3
      src/proto/grpc/testing/services.proto
  26. 28
      src/python/grpcio/commands.py
  27. 3
      src/python/grpcio/grpc/_cython/.gitignore
  28. 26
      src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
  29. 9
      src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
  30. 15
      src/python/grpcio/grpc/_cython/cygrpc.pyx
  31. 564
      src/python/grpcio/grpc/_cython/imports.generated.c
  32. 860
      src/python/grpcio/grpc/_cython/imports.generated.h
  33. 34
      src/python/grpcio/grpc/_cython/loader.c
  34. 45
      src/python/grpcio/grpc/_cython/loader.h
  35. 1
      src/python/grpcio/grpc_core_dependencies.py
  36. 10
      src/ruby/ext/grpc/extconf.rb
  37. 36
      src/ruby/ext/grpc/rb_grpc_imports.generated.c
  38. 58
      src/ruby/ext/grpc/rb_grpc_imports.generated.h
  39. 53
      templates/Makefile.template
  40. 52
      templates/src/python/grpcio/grpc/_cython/imports.generated.c.template
  41. 70
      templates/src/python/grpcio/grpc/_cython/imports.generated.h.template
  42. 280
      test/core/census/context_test.c
  43. 410
      test/cpp/end2end/async_end2end_test.cc
  44. 298
      test/cpp/end2end/end2end_test.cc
  45. 165
      test/cpp/end2end/test_service_impl.cc
  46. 17
      test/cpp/end2end/test_service_impl.h
  47. 139
      test/cpp/end2end/thread_stress_test.cc
  48. 34
      test/cpp/qps/client_async.cc
  49. 13
      test/cpp/qps/driver.cc
  50. 1
      test/cpp/qps/driver.h
  51. 7
      test/cpp/qps/limit_cores.cc
  52. 2
      test/cpp/qps/limit_cores.h
  53. 7
      test/cpp/qps/qps_driver.cc
  54. 24
      test/cpp/qps/qps_worker.cc
  55. 7
      test/cpp/qps/qps_worker.h
  56. 2
      test/cpp/qps/worker.cc
  57. 57
      test/distrib/node/distrib_test.js
  58. 7
      test/distrib/node/package.json
  59. 52
      test/distrib/node/run_distrib_test.sh
  60. 7
      test/distrib/python/distribtest.py
  61. 24
      test/distrib/python/run_distrib_test.sh
  62. 2
      tools/dockerfile/distribtest/csharp_jessie_x64/Dockerfile
  63. 2
      tools/dockerfile/distribtest/csharp_jessie_x86/Dockerfile
  64. 40
      tools/dockerfile/distribtest/csharp_ubuntu1404_x64/Dockerfile
  65. 40
      tools/dockerfile/distribtest/csharp_ubuntu1504_x64/Dockerfile
  66. 40
      tools/dockerfile/distribtest/csharp_ubuntu1510_x64/Dockerfile
  67. 37
      tools/dockerfile/distribtest/csharp_ubuntu1604_x64/Dockerfile
  68. 37
      tools/dockerfile/distribtest/node_centos7_x64/Dockerfile
  69. 36
      tools/dockerfile/distribtest/node_jessie_x64/Dockerfile
  70. 36
      tools/dockerfile/distribtest/node_jessie_x86/Dockerfile
  71. 36
      tools/dockerfile/distribtest/node_ubuntu1204_x64/Dockerfile
  72. 36
      tools/dockerfile/distribtest/node_ubuntu1404_x64/Dockerfile
  73. 36
      tools/dockerfile/distribtest/node_ubuntu1504_x64/Dockerfile
  74. 36
      tools/dockerfile/distribtest/node_ubuntu1510_x64/Dockerfile
  75. 36
      tools/dockerfile/distribtest/node_ubuntu1604_x64/Dockerfile
  76. 36
      tools/dockerfile/distribtest/node_wheezy_x64/Dockerfile
  77. 2
      tools/doxygen/Doxyfile.core.internal
  78. 0
      tools/jenkins/build_packages.sh
  79. 2
      tools/jenkins/docker_run.sh
  80. 49
      tools/jenkins/run_distribtest.sh
  81. 16
      tools/run_tests/artifact_targets.py
  82. 12
      tools/run_tests/build_artifact_python.sh
  83. 2
      tools/run_tests/build_artifact_ruby.sh
  84. 40
      tools/run_tests/build_package_node.sh
  85. 41
      tools/run_tests/distribtest_targets.py
  86. 37
      tools/run_tests/package_targets.py
  87. 30
      tools/run_tests/sources_and_headers.json
  88. 40
      tools/run_tests/tests.json
  89. 50
      vsprojects/buildtests_c.sln
  90. 3
      vsprojects/vcxproj/grpc/grpc.vcxproj
  91. 6
      vsprojects/vcxproj/grpc/grpc.vcxproj.filters
  92. 3
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
  93. 6
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
  94. 8
      vsprojects/vcxproj/test/census_context_test/census_context_test.vcxproj
  95. 8
      vsprojects/vcxproj/test/census_context_test/census_context_test.vcxproj.filters

@ -182,7 +182,6 @@ cc_library(
"src/core/support/thd_internal.h",
"src/core/support/time_precise.h",
"src/core/census/aggregation.h",
"src/core/census/context.h",
"src/core/census/rpc_metric_id.h",
"src/core/httpcli/httpcli_security_connector.c",
"src/core/security/base64.c",
@ -379,7 +378,6 @@ cc_library(
"src/core/census/initialize.c",
"src/core/census/operation.c",
"src/core/census/placeholders.c",
"src/core/census/tag_set.c",
"src/core/census/tracing.c",
],
hdrs = [
@ -580,7 +578,6 @@ cc_library(
"src/core/transport/transport.h",
"src/core/transport/transport_impl.h",
"src/core/census/aggregation.h",
"src/core/census/context.h",
"src/core/census/rpc_metric_id.h",
"src/core/surface/init_unsecure.c",
"src/core/profiling/basic_timers.c",
@ -757,7 +754,6 @@ cc_library(
"src/core/census/initialize.c",
"src/core/census/operation.c",
"src/core/census/placeholders.c",
"src/core/census/tag_set.c",
"src/core/census/tracing.c",
],
hdrs = [
@ -1405,7 +1401,6 @@ objc_library(
"src/core/census/initialize.c",
"src/core/census/operation.c",
"src/core/census/placeholders.c",
"src/core/census/tag_set.c",
"src/core/census/tracing.c",
],
hdrs = [
@ -1602,7 +1597,6 @@ objc_library(
"src/core/support/thd_internal.h",
"src/core/support/time_precise.h",
"src/core/census/aggregation.h",
"src/core/census/context.h",
"src/core/census/rpc_metric_id.h",
],
includes = [

File diff suppressed because it is too large Load Diff

@ -685,7 +685,6 @@
'src/core/census/initialize.c',
'src/core/census/operation.c',
'src/core/census/placeholders.c',
'src/core/census/tag_set.c',
'src/core/census/tracing.c',
],
"conditions": [

@ -14,14 +14,12 @@ filegroups:
- include/grpc/census.h
headers:
- src/core/census/aggregation.h
- src/core/census/context.h
- src/core/census/rpc_metric_id.h
src:
- src/core/census/context.c
- src/core/census/initialize.c
- src/core/census/operation.c
- src/core/census/placeholders.c
- src/core/census/tag_set.c
- src/core/census/tracing.c
- name: gpr
public_headers:
@ -896,6 +894,14 @@ targets:
deps:
- grpc_test_util
- grpc
- name: census_context_test
build: test
language: c
src:
- test/core/census/context_test.c
deps:
- grpc_test_util
- grpc
- name: channel_create_test
build: test
language: c
@ -1561,14 +1567,6 @@ targets:
- mac
- linux
- posix
- name: tag_set_test
build: test
language: c
src:
- test/core/census/tag_set_test.c
deps:
- grpc_test_util
- grpc
- name: tcp_client_posix_test
cpu_cost: 0.5
build: test
@ -2453,6 +2451,7 @@ node_modules:
- src/node/src/client.js
- src/node/src/common.js
- src/node/src/credentials.js
- src/node/src/grpc_extension.js
- src/node/src/metadata.js
- src/node/src/server.js
name: grpc_node

@ -32,7 +32,7 @@
CXX = g++
CPPFLAGS += -I/usr/local/include -pthread
CXXFLAGS += -std=c++11
LDFLAGS += -L/usr/local/lib -lgrpc++_unsecure -lgrpc -lgpr -lprotobuf -lpthread -ldl
LDFLAGS += -L/usr/local/lib -lgrpc++_unsecure -lgrpc -lprotobuf -lpthread -ldl
PROTOC = protoc
GRPC_CPP_PLUGIN = grpc_cpp_plugin
GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)`

@ -1,5 +1,5 @@
#
# Copyright 2015, Google Inc.
# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@ -32,7 +32,7 @@
CXX = g++
CPPFLAGS += -I/usr/local/include -pthread
CXXFLAGS += -std=c++11
LDFLAGS += -L/usr/local/lib -lgrpc++_unsecure -lgrpc -lgpr -lprotobuf -lpthread -ldl
LDFLAGS += -L/usr/local/lib -lgrpc++_unsecure -lgrpc -lprotobuf -lpthread -ldl
PROTOC = protoc
GRPC_CPP_PLUGIN = grpc_cpp_plugin
GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)`

@ -201,7 +201,6 @@ Pod::Spec.new do |s|
'src/core/support/thd_internal.h',
'src/core/support/time_precise.h',
'src/core/census/aggregation.h',
'src/core/census/context.h',
'src/core/census/rpc_metric_id.h',
'include/grpc/grpc_security.h',
'include/grpc/byte_buffer.h',
@ -453,7 +452,6 @@ Pod::Spec.new do |s|
'src/core/census/initialize.c',
'src/core/census/operation.c',
'src/core/census/placeholders.c',
'src/core/census/tag_set.c',
'src/core/census/tracing.c'
ss.private_header_files = 'src/core/security/auth_filters.h',
@ -594,7 +592,6 @@ Pod::Spec.new do |s|
'src/core/support/thd_internal.h',
'src/core/support/time_precise.h',
'src/core/census/aggregation.h',
'src/core/census/context.h',
'src/core/census/rpc_metric_id.h'
ss.header_mappings_dir = '.'

@ -3,7 +3,14 @@ EXPORTS
census_shutdown
census_supported
census_enabled
census_context_serialize
census_context_create
census_context_destroy
census_context_get_status
census_context_initialize_iterator
census_context_next_tag
census_context_get_tag
census_context_encode
census_context_decode
census_trace_mask
census_set_trace_mask
census_start_rpc_op_timestamp
@ -16,15 +23,6 @@ EXPORTS
census_trace_scan_start
census_get_trace_record
census_trace_scan_end
census_tag_set_create
census_tag_set_destroy
census_tag_set_get_create_status
census_tag_set_initialize_iterator
census_tag_set_next_tag
census_tag_set_get_tag_by_key
census_tag_set_encode
census_tag_set_decode
census_context_tag_set
census_record_values
census_view_create
census_view_delete

@ -240,7 +240,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/support/thd_internal.h )
s.files += %w( src/core/support/time_precise.h )
s.files += %w( src/core/census/aggregation.h )
s.files += %w( src/core/census/context.h )
s.files += %w( src/core/census/rpc_metric_id.h )
s.files += %w( src/core/httpcli/httpcli_security_connector.c )
s.files += %w( src/core/security/base64.c )
@ -437,7 +436,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/census/initialize.c )
s.files += %w( src/core/census/operation.c )
s.files += %w( src/core/census/placeholders.c )
s.files += %w( src/core/census/tag_set.c )
s.files += %w( src/core/census/tracing.c )
s.files += %w( third_party/boringssl/crypto/aes/internal.h )
s.files += %w( third_party/boringssl/crypto/asn1/asn1_locl.h )

@ -105,6 +105,19 @@ class ServerContext {
bool IsCancelled() const;
// Cancel the Call from the server. This is a best-effort API and depending on
// when it is called, the RPC may still appear successful to the client.
// For example, if TryCancel() is called on a separate thread, it might race
// with the server handler which might return success to the client before
// TryCancel() was even started by the thread.
//
// It is the caller's responsibility to prevent such races and ensure that if
// TryCancel() is called, the serverhandler must return Status::CANCELLED. The
// only exception is that if the serverhandler is already returning an error
// status code, it is ok to not return Status::CANCELLED even if TryCancel()
// was called.
void TryCancel() const;
const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata() {
return client_metadata_;
}

@ -70,28 +70,148 @@ CENSUS_API int census_supported(void);
CENSUS_API int census_enabled(void);
/**
Context is a handle used by census to represent the current tracing and
tagging information. Contexts should be propagated across RPC's. Contexts
are created by any of the census_start_*_op() functions. A context is
typically used as argument to most census functions. Conceptually, contexts
should be thought of as specific to single RPC/thread. The context can be
serialized for passing across the wire, via census_context_serialize().
*/
A Census Context is a handle used by Census to represent the current tracing
and stats collection information. Contexts should be propagated across RPC's
(this is the responsibility of the local RPC system). A context is typically
used as the first argument to most census functions. Conceptually, they
should be thought of as specific to a single RPC/thread. The user visible
context representation is that of a collection of key:value string pairs,
each of which is termed a 'tag'; these form the basis against which Census
metrics will be recorded. Keys are unique within a context. */
typedef struct census_context census_context;
/* This function is called by the RPC subsystem whenever it needs to get a
* serialized form of the current census context (presumably to pass across
* the wire). Arguments:
* 'buffer': pointer to memory into which serialized context will be placed
* 'buf_size': size of 'buffer'
*
* Returns: the number of bytes used in buffer if successful, or 0 if the
* buffer is of insufficient size.
*
* TODO(aveitch): determine how best to communicate required/max buffer size
* so caller doesn't have to guess. */
CENSUS_API size_t census_context_serialize(const census_context *context,
char *buffer, size_t buf_size);
/* A tag is a key:value pair. The key is a non-empty, printable (UTF-8
encoded), nil-terminated string. The value is a binary string, that may be
printable. There are limits on the sizes of both keys and values (see
CENSUS_MAX_TAG_KB_LEN definition below), and the number of tags that can be
propagated (CENSUS_MAX_PROPAGATED_TAGS). Users should also remember that
some systems may have limits on, e.g., the number of bytes that can be
transmitted as metadata, and that larger tags means more memory consumed
and time in processing. */
typedef struct {
const char *key;
const char *value;
size_t value_len;
uint8_t flags;
} census_tag;
/* Maximum length of a tag's key or value. */
#define CENSUS_MAX_TAG_KV_LEN 255
/* Maximum number of propagatable tags. */
#define CENSUS_MAX_PROPAGATED_TAGS 255
/* Tag flags. */
#define CENSUS_TAG_PROPAGATE 1 /* Tag should be propagated over RPC */
#define CENSUS_TAG_STATS 2 /* Tag will be used for statistics aggregation */
#define CENSUS_TAG_BINARY 4 /* Tag value is not printable */
#define CENSUS_TAG_RESERVED 8 /* Reserved for internal use. */
/* Flag values 8,16,32,64,128 are reserved for future/internal use. Clients
should not use or rely on their values. */
#define CENSUS_TAG_IS_PROPAGATED(flags) (flags & CENSUS_TAG_PROPAGATE)
#define CENSUS_TAG_IS_STATS(flags) (flags & CENSUS_TAG_STATS)
#define CENSUS_TAG_IS_BINARY(flags) (flags & CENSUS_TAG_BINARY)
/* An instance of this structure is kept by every context, and records the
basic information associated with the creation of that context. */
typedef struct {
int n_propagated_tags; /* number of propagated printable tags */
int n_propagated_binary_tags; /* number of propagated binary tags */
int n_local_tags; /* number of non-propagated (local) tags */
int n_deleted_tags; /* number of tags that were deleted */
int n_added_tags; /* number of tags that were added */
int n_modified_tags; /* number of tags that were modified */
int n_invalid_tags; /* number of tags with bad keys or values (e.g.
longer than CENSUS_MAX_TAG_KV_LEN) */
int n_ignored_tags; /* number of tags ignored because of
CENSUS_MAX_PROPAGATED_TAGS limit. */
} census_context_status;
/* Create a new context, adding and removing tags from an existing context.
This will copy all tags from the 'tags' input, so it is recommended
to add as many tags in a single operation as is practical for the client.
@param base Base context to build upon. Can be NULL.
@param tags A set of tags to be added/changed/deleted. Tags with keys that
are in 'tags', but not 'base', are added to the tag set. Keys that are in
both 'tags' and 'base' will have their value/flags modified. Tags with keys
in both, but with NULL or zero-length values, will be deleted from the tag
set. Tags with invalid (too long or short) keys or values will be ignored.
If adding a tag will result in more than CENSUS_MAX_PROPAGATED_TAGS in either
binary or non-binary tags, they will be ignored, as will deletions of
tags that don't exist.
@param ntags number of tags in 'tags'
@param status If not NULL, will return a pointer to a census_context_status
structure containing information about the new context and status of the
tags used in its creation.
@return A new, valid census_context.
*/
CENSUS_API census_context *census_context_create(
const census_context *base, const census_tag *tags, int ntags,
census_context_status const **status);
/* Destroy a context. Once this function has been called, the context cannot
be reused. */
CENSUS_API void census_context_destroy(census_context *context);
/* Get a pointer to the original status from the context creation. */
CENSUS_API const census_context_status *census_context_get_status(
const census_context *context);
/* Structure used for iterating over the tegs in a context. API clients should
not use or reference internal fields - neither their contents or
presence/absence are guaranteed. */
typedef struct {
const census_context *context;
int base;
int index;
char *kvm;
} census_context_iterator;
/* Initialize a census_tag_iterator. Must be called before first use. */
CENSUS_API void census_context_initialize_iterator(
const census_context *context, census_context_iterator *iterator);
/* Get the contents of the "next" tag in the context. If there are no more
tags, returns 0 (and 'tag' contents will be unchanged), otherwise returns 1.
*/
CENSUS_API int census_context_next_tag(census_context_iterator *iterator,
census_tag *tag);
/* Get a context tag by key. Returns 0 if the key is not present. */
CENSUS_API int census_context_get_tag(const census_context *context,
const char *key, census_tag *tag);
/* Tag set encode/decode functionality. These functionas are intended
for use by RPC systems only, for purposes of transmitting/receiving contexts.
*/
/* Encode a context into a buffer. The propagated tags are encoded into the
buffer in two regions: one for printable tags, and one for binary tags.
@param context context to be encoded
@param buffer pointer to buffer. This address will be used to encode the
printable tags.
@param buf_size number of available bytes in buffer.
@param print_buf_size Will be set to the number of bytes consumed by
printable tags.
@param bin_buf_size Will be set to the number of bytes used to encode the
binary tags.
@return A pointer to the binary tag's encoded, or NULL if the buffer was
insufficiently large to hold the encoded tags. Thus, if successful,
printable tags are encoded into
[buffer, buffer + *print_buf_size) and binary tags into
[returned-ptr, returned-ptr + *bin_buf_size) (and the returned
pointer should be buffer + *print_buf_size) */
CENSUS_API char *census_context_encode(const census_context *context,
char *buffer, size_t buf_size,
size_t *print_buf_size,
size_t *bin_buf_size);
/* Decode context buffers encoded with census_context_encode(). Returns NULL
if there is an error in parsing either buffer. */
CENSUS_API census_context *census_context_decode(const char *buffer,
size_t size,
const char *bin_buffer,
size_t bin_size);
/* Distributed traces can have a number of options. */
enum census_trace_mask_values {
@ -326,146 +446,6 @@ CENSUS_API int census_get_trace_record(census_trace_record *trace_record);
/** End a scan previously started by census_trace_scan_start() */
CENSUS_API void census_trace_scan_end();
/* A Census tag set is a collection of key:value string pairs; these form the
basis against which Census metrics will be recorded. Keys are unique within
a tag set. All contexts have an associated tag set. */
typedef struct census_tag_set census_tag_set;
/* A tag is a key:value pair. The key is a non-empty, printable (UTF-8
encoded), nil-terminated string. The value is a binary string, that may be
printable. There are limits on the sizes of both keys and values (see
CENSUS_MAX_TAG_KB_LEN definition below), and the number of tags that can be
propagated (CENSUS_MAX_PROPAGATED_TAGS). Users should also remember that
some systems may have limits on, e.g., the number of bytes that can be
transmitted as metadata, and that larger tags means more memory consumed
and time in processing. */
typedef struct {
const char *key;
const char *value;
size_t value_len;
uint8_t flags;
} census_tag;
/* Maximum length of a tag's key or value. */
#define CENSUS_MAX_TAG_KV_LEN 255
/* Maximum number of propagatable tags. */
#define CENSUS_MAX_PROPAGATED_TAGS 255
/* Tag flags. */
#define CENSUS_TAG_PROPAGATE 1 /* Tag should be propagated over RPC */
#define CENSUS_TAG_STATS 2 /* Tag will be used for statistics aggregation */
#define CENSUS_TAG_BINARY 4 /* Tag value is not printable */
#define CENSUS_TAG_RESERVED 8 /* Reserved for internal use. */
/* Flag values 8,16,32,64,128 are reserved for future/internal use. Clients
should not use or rely on their values. */
#define CENSUS_TAG_IS_PROPAGATED(flags) (flags & CENSUS_TAG_PROPAGATE)
#define CENSUS_TAG_IS_STATS(flags) (flags & CENSUS_TAG_STATS)
#define CENSUS_TAG_IS_BINARY(flags) (flags & CENSUS_TAG_BINARY)
typedef struct {
int n_propagated_tags; /* number of propagated printable tags */
int n_propagated_binary_tags; /* number of propagated binary tags */
int n_local_tags; /* number of non-propagated (local) tags */
int n_deleted_tags; /* number of tags that were deleted */
int n_added_tags; /* number of tags that were added */
int n_modified_tags; /* number of tags that were modified */
int n_invalid_tags; /* number of tags with bad keys or values (e.g.
longer than CENSUS_MAX_TAG_KV_LEN) */
int n_ignored_tags; /* number of tags ignored because of
CENSUS_MAX_PROPAGATED_TAGS limit. */
} census_tag_set_create_status;
/* Create a new tag set, adding and removing tags from an existing tag set.
This will copy all tags from it's input parameters, so it is recommended
to add as many tags in a single operation as is practical for the client.
@param base Base tag set to build upon. Can be NULL.
@param tags A set of tags to be added/changed/deleted. Tags with keys that
are in 'tags', but not 'base', are added to the tag set. Keys that are in
both 'tags' and 'base' will have their value/flags modified. Tags with keys
in both, but with NULL or zero-length values, will be deleted from the tag
set. Tags with invalid (too long or short) keys or values will be ignored.
If adding a tag will result in more than CENSUS_MAX_PROPAGATED_TAGS in either
binary or non-binary tags, they will be ignored, as will deletions of
tags that don't exist.
@param ntags number of tags in 'tags'
@param status If not NULL, will return a pointer to a
census_tag_set_create_status structure containing information about the new
tag set and status of the tags used in its creation.
@return A new, valid census_tag_set.
*/
CENSUS_API census_tag_set *census_tag_set_create(
const census_tag_set *base, const census_tag *tags, int ntags,
census_tag_set_create_status const **status);
/* Destroy a tag set created by census_tag_set_create(). Once this function
has been called, the tag set cannot be reused. */
CENSUS_API void census_tag_set_destroy(census_tag_set *tags);
/* Get a pointer to the original status from the creation of this tag set. */
CENSUS_API const census_tag_set_create_status *census_tag_set_get_create_status(
const census_tag_set *tags);
/* Structure used for tag set iteration. API clients should not use or
reference internal fields - neither their contents or presence/absence are
guaranteed. */
typedef struct {
const census_tag_set *tags;
int base;
int index;
char *kvm;
} census_tag_set_iterator;
/* Initialize a tag set iterator. Must be called before first use of the
iterator. */
CENSUS_API void census_tag_set_initialize_iterator(
const census_tag_set *tags, census_tag_set_iterator *iterator);
/* Get the contents of the "next" tag in the tag set. If there are no more
tags in the tag set, returns 0 (and 'tag' contents will be unchanged),
otherwise returns 1. */
CENSUS_API int census_tag_set_next_tag(census_tag_set_iterator *iterator,
census_tag *tag);
/* Get a tag by its key. Returns 0 if the key is not present in the tag
set. */
CENSUS_API int census_tag_set_get_tag_by_key(const census_tag_set *tags,
const char *key, census_tag *tag);
/* Tag set encode/decode functionality. These functionas are intended
for use by RPC systems only, for purposes of transmitting/receiving tag
sets. */
/* Encode a tag set into a buffer. The propagated tags are encoded into the
buffer in two regions: one for printable tags, and one for binary tags.
@param tags tag set to be encoded
@param buffer pointer to buffer. This address will be used to encode the
printable tags.
@param buf_size number of available bytes in buffer.
@param print_buf_size Will be set to the number of bytes consumed by
printable tags.
@param bin_buf_size Will be set to the number of bytes used to encode the
binary tags.
@return A pointer to the binary tag's encoded, or NULL if the buffer was
insufficiently large to hold the encoded tags. Thus, if successful,
printable tags are encoded into
[buffer, buffer + *print_buf_size) and binary tags into
[returned-ptr, returned-ptr + *bin_buf_size) (and the return value
should be buffer + *print_buf_size) */
CENSUS_API char *census_tag_set_encode(const census_tag_set *tags, char *buffer,
size_t buf_size, size_t *print_buf_size,
size_t *bin_buf_size);
/* Decode tag set buffers encoded with census_tag_set_encode_*(). Returns NULL
if there is an error in parsing either buffer. */
CENSUS_API census_tag_set *census_tag_set_decode(const char *buffer,
size_t size,
const char *bin_buffer,
size_t bin_size);
/* Get a contexts tag set. */
CENSUS_API census_tag_set *census_context_tag_set(census_context *context);
/* Core stats collection API's. The following concepts are used:
* Aggregation: A collection of values. Census supports the following
aggregation types:
@ -511,8 +491,7 @@ extern census_aggregation_ops census_agg_window;
construction via census_define_view(). */
typedef struct {
const census_aggregation_ops *ops;
const void *
create_arg; /* Argument to be used for aggregation initialization. */
const void *create_arg; /* Aaggregation initialization argument. */
} census_aggregation;
/** A census view type. Opaque. */
@ -520,14 +499,17 @@ typedef struct census_view census_view;
/** Create a new view.
@param metric_id Metric with which this view is associated.
@param tags tags that define the view
@param tags tags that define the view.
@param aggregations aggregations to associate with the view
@param naggregations number of aggregations
@return A new census view
*/
/* TODO(aveitch): consider if context is the right argument type to pass in
tags. */
CENSUS_API census_view *census_view_create(
uint32_t metric_id, const census_tag_set *tags,
uint32_t metric_id, const census_context *tags,
const census_aggregation *aggregations, size_t naggregations);
/** Destroy a previously created view. */
@ -540,7 +522,7 @@ CENSUS_API size_t census_view_metric(const census_view *view);
CENSUS_API size_t census_view_naggregations(const census_view *view);
/** Get tags associated with view. */
CENSUS_API const census_tag_set *census_view_tags(const census_view *view);
CENSUS_API const census_context *census_view_tags(const census_view *view);
/** Get aggregation descriptors associated with a view. */
CENSUS_API const census_aggregation *census_view_aggregrations(
@ -549,7 +531,7 @@ CENSUS_API const census_aggregation *census_view_aggregrations(
/** Holds all the aggregation data for a particular view instantiation. Forms
part of the data returned by census_view_data(). */
typedef struct {
const census_tag_set *tags; /* Tags for this set of aggregations. */
const census_context *tags; /* Tags for this set of aggregations. */
const void **data; /* One data set for every aggregation in the view. */
} census_view_aggregation_data;

@ -34,7 +34,7 @@
#ifndef GRPC_IMPL_CODEGEN_COMPRESSION_TYPES_H
#define GRPC_IMPL_CODEGEN_COMPRESSION_TYPES_H
#include <stdint.h>
#include <grpc/support/port_platform.h>
#ifdef __cplusplus
extern "C" {

@ -254,9 +254,22 @@
#define GPR_FORBID_UNREACHABLE_CODE 1
#endif
/* For a common case, assume that the platform has a C99-like stdint.h */
#ifdef _MSC_VER
#if _MSC_VER < 1700
typedef __int8 int8_t;
typedef __int16 int16_t;
typedef __int32 int32_t;
typedef __int64 int64_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif /* _MSC_VER < 1700 */
#else
#include <stdint.h>
#endif /* _MSC_VER */
/* Cache line alignment */
#ifndef GPR_CACHELINE_SIZE_LOG

@ -34,7 +34,7 @@
#ifndef GRPC_IMPL_CODEGEN_H
#define GRPC_IMPL_CODEGEN_H
#include <stdint.h>
#include <grpc/support/port_platform.h>
#ifdef __cplusplus
extern "C" {

@ -84,6 +84,7 @@
"src/node/src/client.js",
"src/node/src/common.js",
"src/node/src/credentials.js",
"src/node/src/grpc_extension.js",
"src/node/src/metadata.js",
"src/node/src/server.js",
"include/grpc/grpc_security.h",
@ -279,7 +280,6 @@
"src/core/support/thd_internal.h",
"src/core/support/time_precise.h",
"src/core/census/aggregation.h",
"src/core/census/context.h",
"src/core/census/rpc_metric_id.h",
"src/core/httpcli/httpcli_security_connector.c",
"src/core/security/base64.c",
@ -476,7 +476,6 @@
"src/core/census/initialize.c",
"src/core/census/operation.c",
"src/core/census/placeholders.c",
"src/core/census/tag_set.c",
"src/core/census/tracing.c",
"third_party/zlib/crc32.h",
"third_party/zlib/deflate.h",

@ -75,14 +75,25 @@ CYTHON_EXTENSION_PACKAGE_NAMES = ()
CYTHON_EXTENSION_MODULE_NAMES = ('grpc._cython.cygrpc',)
CYTHON_HELPER_C_FILES = (
os.path.join(PYTHON_STEM, 'grpc/_cython/loader.c'),
os.path.join(PYTHON_STEM, 'grpc/_cython/imports.generated.c'),
)
CORE_C_FILES = ()
if not "win32" in sys.platform:
CORE_C_FILES += tuple(grpc_core_dependencies.CORE_SOURCE_FILES)
EXTENSION_INCLUDE_DIRECTORIES = (
(PYTHON_STEM,) + CORE_INCLUDE + BORINGSSL_INCLUDE + ZLIB_INCLUDE)
EXTENSION_LIBRARIES = ('m',)
if not "darwin" in sys.platform:
EXTENSION_LIBRARIES = ()
if "linux" in sys.platform:
EXTENSION_LIBRARIES += ('rt',)
if not "win32" in sys.platform:
EXTENSION_LIBRARIES += ('m',)
DEFINE_MACROS = (('OPENSSL_NO_ASM', 1),)
DEFINE_MACROS = (('OPENSSL_NO_ASM', 1), ('_WIN32_WINNT', 0x600))
CFLAGS = ()
LDFLAGS = ()
@ -93,8 +104,8 @@ if "linux" in sys.platform or "darwin" in sys.platform:
DEFINE_MACROS += (('PyMODINIT_FUNC', '__attribute__((visibility ("default"))) void'),)
def cython_extensions(package_names, module_names, include_dirs, libraries,
define_macros, build_with_cython=False):
def cython_extensions(package_names, module_names, extra_sources, include_dirs,
libraries, define_macros, build_with_cython=False):
if ENABLE_CYTHON_TRACING:
define_macros = define_macros + [('CYTHON_TRACE_NOGIL', 1)]
file_extension = 'pyx' if build_with_cython else 'c'
@ -104,7 +115,7 @@ def cython_extensions(package_names, module_names, include_dirs, libraries,
extensions = [
_extension.Extension(
name=module_name,
sources=[module_file] + grpc_core_dependencies.CORE_SOURCE_FILES,
sources=[module_file] + extra_sources,
include_dirs=include_dirs, libraries=libraries,
define_macros=define_macros,
) for (module_name, module_file) in zip(module_names, module_files)
@ -120,6 +131,7 @@ def cython_extensions(package_names, module_names, include_dirs, libraries,
CYTHON_EXTENSION_MODULES = cython_extensions(
list(CYTHON_EXTENSION_PACKAGE_NAMES), list(CYTHON_EXTENSION_MODULE_NAMES),
list(CYTHON_HELPER_C_FILES) + list(CORE_C_FILES),
list(EXTENSION_INCLUDE_DIRECTORIES), list(EXTENSION_LIBRARIES),
list(DEFINE_MACROS), bool(BUILD_WITH_CYTHON))
@ -174,9 +186,6 @@ TEST_PACKAGE_DATA = {
'credentials/server1.key',
'credentials/server1.pem',
],
'grpc._adapter': [
'credentials/roots.pem'
],
}
TESTS_REQUIRE = (
@ -189,7 +198,15 @@ TEST_SUITE = 'tests'
TEST_LOADER = 'tests:Loader'
TEST_RUNNER = 'tests:Runner'
PACKAGE_DATA = {}
PACKAGE_DATA = {
'grpc._adapter': [
'credentials/roots.pem'
],
'grpc._cython': [
'_windows/grpc_c.32.python',
'_windows/grpc_c.64.python',
],
}
if INSTALL_TESTS:
PACKAGE_DATA = dict(PACKAGE_DATA, **TEST_PACKAGE_DATA)
PACKAGES = setuptools.find_packages(PYTHON_STEM)
@ -199,7 +216,7 @@ else:
setuptools.setup(
name='grpcio',
version='0.12.0b6',
version='0.12.0b8',
license=LICENSE,
ext_modules=CYTHON_EXTENSION_MODULES,
packages=list(PACKAGES),

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -31,16 +31,500 @@
*
*/
#include "src/core/census/context.h"
#include <string.h>
#include <grpc/census.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/useful.h>
#include <stdbool.h>
#include <string.h>
#include "src/core/support/string.h"
// Functions in this file support the public context API, including
// encoding/decoding as part of context propagation across RPC's. The overall
// requirements (in approximate priority order) for the
// context representation:
// 1. Efficient conversion to/from wire format
// 2. Minimal bytes used on-wire
// 3. Efficient context creation
// 4. Efficient lookup of tag value for a key
// 5. Efficient iteration over tags
// 6. Minimal memory footprint
//
// Notes on tradeoffs/decisions:
// * tag includes 1 byte length of key, as well as nil-terminating byte. These
// are to aid in efficient parsing and the ability to directly return key
// strings. This is more important than saving a single byte/tag on the wire.
// * The wire encoding uses only single byte values. This eliminates the need
// to handle endian-ness conversions. It also means there is a hard upper
// limit of 255 for both CENSUS_MAX_TAG_KV_LEN and CENSUS_MAX_PROPAGATED_TAGS.
// * Keep all tag information (keys/values/flags) in a single memory buffer,
// that can be directly copied to the wire.
// * Binary tags share the same structure as, but are encoded separately from,
// non-binary tags. This is primarily because non-binary tags are far more
// likely to be repeated across multiple RPC calls, so are more efficiently
// cached and compressed in any metadata schemes.
// Structure representing a set of tags. Essentially a count of number of tags
// present, and pointer to a chunk of memory that contains the per-tag details.
struct tag_set {
int ntags; // number of tags.
int ntags_alloc; // ntags + number of deleted tags (total number of tags
// in all of kvm). This will always be == ntags, except during the process
// of building a new tag set.
size_t kvm_size; // number of bytes allocated for key/value storage.
size_t kvm_used; // number of bytes of used key/value memory
char *kvm; // key/value memory. Consists of repeated entries of:
// Offset Size Description
// 0 1 Key length, including trailing 0. (K)
// 1 1 Value length. (V)
// 2 1 Flags
// 3 K Key bytes
// 3 + K V Value bytes
//
// We refer to the first 3 entries as the 'tag header'. If extra values are
// introduced in the header, you will need to modify the TAG_HEADER_SIZE
// constant, the raw_tag structure (and everything that uses it) and the
// encode/decode functions appropriately.
};
// Number of bytes in tag header.
#define TAG_HEADER_SIZE 3 // key length (1) + value length (1) + flags (1)
// Offsets to tag header entries.
#define KEY_LEN_OFFSET 0
#define VALUE_LEN_OFFSET 1
#define FLAG_OFFSET 2
// raw_tag represents the raw-storage form of a tag in the kvm of a tag_set.
struct raw_tag {
uint8_t key_len;
uint8_t value_len;
uint8_t flags;
char *key;
char *value;
};
// Use a reserved flag bit for indication of deleted tag.
#define CENSUS_TAG_DELETED CENSUS_TAG_RESERVED
#define CENSUS_TAG_IS_DELETED(flags) (flags & CENSUS_TAG_DELETED)
// Primary (external) representation of a context. Composed of 3 underlying
// tag_set structs, one for each of the binary/printable propagated tags, and
// one for everything else. This is to efficiently support tag
// encoding/decoding.
struct census_context {
struct tag_set tags[3];
census_context_status status;
};
// Indices into the tags member of census_context
#define PROPAGATED_TAGS 0
#define PROPAGATED_BINARY_TAGS 1
#define LOCAL_TAGS 2
// Extract a raw tag given a pointer (raw) to the tag header. Allow for some
// extra bytes in the tag header (see encode/decode functions for usage: this
// allows for future expansion of the tag header).
static char *decode_tag(struct raw_tag *tag, char *header, int offset) {
tag->key_len = (uint8_t)(*header++);
tag->value_len = (uint8_t)(*header++);
tag->flags = (uint8_t)(*header++);
header += offset;
tag->key = header;
header += tag->key_len;
tag->value = header;
return header + tag->value_len;
}
/* Placeholder implementation only. */
// Make a copy (in 'to') of an existing tag_set.
static void tag_set_copy(struct tag_set *to, const struct tag_set *from) {
memcpy(to, from, sizeof(struct tag_set));
to->kvm = gpr_malloc(to->kvm_size);
memcpy(to->kvm, from->kvm, from->kvm_used);
}
// Delete a tag from a tag_set, if it exists (returns true if it did).
static bool tag_set_delete_tag(struct tag_set *tags, const char *key,
size_t key_len) {
char *kvp = tags->kvm;
for (int i = 0; i < tags->ntags_alloc; i++) {
uint8_t *flags = (uint8_t *)(kvp + FLAG_OFFSET);
struct raw_tag tag;
kvp = decode_tag(&tag, kvp, 0);
if (CENSUS_TAG_IS_DELETED(tag.flags)) continue;
if ((key_len == tag.key_len) && (memcmp(key, tag.key, key_len) == 0)) {
*flags |= CENSUS_TAG_DELETED;
tags->ntags--;
return true;
}
}
return false;
}
// Delete a tag from a context, return true if it existed.
static bool context_delete_tag(census_context *context, const census_tag *tag,
size_t key_len) {
return (
tag_set_delete_tag(&context->tags[LOCAL_TAGS], tag->key, key_len) ||
tag_set_delete_tag(&context->tags[PROPAGATED_TAGS], tag->key, key_len) ||
tag_set_delete_tag(&context->tags[PROPAGATED_BINARY_TAGS], tag->key,
key_len));
}
// Add a tag to a tag_set. Return true on success, false if the tag could
// not be added because of constraints on tag set size. This function should
// not be called if the tag may already exist (in a non-deleted state) in
// the tag_set, as that would result in two tags with the same key.
static bool tag_set_add_tag(struct tag_set *tags, const census_tag *tag,
size_t key_len) {
if (tags->ntags == CENSUS_MAX_PROPAGATED_TAGS) {
return false;
}
const size_t tag_size = key_len + tag->value_len + TAG_HEADER_SIZE;
if (tags->kvm_used + tag_size > tags->kvm_size) {
// allocate new memory if needed
tags->kvm_size += 2 * CENSUS_MAX_TAG_KV_LEN + TAG_HEADER_SIZE;
char *new_kvm = gpr_malloc(tags->kvm_size);
memcpy(new_kvm, tags->kvm, tags->kvm_used);
gpr_free(tags->kvm);
tags->kvm = new_kvm;
}
char *kvp = tags->kvm + tags->kvm_used;
*kvp++ = (char)key_len;
*kvp++ = (char)tag->value_len;
// ensure reserved flags are not used.
*kvp++ = (char)(tag->flags & (CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS |
CENSUS_TAG_BINARY));
memcpy(kvp, tag->key, key_len);
kvp += key_len;
memcpy(kvp, tag->value, tag->value_len);
tags->kvm_used += tag_size;
tags->ntags++;
tags->ntags_alloc++;
return true;
}
// Add/modify/delete a tag to/in a context. Caller must validate that tag key
// etc. are valid.
static void context_modify_tag(census_context *context, const census_tag *tag,
size_t key_len) {
// First delete the tag if it is already present.
bool deleted = context_delete_tag(context, tag, key_len);
// Determine if we need to add it back.
bool call_add = tag->value != NULL && tag->value_len != 0;
bool added = false;
if (call_add) {
if (CENSUS_TAG_IS_PROPAGATED(tag->flags)) {
if (CENSUS_TAG_IS_BINARY(tag->flags)) {
added = tag_set_add_tag(&context->tags[PROPAGATED_BINARY_TAGS], tag,
key_len);
} else {
added = tag_set_add_tag(&context->tags[PROPAGATED_TAGS], tag, key_len);
}
} else {
added = tag_set_add_tag(&context->tags[LOCAL_TAGS], tag, key_len);
}
}
if (deleted) {
if (call_add) {
context->status.n_modified_tags++;
} else {
context->status.n_deleted_tags++;
}
} else {
if (added) {
context->status.n_added_tags++;
} else {
context->status.n_ignored_tags++;
}
}
}
// Remove memory used for deleted tags from a tag set. Basic algorithm:
// 1) Walk through tag set to find first deleted tag. Record where it is.
// 2) Find the next not-deleted tag. Copy all of kvm from there to the end
// "over" the deleted tags
// 3) repeat #1 and #2 until we have seen all tags
// 4) if we are still looking for a not-deleted tag, then all the end portion
// of the kvm is deleted. Just reduce the used amount of memory by the
// appropriate amount.
static void tag_set_flatten(struct tag_set *tags) {
if (tags->ntags == tags->ntags_alloc) return;
bool found_deleted = false; // found a deleted tag.
char *kvp = tags->kvm;
char *dbase = NULL; // record location of deleted tag
for (int i = 0; i < tags->ntags_alloc; i++) {
struct raw_tag tag;
char *next_kvp = decode_tag(&tag, kvp, 0);
if (found_deleted) {
if (!CENSUS_TAG_IS_DELETED(tag.flags)) {
ptrdiff_t reduce = kvp - dbase; // #bytes in deleted tags
GPR_ASSERT(reduce > 0);
ptrdiff_t copy_size = tags->kvm + tags->kvm_used - kvp;
GPR_ASSERT(copy_size > 0);
memmove(dbase, kvp, (size_t)copy_size);
tags->kvm_used -= (size_t)reduce;
next_kvp -= reduce;
found_deleted = false;
}
} else {
if (CENSUS_TAG_IS_DELETED(tag.flags)) {
dbase = kvp;
found_deleted = true;
}
}
kvp = next_kvp;
}
if (found_deleted) {
GPR_ASSERT(dbase > tags->kvm);
tags->kvm_used = (size_t)(dbase - tags->kvm);
}
tags->ntags_alloc = tags->ntags;
}
size_t census_context_serialize(const census_context *context, char *buffer,
size_t buf_size) {
/* TODO(aveitch): implement serialization */
census_context *census_context_create(const census_context *base,
const census_tag *tags, int ntags,
census_context_status const **status) {
census_context *context = gpr_malloc(sizeof(census_context));
// If we are given a base, copy it into our new tag set. Otherwise set it
// to zero/NULL everything.
if (base == NULL) {
memset(context, 0, sizeof(census_context));
} else {
tag_set_copy(&context->tags[PROPAGATED_TAGS], &base->tags[PROPAGATED_TAGS]);
tag_set_copy(&context->tags[PROPAGATED_BINARY_TAGS],
&base->tags[PROPAGATED_BINARY_TAGS]);
tag_set_copy(&context->tags[LOCAL_TAGS], &base->tags[LOCAL_TAGS]);
memset(&context->status, 0, sizeof(context->status));
}
// Walk over the additional tags and, for those that aren't invalid, modify
// the context to add/replace/delete as required.
for (int i = 0; i < ntags; i++) {
const census_tag *tag = &tags[i];
size_t key_len = strlen(tag->key) + 1;
// ignore the tag if it is too long/short.
if (key_len != 1 && key_len <= CENSUS_MAX_TAG_KV_LEN &&
tag->value_len <= CENSUS_MAX_TAG_KV_LEN) {
context_modify_tag(context, tag, key_len);
} else {
context->status.n_invalid_tags++;
}
}
// Remove any deleted tags, update status if needed, and return.
tag_set_flatten(&context->tags[PROPAGATED_TAGS]);
tag_set_flatten(&context->tags[PROPAGATED_BINARY_TAGS]);
tag_set_flatten(&context->tags[LOCAL_TAGS]);
context->status.n_propagated_tags = context->tags[PROPAGATED_TAGS].ntags;
context->status.n_propagated_binary_tags =
context->tags[PROPAGATED_BINARY_TAGS].ntags;
context->status.n_local_tags = context->tags[LOCAL_TAGS].ntags;
if (status) {
*status = &context->status;
}
return context;
}
const census_context_status *census_context_get_status(
const census_context *context) {
return &context->status;
}
void census_context_destroy(census_context *context) {
gpr_free(context->tags[PROPAGATED_TAGS].kvm);
gpr_free(context->tags[PROPAGATED_BINARY_TAGS].kvm);
gpr_free(context->tags[LOCAL_TAGS].kvm);
gpr_free(context);
}
void census_context_initialize_iterator(const census_context *context,
census_context_iterator *iterator) {
iterator->context = context;
iterator->index = 0;
if (context->tags[PROPAGATED_TAGS].ntags != 0) {
iterator->base = PROPAGATED_TAGS;
iterator->kvm = context->tags[PROPAGATED_TAGS].kvm;
} else if (context->tags[PROPAGATED_BINARY_TAGS].ntags != 0) {
iterator->base = PROPAGATED_BINARY_TAGS;
iterator->kvm = context->tags[PROPAGATED_BINARY_TAGS].kvm;
} else if (context->tags[LOCAL_TAGS].ntags != 0) {
iterator->base = LOCAL_TAGS;
iterator->kvm = context->tags[LOCAL_TAGS].kvm;
} else {
iterator->base = -1;
}
}
int census_context_next_tag(census_context_iterator *iterator,
census_tag *tag) {
if (iterator->base < 0) {
return 0;
}
struct raw_tag raw;
iterator->kvm = decode_tag(&raw, iterator->kvm, 0);
tag->key = raw.key;
tag->value = raw.value;
tag->value_len = raw.value_len;
tag->flags = raw.flags;
if (++iterator->index == iterator->context->tags[iterator->base].ntags) {
do {
if (iterator->base == LOCAL_TAGS) {
iterator->base = -1;
return 1;
}
} while (iterator->context->tags[++iterator->base].ntags == 0);
iterator->index = 0;
iterator->kvm = iterator->context->tags[iterator->base].kvm;
}
return 1;
}
// Find a tag in a tag_set by key. Return true if found, false otherwise.
static bool tag_set_get_tag(const struct tag_set *tags, const char *key,
size_t key_len, census_tag *tag) {
char *kvp = tags->kvm;
for (int i = 0; i < tags->ntags; i++) {
struct raw_tag raw;
kvp = decode_tag(&raw, kvp, 0);
if (key_len == raw.key_len && memcmp(raw.key, key, key_len) == 0) {
tag->key = raw.key;
tag->value = raw.value;
tag->value_len = raw.value_len;
tag->flags = raw.flags;
return true;
}
}
return false;
}
int census_context_get_tag(const census_context *context, const char *key,
census_tag *tag) {
size_t key_len = strlen(key) + 1;
if (key_len == 1) {
return 0;
}
if (tag_set_get_tag(&context->tags[PROPAGATED_TAGS], key, key_len, tag) ||
tag_set_get_tag(&context->tags[PROPAGATED_BINARY_TAGS], key, key_len,
tag) ||
tag_set_get_tag(&context->tags[LOCAL_TAGS], key, key_len, tag)) {
return 1;
}
return 0;
}
// Context encoding and decoding functions.
//
// Wire format for tag_set's on the wire:
//
// First, a tag set header:
//
// offset bytes description
// 0 1 version number
// 1 1 number of bytes in this header. This allows for future
// expansion.
// 2 1 number of bytes in each tag header.
// 3 1 ntags value from tag set.
//
// This is followed by the key/value memory from struct tag_set.
#define ENCODED_VERSION 0 // Version number
#define ENCODED_HEADER_SIZE 4 // size of tag set header
// Encode a tag set. Returns 0 if buffer is too small.
static size_t tag_set_encode(const struct tag_set *tags, char *buffer,
size_t buf_size) {
if (buf_size < ENCODED_HEADER_SIZE + tags->kvm_used) {
return 0;
}
buf_size -= ENCODED_HEADER_SIZE;
*buffer++ = (char)ENCODED_VERSION;
*buffer++ = (char)ENCODED_HEADER_SIZE;
*buffer++ = (char)TAG_HEADER_SIZE;
*buffer++ = (char)tags->ntags;
if (tags->ntags == 0) {
return ENCODED_HEADER_SIZE;
}
memcpy(buffer, tags->kvm, tags->kvm_used);
return ENCODED_HEADER_SIZE + tags->kvm_used;
}
char *census_context_encode(const census_context *context, char *buffer,
size_t buf_size, size_t *print_buf_size,
size_t *bin_buf_size) {
*print_buf_size =
tag_set_encode(&context->tags[PROPAGATED_TAGS], buffer, buf_size);
if (*print_buf_size == 0) {
return NULL;
}
char *b_buffer = buffer + *print_buf_size;
*bin_buf_size = tag_set_encode(&context->tags[PROPAGATED_BINARY_TAGS],
b_buffer, buf_size - *print_buf_size);
if (*bin_buf_size == 0) {
return NULL;
}
return b_buffer;
}
// Decode a tag set.
static void tag_set_decode(struct tag_set *tags, const char *buffer,
size_t size) {
uint8_t version = (uint8_t)(*buffer++);
uint8_t header_size = (uint8_t)(*buffer++);
uint8_t tag_header_size = (uint8_t)(*buffer++);
tags->ntags = tags->ntags_alloc = (int)(*buffer++);
if (tags->ntags == 0) {
tags->ntags_alloc = 0;
tags->kvm_size = 0;
tags->kvm_used = 0;
tags->kvm = NULL;
return;
}
if (header_size != ENCODED_HEADER_SIZE) {
GPR_ASSERT(version != ENCODED_VERSION);
GPR_ASSERT(ENCODED_HEADER_SIZE < header_size);
buffer += (header_size - ENCODED_HEADER_SIZE);
}
tags->kvm_used = size - header_size;
tags->kvm_size = tags->kvm_used + CENSUS_MAX_TAG_KV_LEN;
tags->kvm = gpr_malloc(tags->kvm_size);
if (tag_header_size != TAG_HEADER_SIZE) {
// something new in the tag information. I don't understand it, so
// don't copy it over.
GPR_ASSERT(version != ENCODED_VERSION);
GPR_ASSERT(tag_header_size > TAG_HEADER_SIZE);
char *kvp = tags->kvm;
for (int i = 0; i < tags->ntags; i++) {
memcpy(kvp, buffer, TAG_HEADER_SIZE);
kvp += header_size;
struct raw_tag raw;
buffer =
decode_tag(&raw, (char *)buffer, tag_header_size - TAG_HEADER_SIZE);
memcpy(kvp, raw.key, (size_t)raw.key_len + raw.value_len);
kvp += raw.key_len + raw.value_len;
}
} else {
memcpy(tags->kvm, buffer, tags->kvm_used);
}
}
census_context *census_context_decode(const char *buffer, size_t size,
const char *bin_buffer, size_t bin_size) {
census_context *context = gpr_malloc(sizeof(census_context));
memset(&context->tags[LOCAL_TAGS], 0, sizeof(struct tag_set));
if (buffer == NULL) {
memset(&context->tags[PROPAGATED_TAGS], 0, sizeof(struct tag_set));
} else {
tag_set_decode(&context->tags[PROPAGATED_TAGS], buffer, size);
}
if (bin_buffer == NULL) {
memset(&context->tags[PROPAGATED_BINARY_TAGS], 0, sizeof(struct tag_set));
} else {
tag_set_decode(&context->tags[PROPAGATED_BINARY_TAGS], bin_buffer,
bin_size);
}
memset(&context->status, 0, sizeof(context->status));
context->status.n_propagated_tags = context->tags[PROPAGATED_TAGS].ntags;
context->status.n_propagated_binary_tags =
context->tags[PROPAGATED_BINARY_TAGS].ntags;
// TODO(aveitch): check that BINARY flag is correct for each type.
return context;
}

@ -37,11 +37,6 @@
/* Placeholders for the pending APIs */
census_tag_set *census_context_tag_set(census_context *context) {
(void)context;
abort();
}
int census_get_trace_record(census_trace_record *trace_record) {
(void)trace_record;
abort();
@ -73,7 +68,7 @@ const census_aggregation *census_view_aggregrations(const census_view *view) {
abort();
}
census_view *census_view_create(uint32_t metric_id, const census_tag_set *tags,
census_view *census_view_create(uint32_t metric_id, const census_context *tags,
const census_aggregation *aggregations,
size_t naggregations) {
(void)metric_id;
@ -83,7 +78,7 @@ census_view *census_view_create(uint32_t metric_id, const census_tag_set *tags,
abort();
}
const census_tag_set *census_view_tags(const census_view *view) {
const census_context *census_view_tags(const census_view *view) {
(void)view;
abort();
}

@ -1,535 +0,0 @@
/*
*
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <grpc/census.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/useful.h>
#include <stdbool.h>
#include <string.h>
#include "src/core/support/string.h"
// Functions in this file support the public tag_set API, as well as
// encoding/decoding tag_sets as part of context propagation across
// RPC's. The overall requirements (in approximate priority order) for the
// tag_set representations:
// 1. Efficient conversion to/from wire format
// 2. Minimal bytes used on-wire
// 3. Efficient tag set creation
// 4. Efficient lookup of value for a key
// 5. Efficient lookup of value for an index (to support iteration)
// 6. Minimal memory footprint
//
// Notes on tradeoffs/decisions:
// * tag includes 1 byte length of key, as well as nil-terminating byte. These
// are to aid in efficient parsing and the ability to directly return key
// strings. This is more important than saving a single byte/tag on the wire.
// * The wire encoding uses only single byte values. This eliminates the need
// to handle endian-ness conversions. It also means there is a hard upper
// limit of 255 for both CENSUS_MAX_TAG_KV_LEN and CENSUS_MAX_PROPAGATED_TAGS.
// * Keep all tag information (keys/values/flags) in a single memory buffer,
// that can be directly copied to the wire.14
// * Binary tags share the same structure as, but are encoded separately from,
// non-binary tags. This is primarily because non-binary tags are far more
// likely to be repeated across multiple RPC calls, so are more efficiently
// cached and compressed in any metadata schemes.
// * all lengths etc. are restricted to one byte. This eliminates endian
// issues.
// Structure representing a set of tags. Essentially a count of number of tags
// present, and pointer to a chunk of memory that contains the per-tag details.
struct tag_set {
int ntags; // number of tags.
int ntags_alloc; // ntags + number of deleted tags (total number of tags
// in all of kvm). This will always be == ntags, except during the process
// of building a new tag set.
size_t kvm_size; // number of bytes allocated for key/value storage.
size_t kvm_used; // number of bytes of used key/value memory
char *kvm; // key/value memory. Consists of repeated entries of:
// Offset Size Description
// 0 1 Key length, including trailing 0. (K)
// 1 1 Value length. (V)
// 2 1 Flags
// 3 K Key bytes
// 3 + K V Value bytes
//
// We refer to the first 3 entries as the 'tag header'. If extra values are
// introduced in the header, you will need to modify the TAG_HEADER_SIZE
// constant, the raw_tag structure (and everything that uses it) and the
// encode/decode functions appropriately.
};
// Number of bytes in tag header.
#define TAG_HEADER_SIZE 3 // key length (1) + value length (1) + flags (1)
// Offsets to tag header entries.
#define KEY_LEN_OFFSET 0
#define VALUE_LEN_OFFSET 1
#define FLAG_OFFSET 2
// raw_tag represents the raw-storage form of a tag in the kvm of a tag_set.
struct raw_tag {
uint8_t key_len;
uint8_t value_len;
uint8_t flags;
char *key;
char *value;
};
// Use a reserved flag bit for indication of deleted tag.
#define CENSUS_TAG_DELETED CENSUS_TAG_RESERVED
#define CENSUS_TAG_IS_DELETED(flags) (flags & CENSUS_TAG_DELETED)
// Primary (external) representation of a tag set. Composed of 3 underlying
// tag_set structs, one for each of the binary/printable propagated tags, and
// one for everything else. This is to efficiently support tag
// encoding/decoding.
struct census_tag_set {
struct tag_set tags[3];
census_tag_set_create_status status;
};
// Indices into the tags member of census_tag_set
#define PROPAGATED_TAGS 0
#define PROPAGATED_BINARY_TAGS 1
#define LOCAL_TAGS 2
// Extract a raw tag given a pointer (raw) to the tag header. Allow for some
// extra bytes in the tag header (see encode/decode functions for usage: this
// allows for future expansion of the tag header).
static char *decode_tag(struct raw_tag *tag, char *header, int offset) {
tag->key_len = (uint8_t)(*header++);
tag->value_len = (uint8_t)(*header++);
tag->flags = (uint8_t)(*header++);
header += offset;
tag->key = header;
header += tag->key_len;
tag->value = header;
return header + tag->value_len;
}
// Make a copy (in 'to') of an existing tag_set.
static void tag_set_copy(struct tag_set *to, const struct tag_set *from) {
memcpy(to, from, sizeof(struct tag_set));
to->kvm = gpr_malloc(to->kvm_size);
memcpy(to->kvm, from->kvm, from->kvm_used);
}
// Delete a tag from a tag_set, if it exists (returns true if it did).
static bool tag_set_delete_tag(struct tag_set *tags, const char *key,
size_t key_len) {
char *kvp = tags->kvm;
for (int i = 0; i < tags->ntags_alloc; i++) {
uint8_t *flags = (uint8_t *)(kvp + FLAG_OFFSET);
struct raw_tag tag;
kvp = decode_tag(&tag, kvp, 0);
if (CENSUS_TAG_IS_DELETED(tag.flags)) continue;
if ((key_len == tag.key_len) && (memcmp(key, tag.key, key_len) == 0)) {
*flags |= CENSUS_TAG_DELETED;
tags->ntags--;
return true;
}
}
return false;
}
// Delete a tag from a census_tag_set, return true if it existed.
static bool cts_delete_tag(census_tag_set *tags, const census_tag *tag,
size_t key_len) {
return (tag_set_delete_tag(&tags->tags[LOCAL_TAGS], tag->key, key_len) ||
tag_set_delete_tag(&tags->tags[PROPAGATED_TAGS], tag->key, key_len) ||
tag_set_delete_tag(&tags->tags[PROPAGATED_BINARY_TAGS], tag->key,
key_len));
}
// Add a tag to a tag_set. Return true on sucess, false if the tag could
// not be added because of constraints on tag set size. This function should
// not be called if the tag may already exist (in a non-deleted state) in
// the tag_set, as that would result in two tags with the same key.
static bool tag_set_add_tag(struct tag_set *tags, const census_tag *tag,
size_t key_len) {
if (tags->ntags == CENSUS_MAX_PROPAGATED_TAGS) {
return false;
}
const size_t tag_size = key_len + tag->value_len + TAG_HEADER_SIZE;
if (tags->kvm_used + tag_size > tags->kvm_size) {
// allocate new memory if needed
tags->kvm_size += 2 * CENSUS_MAX_TAG_KV_LEN + TAG_HEADER_SIZE;
char *new_kvm = gpr_malloc(tags->kvm_size);
memcpy(new_kvm, tags->kvm, tags->kvm_used);
gpr_free(tags->kvm);
tags->kvm = new_kvm;
}
char *kvp = tags->kvm + tags->kvm_used;
*kvp++ = (char)key_len;
*kvp++ = (char)tag->value_len;
// ensure reserved flags are not used.
*kvp++ = (char)(tag->flags & (CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS |
CENSUS_TAG_BINARY));
memcpy(kvp, tag->key, key_len);
kvp += key_len;
memcpy(kvp, tag->value, tag->value_len);
tags->kvm_used += tag_size;
tags->ntags++;
tags->ntags_alloc++;
return true;
}
// Add/modify/delete a tag to/in a census_tag_set. Caller must validate that
// tag key etc. are valid.
static void cts_modify_tag(census_tag_set *tags, const census_tag *tag,
size_t key_len) {
// First delete the tag if it is already present.
bool deleted = cts_delete_tag(tags, tag, key_len);
// Determine if we need to add it back.
bool call_add = tag->value != NULL && tag->value_len != 0;
bool added = false;
if (call_add) {
if (CENSUS_TAG_IS_PROPAGATED(tag->flags)) {
if (CENSUS_TAG_IS_BINARY(tag->flags)) {
added =
tag_set_add_tag(&tags->tags[PROPAGATED_BINARY_TAGS], tag, key_len);
} else {
added = tag_set_add_tag(&tags->tags[PROPAGATED_TAGS], tag, key_len);
}
} else {
added = tag_set_add_tag(&tags->tags[LOCAL_TAGS], tag, key_len);
}
}
if (deleted) {
if (call_add) {
tags->status.n_modified_tags++;
} else {
tags->status.n_deleted_tags++;
}
} else {
if (added) {
tags->status.n_added_tags++;
} else {
tags->status.n_ignored_tags++;
}
}
}
// Remove memory used for deleted tags from the tag set. Basic algorithm:
// 1) Walk through tag set to find first deleted tag. Record where it is.
// 2) Find the next not-deleted tag. Copy all of kvm from there to the end
// "over" the deleted tags
// 3) repeat #1 and #2 until we have seen all tags
// 4) if we are still looking for a not-deleted tag, then all the end portion
// of the kvm is deleted. Just reduce the used amount of memory by the
// appropriate amount.
static void tag_set_flatten(struct tag_set *tags) {
if (tags->ntags == tags->ntags_alloc) return;
bool found_deleted = false; // found a deleted tag.
char *kvp = tags->kvm;
char *dbase = NULL; // record location of deleted tag
for (int i = 0; i < tags->ntags_alloc; i++) {
struct raw_tag tag;
char *next_kvp = decode_tag(&tag, kvp, 0);
if (found_deleted) {
if (!CENSUS_TAG_IS_DELETED(tag.flags)) {
ptrdiff_t reduce = kvp - dbase; // #bytes in deleted tags
GPR_ASSERT(reduce > 0);
ptrdiff_t copy_size = tags->kvm + tags->kvm_used - kvp;
GPR_ASSERT(copy_size > 0);
memmove(dbase, kvp, (size_t)copy_size);
tags->kvm_used -= (size_t)reduce;
next_kvp -= reduce;
found_deleted = false;
}
} else {
if (CENSUS_TAG_IS_DELETED(tag.flags)) {
dbase = kvp;
found_deleted = true;
}
}
kvp = next_kvp;
}
if (found_deleted) {
GPR_ASSERT(dbase > tags->kvm);
tags->kvm_used = (size_t)(dbase - tags->kvm);
}
tags->ntags_alloc = tags->ntags;
}
census_tag_set *census_tag_set_create(
const census_tag_set *base, const census_tag *tags, int ntags,
census_tag_set_create_status const **status) {
census_tag_set *new_ts = gpr_malloc(sizeof(census_tag_set));
// If we are given a base, copy it into our new tag set. Otherwise set it
// to zero/NULL everything.
if (base == NULL) {
memset(new_ts, 0, sizeof(census_tag_set));
} else {
tag_set_copy(&new_ts->tags[PROPAGATED_TAGS], &base->tags[PROPAGATED_TAGS]);
tag_set_copy(&new_ts->tags[PROPAGATED_BINARY_TAGS],
&base->tags[PROPAGATED_BINARY_TAGS]);
tag_set_copy(&new_ts->tags[LOCAL_TAGS], &base->tags[LOCAL_TAGS]);
memset(&new_ts->status, 0, sizeof(new_ts->status));
}
// Walk over the additional tags and, for those that aren't invalid, modify
// the tag set to add/replace/delete as required.
for (int i = 0; i < ntags; i++) {
const census_tag *tag = &tags[i];
size_t key_len = strlen(tag->key) + 1;
// ignore the tag if it is too long/short.
if (key_len != 1 && key_len <= CENSUS_MAX_TAG_KV_LEN &&
tag->value_len <= CENSUS_MAX_TAG_KV_LEN) {
cts_modify_tag(new_ts, tag, key_len);
} else {
new_ts->status.n_invalid_tags++;
}
}
// Remove any deleted tags, update status if needed, and return.
tag_set_flatten(&new_ts->tags[PROPAGATED_TAGS]);
tag_set_flatten(&new_ts->tags[PROPAGATED_BINARY_TAGS]);
tag_set_flatten(&new_ts->tags[LOCAL_TAGS]);
new_ts->status.n_propagated_tags = new_ts->tags[PROPAGATED_TAGS].ntags;
new_ts->status.n_propagated_binary_tags =
new_ts->tags[PROPAGATED_BINARY_TAGS].ntags;
new_ts->status.n_local_tags = new_ts->tags[LOCAL_TAGS].ntags;
if (status) {
*status = &new_ts->status;
}
return new_ts;
}
const census_tag_set_create_status *census_tag_set_get_create_status(
const census_tag_set *tags) {
return &tags->status;
}
void census_tag_set_destroy(census_tag_set *tags) {
gpr_free(tags->tags[PROPAGATED_TAGS].kvm);
gpr_free(tags->tags[PROPAGATED_BINARY_TAGS].kvm);
gpr_free(tags->tags[LOCAL_TAGS].kvm);
gpr_free(tags);
}
// Initialize a tag set iterator. Must be called before first use of the
// iterator.
void census_tag_set_initialize_iterator(const census_tag_set *tags,
census_tag_set_iterator *iterator) {
iterator->tags = tags;
iterator->index = 0;
if (tags->tags[PROPAGATED_TAGS].ntags != 0) {
iterator->base = PROPAGATED_TAGS;
iterator->kvm = tags->tags[PROPAGATED_TAGS].kvm;
} else if (tags->tags[PROPAGATED_BINARY_TAGS].ntags != 0) {
iterator->base = PROPAGATED_BINARY_TAGS;
iterator->kvm = tags->tags[PROPAGATED_BINARY_TAGS].kvm;
} else if (tags->tags[LOCAL_TAGS].ntags != 0) {
iterator->base = LOCAL_TAGS;
iterator->kvm = tags->tags[LOCAL_TAGS].kvm;
} else {
iterator->base = -1;
}
}
// Get the contents of the "next" tag in the tag set. If there are no more
// tags in the tag set, returns 0 (and 'tag' contents will be unchanged),
// otherwise returns 1. */
int census_tag_set_next_tag(census_tag_set_iterator *iterator,
census_tag *tag) {
if (iterator->base < 0) {
return 0;
}
struct raw_tag raw;
iterator->kvm = decode_tag(&raw, iterator->kvm, 0);
tag->key = raw.key;
tag->value = raw.value;
tag->value_len = raw.value_len;
tag->flags = raw.flags;
if (++iterator->index == iterator->tags->tags[iterator->base].ntags) {
do {
if (iterator->base == LOCAL_TAGS) {
iterator->base = -1;
return 1;
}
} while (iterator->tags->tags[++iterator->base].ntags == 0);
iterator->index = 0;
iterator->kvm = iterator->tags->tags[iterator->base].kvm;
}
return 1;
}
// Find a tag in a tag_set by key. Return true if found, false otherwise.
static bool tag_set_get_tag_by_key(const struct tag_set *tags, const char *key,
size_t key_len, census_tag *tag) {
char *kvp = tags->kvm;
for (int i = 0; i < tags->ntags; i++) {
struct raw_tag raw;
kvp = decode_tag(&raw, kvp, 0);
if (key_len == raw.key_len && memcmp(raw.key, key, key_len) == 0) {
tag->key = raw.key;
tag->value = raw.value;
tag->value_len = raw.value_len;
tag->flags = raw.flags;
return true;
}
}
return false;
}
int census_tag_set_get_tag_by_key(const census_tag_set *tags, const char *key,
census_tag *tag) {
size_t key_len = strlen(key) + 1;
if (key_len == 1) {
return 0;
}
if (tag_set_get_tag_by_key(&tags->tags[PROPAGATED_TAGS], key, key_len, tag) ||
tag_set_get_tag_by_key(&tags->tags[PROPAGATED_BINARY_TAGS], key, key_len,
tag) ||
tag_set_get_tag_by_key(&tags->tags[LOCAL_TAGS], key, key_len, tag)) {
return 1;
}
return 0;
}
// tag_set encoding and decoding functions.
//
// Wire format for tag sets on the wire:
//
// First, a tag set header:
//
// offset bytes description
// 0 1 version number
// 1 1 number of bytes in this header. This allows for future
// expansion.
// 2 1 number of bytes in each tag header.
// 3 1 ntags value from tag set.
//
// This is followed by the key/value memory from struct tag_set.
#define ENCODED_VERSION 0 // Version number
#define ENCODED_HEADER_SIZE 4 // size of tag set header
// Encode a tag set. Returns 0 if buffer is too small.
static size_t tag_set_encode(const struct tag_set *tags, char *buffer,
size_t buf_size) {
if (buf_size < ENCODED_HEADER_SIZE + tags->kvm_used) {
return 0;
}
buf_size -= ENCODED_HEADER_SIZE;
*buffer++ = (char)ENCODED_VERSION;
*buffer++ = (char)ENCODED_HEADER_SIZE;
*buffer++ = (char)TAG_HEADER_SIZE;
*buffer++ = (char)tags->ntags;
if (tags->ntags == 0) {
return ENCODED_HEADER_SIZE;
}
memcpy(buffer, tags->kvm, tags->kvm_used);
return ENCODED_HEADER_SIZE + tags->kvm_used;
}
char *census_tag_set_encode(const census_tag_set *tags, char *buffer,
size_t buf_size, size_t *print_buf_size,
size_t *bin_buf_size) {
*print_buf_size =
tag_set_encode(&tags->tags[PROPAGATED_TAGS], buffer, buf_size);
if (*print_buf_size == 0) {
return NULL;
}
char *b_buffer = buffer + *print_buf_size;
*bin_buf_size = tag_set_encode(&tags->tags[PROPAGATED_BINARY_TAGS], b_buffer,
buf_size - *print_buf_size);
if (*bin_buf_size == 0) {
return NULL;
}
return b_buffer;
}
// Decode a tag set.
static void tag_set_decode(struct tag_set *tags, const char *buffer,
size_t size) {
uint8_t version = (uint8_t)(*buffer++);
uint8_t header_size = (uint8_t)(*buffer++);
uint8_t tag_header_size = (uint8_t)(*buffer++);
tags->ntags = tags->ntags_alloc = (int)(*buffer++);
if (tags->ntags == 0) {
tags->ntags_alloc = 0;
tags->kvm_size = 0;
tags->kvm_used = 0;
tags->kvm = NULL;
return;
}
if (header_size != ENCODED_HEADER_SIZE) {
GPR_ASSERT(version != ENCODED_VERSION);
GPR_ASSERT(ENCODED_HEADER_SIZE < header_size);
buffer += (header_size - ENCODED_HEADER_SIZE);
}
tags->kvm_used = size - header_size;
tags->kvm_size = tags->kvm_used + CENSUS_MAX_TAG_KV_LEN;
tags->kvm = gpr_malloc(tags->kvm_size);
if (tag_header_size != TAG_HEADER_SIZE) {
// something new in the tag information. I don't understand it, so
// don't copy it over.
GPR_ASSERT(version != ENCODED_VERSION);
GPR_ASSERT(tag_header_size > TAG_HEADER_SIZE);
char *kvp = tags->kvm;
for (int i = 0; i < tags->ntags; i++) {
memcpy(kvp, buffer, TAG_HEADER_SIZE);
kvp += header_size;
struct raw_tag raw;
buffer =
decode_tag(&raw, (char *)buffer, tag_header_size - TAG_HEADER_SIZE);
memcpy(kvp, raw.key, (size_t)raw.key_len + raw.value_len);
kvp += raw.key_len + raw.value_len;
}
} else {
memcpy(tags->kvm, buffer, tags->kvm_used);
}
}
census_tag_set *census_tag_set_decode(const char *buffer, size_t size,
const char *bin_buffer, size_t bin_size) {
census_tag_set *new_ts = gpr_malloc(sizeof(census_tag_set));
memset(&new_ts->tags[LOCAL_TAGS], 0, sizeof(struct tag_set));
if (buffer == NULL) {
memset(&new_ts->tags[PROPAGATED_TAGS], 0, sizeof(struct tag_set));
} else {
tag_set_decode(&new_ts->tags[PROPAGATED_TAGS], buffer, size);
}
if (bin_buffer == NULL) {
memset(&new_ts->tags[PROPAGATED_BINARY_TAGS], 0, sizeof(struct tag_set));
} else {
tag_set_decode(&new_ts->tags[PROPAGATED_BINARY_TAGS], bin_buffer, bin_size);
}
memset(&new_ts->status, 0, sizeof(new_ts->status));
new_ts->status.n_propagated_tags = new_ts->tags[PROPAGATED_TAGS].ntags;
new_ts->status.n_propagated_binary_tags =
new_ts->tags[PROPAGATED_BINARY_TAGS].ntags;
// TODO(aveitch): check that BINARY flag is correct for each type.
return new_ts;
}

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -99,6 +99,11 @@ gpr_stack_lockfree *gpr_stack_lockfree_create(size_t entries) {
/* Point the head at reserved dummy entry */
stack->head.contents.index = INVALID_ENTRY_INDEX;
/* Fill in the pad and aba_ctr to avoid confusing memcheck tools */
#ifdef GPR_ARCH_64
stack->head.contents.pad = 0;
#endif
stack->head.contents.aba_ctr = 0;
return stack;
}
@ -115,6 +120,11 @@ int gpr_stack_lockfree_push(gpr_stack_lockfree *stack, int entry) {
/* First fill in the entry's index and aba ctr for new head */
newhead.contents.index = (uint16_t)entry;
#ifdef GPR_ARCH_64
/* Fill in the pad to avoid confusing memcheck tools */
newhead.contents.pad = 0;
#endif
/* Also post-increment the aba_ctr */
curent.atm = gpr_atm_no_barrier_load(&stack->entries[entry].atm);
newhead.contents.aba_ctr = ++curent.contents.aba_ctr;

@ -33,14 +33,14 @@
#include <grpc++/server_context.h>
#include <grpc/compression.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc++/completion_queue.h>
#include <grpc++/impl/call.h>
#include <grpc++/impl/sync.h>
#include <grpc++/support/time.h>
#include <grpc/compression.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/channel/compress_filter.h"
#include "src/cpp/common/create_auth_context.h"
@ -173,6 +173,14 @@ void ServerContext::AddTrailingMetadata(const grpc::string& key,
trailing_metadata_.insert(std::make_pair(key, value));
}
void ServerContext::TryCancel() const {
grpc_call_error err = grpc_call_cancel_with_status(
call_, GRPC_STATUS_CANCELLED, "Cancelled on the server side", NULL);
if (err != GRPC_CALL_OK) {
gpr_log(GPR_ERROR, "TryCancel failed with: %d", err);
}
}
bool ServerContext::IsCancelled() const {
return completion_op_ && completion_op_->CheckCancelled(cq_);
}

@ -106,7 +106,7 @@ namespace Grpc.Core.Internal
private static string GetExecutingAssemblyDirectory()
{
return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
return Path.GetDirectoryName(typeof(NativeExtension).GetTypeInfo().Assembly.Location);
}
private static string GetPlatformString()

@ -33,9 +33,15 @@
'use strict';
var os = require('os');
var BenchmarkClient = require('./benchmark_client');
var BenchmarkServer = require('./benchmark_server');
exports.quitWorker = function quitWorker(call, callback) {
callback(null, {});
process.exit(0);
}
exports.runClient = function runClient(call) {
var client;
call.on('data', function(request) {
@ -130,3 +136,7 @@ exports.runServer = function runServer(call) {
});
});
};
exports.coreCount = function coreCount(call, callback) {
callback(null, {cores: os.cpus().length});
};

@ -166,3 +166,6 @@ message CoreResponse {
// Number of cores available on the server
int32 cores = 1;
}
message Void {
}

@ -65,4 +65,7 @@ service WorkerService {
// Just return the core count - unary call
rpc CoreCount(CoreRequest) returns (CoreResponse);
// Quit this worker
rpc QuitWorker(Void) returns (Void);
}

@ -52,6 +52,10 @@ import support
PYTHON_STEM = os.path.dirname(os.path.abspath(__file__))
BINARIES_REPOSITORY = os.environ.get(
'GRPC_PYTHON_BINARIES_REPOSITORY',
'https://storage.googleapis.com/grpc-precompiled-binaries/python/')
CONF_PY_ADDENDUM = """
extensions.append('sphinx.ext.napoleon')
napoleon_google_docstring = True
@ -67,7 +71,7 @@ class CommandError(Exception):
# TODO(atash): Remove this once PyPI has better Linux bdist support. See
# https://bitbucket.org/pypa/pypi/issues/120/binary-wheels-for-linux-are-not-supported
def _get_linux_bdist_egg(decorated_basename, target_egg_basename):
def _get_grpc_custom_bdist_egg(decorated_basename, target_egg_basename):
"""Returns a string path to a .egg file for Linux to install.
If we can retrieve a pre-compiled egg from online, uses it. Else, emits a
@ -78,10 +82,7 @@ def _get_linux_bdist_egg(decorated_basename, target_egg_basename):
from six.moves.urllib import request
decorated_path = decorated_basename + '.egg'
try:
url = (
'https://storage.googleapis.com/grpc-precompiled-binaries/'
'python/{target}'
.format(target=decorated_path))
url = BINARIES_REPOSITORY + '/{target}'.format(target=decorated_path)
egg_data = request.urlopen(url).read()
except IOError as error:
raise CommandError(
@ -100,6 +101,7 @@ def _get_linux_bdist_egg(decorated_basename, target_egg_basename):
class EggNameMixin(object):
"""Mixin for setuptools.Command classes to enable acquiring the egg name."""
def egg_name(self, with_custom):
"""
@ -124,25 +126,25 @@ class Install(install.install, EggNameMixin):
"""
user_options = install.install.user_options + [
# TODO(atash): remove this once manylinux gets on PyPI. See
# TODO(atash): remove this once PyPI has better Linux bdist support. See
# https://bitbucket.org/pypa/pypi/issues/120/binary-wheels-for-linux-are-not-supported
('use-linux-bdist', None,
'Whether to retrieve a binary for Linux instead of building from '
'source.'),
('use-grpc-custom-bdist', None,
'Whether to retrieve a binary from the gRPC binary repository instead '
'of building from source.'),
]
def initialize_options(self):
install.install.initialize_options(self)
self.use_linux_bdist = False
self.use_grpc_custom_bdist = False
def finalize_options(self):
install.install.finalize_options(self)
def run(self):
if self.use_linux_bdist:
if self.use_grpc_custom_bdist:
try:
egg_path = _get_linux_bdist_egg(self.egg_name(True),
self.egg_name(False))
egg_path = _get_grpc_custom_bdist_egg(self.egg_name(True),
self.egg_name(False))
except CommandError as error:
sys.stderr.write(
'\nWARNING: Failed to acquire grpcio prebuilt binary:\n'

@ -1,5 +1,4 @@
*.h
*.c
cygrpc.c
*.a
*.so
*.dll

@ -28,15 +28,20 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
cimport libc.time
from libc.stdint cimport int64_t, uint32_t, int32_t
cdef extern from "grpc/support/alloc.h":
cdef extern from "grpc/_cython/loader.h":
ctypedef int int32_t
ctypedef unsigned uint32_t
ctypedef long int64_t
int pygrpc_load_core(const char*)
void *gpr_malloc(size_t size)
void gpr_free(void *ptr)
void *gpr_realloc(void *p, size_t size)
cdef extern from "grpc/support/slice.h":
ctypedef struct gpr_slice:
# don't worry about writing out the members of gpr_slice; we never access
# them directly.
@ -55,9 +60,6 @@ cdef extern from "grpc/support/slice.h":
void *gpr_slice_start_ptr "GPR_SLICE_START_PTR" (gpr_slice s)
size_t gpr_slice_length "GPR_SLICE_LENGTH" (gpr_slice s)
cdef extern from "grpc/support/time.h":
ctypedef enum gpr_clock_type:
GPR_CLOCK_MONOTONIC
GPR_CLOCK_REALTIME
@ -78,8 +80,6 @@ cdef extern from "grpc/support/time.h":
gpr_timespec gpr_convert_clock_type(gpr_timespec t,
gpr_clock_type target_clock)
cdef extern from "grpc/status.h":
ctypedef enum grpc_status_code:
GRPC_STATUS_OK
GRPC_STATUS_CANCELLED
@ -100,14 +100,10 @@ cdef extern from "grpc/status.h":
GRPC_STATUS_DATA_LOSS
GRPC_STATUS__DO_NOT_USE
cdef extern from "grpc/byte_buffer_reader.h":
struct grpc_byte_buffer_reader:
# We don't care about the internals
pass
cdef extern from "grpc/byte_buffer.h":
ctypedef struct grpc_byte_buffer:
# We don't care about the internals.
pass
@ -123,9 +119,6 @@ cdef extern from "grpc/byte_buffer.h":
gpr_slice *slice)
void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader)
cdef extern from "grpc/grpc.h":
const char *GRPC_ARG_PRIMARY_USER_AGENT_STRING
const char *GRPC_ARG_ENABLE_CENSUS
const char *GRPC_ARG_MAX_CONCURRENT_STREAMS
@ -333,9 +326,6 @@ cdef extern from "grpc/grpc.h":
void grpc_server_cancel_all_calls(grpc_server *server)
void grpc_server_destroy(grpc_server *server)
cdef extern from "grpc/grpc_security.h":
ctypedef struct grpc_ssl_pem_key_cert_pair:
const char *private_key
const char *certificate_chain "cert_chain"

@ -146,8 +146,13 @@ cdef class Timespec:
gpr_convert_clock_type(self.c_time, GPR_CLOCK_REALTIME))
return <double>real_time.seconds + <double>real_time.nanoseconds / 1e9
infinite_future = Timespec(float("+inf"))
infinite_past = Timespec(float("-inf"))
@staticmethod
def infinite_future():
return Timespec(float("+inf"))
@staticmethod
def infinite_past():
return Timespec(float("-inf"))
cdef class CallDetails:

@ -29,6 +29,10 @@
cimport cpython
import pkg_resources
import os.path
import sys
# TODO(atash): figure out why the coverage tool gets confused about the Cython
# coverage plugin when the following files don't have a '.pxi' suffix.
include "grpc/_cython/_cygrpc/call.pyx.pxi"
@ -44,11 +48,20 @@ include "grpc/_cython/_cygrpc/server.pyx.pxi"
cdef class _ModuleState:
cdef bint is_loaded
def __cinit__(self):
if 'win32' in sys.platform:
filename = pkg_resources.resource_filename(
'grpc._cython', '_windows/grpc_c.64.python')
if not pygrpc_load_core(filename):
raise ImportError('failed to load core gRPC library')
grpc_init()
self.is_loaded = True
def __dealloc__(self):
grpc_shutdown()
if self.is_loaded:
grpc_shutdown()
_module_state = _ModuleState()

@ -0,0 +1,564 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <grpc/support/port_platform.h>
#include "imports.generated.h"
#ifdef GPR_WIN32
census_initialize_type census_initialize_import;
census_shutdown_type census_shutdown_import;
census_supported_type census_supported_import;
census_enabled_type census_enabled_import;
census_context_serialize_type census_context_serialize_import;
census_trace_mask_type census_trace_mask_import;
census_set_trace_mask_type census_set_trace_mask_import;
census_start_rpc_op_timestamp_type census_start_rpc_op_timestamp_import;
census_start_client_rpc_op_type census_start_client_rpc_op_import;
census_set_rpc_client_peer_type census_set_rpc_client_peer_import;
census_start_server_rpc_op_type census_start_server_rpc_op_import;
census_start_op_type census_start_op_import;
census_end_op_type census_end_op_import;
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_tag_set_create_type census_tag_set_create_import;
census_tag_set_destroy_type census_tag_set_destroy_import;
census_tag_set_get_create_status_type census_tag_set_get_create_status_import;
census_tag_set_initialize_iterator_type census_tag_set_initialize_iterator_import;
census_tag_set_next_tag_type census_tag_set_next_tag_import;
census_tag_set_get_tag_by_key_type census_tag_set_get_tag_by_key_import;
census_tag_set_encode_type census_tag_set_encode_import;
census_tag_set_decode_type census_tag_set_decode_import;
census_context_tag_set_type census_context_tag_set_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;
grpc_compression_options_init_type grpc_compression_options_init_import;
grpc_compression_options_enable_algorithm_type grpc_compression_options_enable_algorithm_import;
grpc_compression_options_disable_algorithm_type grpc_compression_options_disable_algorithm_import;
grpc_compression_options_is_algorithm_enabled_type grpc_compression_options_is_algorithm_enabled_import;
grpc_metadata_array_init_type grpc_metadata_array_init_import;
grpc_metadata_array_destroy_type grpc_metadata_array_destroy_import;
grpc_call_details_init_type grpc_call_details_init_import;
grpc_call_details_destroy_type grpc_call_details_destroy_import;
grpc_register_plugin_type grpc_register_plugin_import;
grpc_init_type grpc_init_import;
grpc_shutdown_type grpc_shutdown_import;
grpc_version_string_type grpc_version_string_import;
grpc_completion_queue_create_type grpc_completion_queue_create_import;
grpc_completion_queue_next_type grpc_completion_queue_next_import;
grpc_completion_queue_pluck_type grpc_completion_queue_pluck_import;
grpc_completion_queue_shutdown_type grpc_completion_queue_shutdown_import;
grpc_completion_queue_destroy_type grpc_completion_queue_destroy_import;
grpc_alarm_create_type grpc_alarm_create_import;
grpc_alarm_cancel_type grpc_alarm_cancel_import;
grpc_alarm_destroy_type grpc_alarm_destroy_import;
grpc_channel_check_connectivity_state_type grpc_channel_check_connectivity_state_import;
grpc_channel_watch_connectivity_state_type grpc_channel_watch_connectivity_state_import;
grpc_channel_create_call_type grpc_channel_create_call_import;
grpc_channel_ping_type grpc_channel_ping_import;
grpc_channel_register_call_type grpc_channel_register_call_import;
grpc_channel_create_registered_call_type grpc_channel_create_registered_call_import;
grpc_call_start_batch_type grpc_call_start_batch_import;
grpc_call_get_peer_type grpc_call_get_peer_import;
grpc_census_call_set_context_type grpc_census_call_set_context_import;
grpc_census_call_get_context_type grpc_census_call_get_context_import;
grpc_channel_get_target_type grpc_channel_get_target_import;
grpc_insecure_channel_create_type grpc_insecure_channel_create_import;
grpc_lame_client_channel_create_type grpc_lame_client_channel_create_import;
grpc_channel_destroy_type grpc_channel_destroy_import;
grpc_call_cancel_type grpc_call_cancel_import;
grpc_call_cancel_with_status_type grpc_call_cancel_with_status_import;
grpc_call_destroy_type grpc_call_destroy_import;
grpc_server_request_call_type grpc_server_request_call_import;
grpc_server_register_method_type grpc_server_register_method_import;
grpc_server_request_registered_call_type grpc_server_request_registered_call_import;
grpc_server_create_type grpc_server_create_import;
grpc_server_register_completion_queue_type grpc_server_register_completion_queue_import;
grpc_server_add_insecure_http2_port_type grpc_server_add_insecure_http2_port_import;
grpc_server_start_type grpc_server_start_import;
grpc_server_shutdown_and_notify_type grpc_server_shutdown_and_notify_import;
grpc_server_cancel_all_calls_type grpc_server_cancel_all_calls_import;
grpc_server_destroy_type grpc_server_destroy_import;
grpc_tracer_set_enabled_type grpc_tracer_set_enabled_import;
grpc_header_key_is_legal_type grpc_header_key_is_legal_import;
grpc_header_nonbin_value_is_legal_type grpc_header_nonbin_value_is_legal_import;
grpc_is_binary_header_type grpc_is_binary_header_import;
grpc_auth_property_iterator_next_type grpc_auth_property_iterator_next_import;
grpc_auth_context_property_iterator_type grpc_auth_context_property_iterator_import;
grpc_auth_context_peer_identity_type grpc_auth_context_peer_identity_import;
grpc_auth_context_find_properties_by_name_type grpc_auth_context_find_properties_by_name_import;
grpc_auth_context_peer_identity_property_name_type grpc_auth_context_peer_identity_property_name_import;
grpc_auth_context_peer_is_authenticated_type grpc_auth_context_peer_is_authenticated_import;
grpc_call_auth_context_type grpc_call_auth_context_import;
grpc_auth_context_release_type grpc_auth_context_release_import;
grpc_auth_context_add_property_type grpc_auth_context_add_property_import;
grpc_auth_context_add_cstring_property_type grpc_auth_context_add_cstring_property_import;
grpc_auth_context_set_peer_identity_property_name_type grpc_auth_context_set_peer_identity_property_name_import;
grpc_channel_credentials_release_type grpc_channel_credentials_release_import;
grpc_google_default_credentials_create_type grpc_google_default_credentials_create_import;
grpc_ssl_credentials_create_type grpc_ssl_credentials_create_import;
grpc_call_credentials_release_type grpc_call_credentials_release_import;
grpc_composite_channel_credentials_create_type grpc_composite_channel_credentials_create_import;
grpc_composite_call_credentials_create_type grpc_composite_call_credentials_create_import;
grpc_google_compute_engine_credentials_create_type grpc_google_compute_engine_credentials_create_import;
grpc_max_auth_token_lifetime_type grpc_max_auth_token_lifetime_import;
grpc_service_account_jwt_access_credentials_create_type grpc_service_account_jwt_access_credentials_create_import;
grpc_google_refresh_token_credentials_create_type grpc_google_refresh_token_credentials_create_import;
grpc_access_token_credentials_create_type grpc_access_token_credentials_create_import;
grpc_google_iam_credentials_create_type grpc_google_iam_credentials_create_import;
grpc_metadata_credentials_create_from_plugin_type grpc_metadata_credentials_create_from_plugin_import;
grpc_secure_channel_create_type grpc_secure_channel_create_import;
grpc_server_credentials_release_type grpc_server_credentials_release_import;
grpc_ssl_server_credentials_create_type grpc_ssl_server_credentials_create_import;
grpc_server_add_secure_http2_port_type grpc_server_add_secure_http2_port_import;
grpc_call_set_credentials_type grpc_call_set_credentials_import;
grpc_server_credentials_set_auth_metadata_processor_type grpc_server_credentials_set_auth_metadata_processor_import;
gpr_malloc_type gpr_malloc_import;
gpr_free_type gpr_free_import;
gpr_realloc_type gpr_realloc_import;
gpr_malloc_aligned_type gpr_malloc_aligned_import;
gpr_free_aligned_type gpr_free_aligned_import;
gpr_set_allocation_functions_type gpr_set_allocation_functions_import;
gpr_get_allocation_functions_type gpr_get_allocation_functions_import;
grpc_raw_byte_buffer_create_type grpc_raw_byte_buffer_create_import;
grpc_raw_compressed_byte_buffer_create_type grpc_raw_compressed_byte_buffer_create_import;
grpc_byte_buffer_copy_type grpc_byte_buffer_copy_import;
grpc_byte_buffer_length_type grpc_byte_buffer_length_import;
grpc_byte_buffer_destroy_type grpc_byte_buffer_destroy_import;
grpc_byte_buffer_reader_init_type grpc_byte_buffer_reader_init_import;
grpc_byte_buffer_reader_destroy_type grpc_byte_buffer_reader_destroy_import;
grpc_byte_buffer_reader_next_type grpc_byte_buffer_reader_next_import;
grpc_byte_buffer_reader_readall_type grpc_byte_buffer_reader_readall_import;
grpc_raw_byte_buffer_from_reader_type grpc_raw_byte_buffer_from_reader_import;
gpr_log_type gpr_log_import;
gpr_log_message_type gpr_log_message_import;
gpr_set_log_function_type gpr_set_log_function_import;
gpr_slice_ref_type gpr_slice_ref_import;
gpr_slice_unref_type gpr_slice_unref_import;
gpr_slice_new_type gpr_slice_new_import;
gpr_slice_new_with_len_type gpr_slice_new_with_len_import;
gpr_slice_malloc_type gpr_slice_malloc_import;
gpr_slice_from_copied_string_type gpr_slice_from_copied_string_import;
gpr_slice_from_copied_buffer_type gpr_slice_from_copied_buffer_import;
gpr_slice_from_static_string_type gpr_slice_from_static_string_import;
gpr_slice_sub_type gpr_slice_sub_import;
gpr_slice_sub_no_ref_type gpr_slice_sub_no_ref_import;
gpr_slice_split_tail_type gpr_slice_split_tail_import;
gpr_slice_split_head_type gpr_slice_split_head_import;
gpr_empty_slice_type gpr_empty_slice_import;
gpr_slice_cmp_type gpr_slice_cmp_import;
gpr_slice_str_cmp_type gpr_slice_str_cmp_import;
gpr_slice_buffer_init_type gpr_slice_buffer_init_import;
gpr_slice_buffer_destroy_type gpr_slice_buffer_destroy_import;
gpr_slice_buffer_add_type gpr_slice_buffer_add_import;
gpr_slice_buffer_add_indexed_type gpr_slice_buffer_add_indexed_import;
gpr_slice_buffer_addn_type gpr_slice_buffer_addn_import;
gpr_slice_buffer_tiny_add_type gpr_slice_buffer_tiny_add_import;
gpr_slice_buffer_pop_type gpr_slice_buffer_pop_import;
gpr_slice_buffer_reset_and_unref_type gpr_slice_buffer_reset_and_unref_import;
gpr_slice_buffer_swap_type gpr_slice_buffer_swap_import;
gpr_slice_buffer_move_into_type gpr_slice_buffer_move_into_import;
gpr_slice_buffer_trim_end_type gpr_slice_buffer_trim_end_import;
gpr_slice_buffer_move_first_type gpr_slice_buffer_move_first_import;
gpr_slice_buffer_take_first_type gpr_slice_buffer_take_first_import;
gpr_mu_init_type gpr_mu_init_import;
gpr_mu_destroy_type gpr_mu_destroy_import;
gpr_mu_lock_type gpr_mu_lock_import;
gpr_mu_unlock_type gpr_mu_unlock_import;
gpr_mu_trylock_type gpr_mu_trylock_import;
gpr_cv_init_type gpr_cv_init_import;
gpr_cv_destroy_type gpr_cv_destroy_import;
gpr_cv_wait_type gpr_cv_wait_import;
gpr_cv_signal_type gpr_cv_signal_import;
gpr_cv_broadcast_type gpr_cv_broadcast_import;
gpr_once_init_type gpr_once_init_import;
gpr_event_init_type gpr_event_init_import;
gpr_event_set_type gpr_event_set_import;
gpr_event_get_type gpr_event_get_import;
gpr_event_wait_type gpr_event_wait_import;
gpr_ref_init_type gpr_ref_init_import;
gpr_ref_type gpr_ref_import;
gpr_refn_type gpr_refn_import;
gpr_unref_type gpr_unref_import;
gpr_stats_init_type gpr_stats_init_import;
gpr_stats_inc_type gpr_stats_inc_import;
gpr_stats_read_type gpr_stats_read_import;
gpr_time_0_type gpr_time_0_import;
gpr_inf_future_type gpr_inf_future_import;
gpr_inf_past_type gpr_inf_past_import;
gpr_time_init_type gpr_time_init_import;
gpr_now_type gpr_now_import;
gpr_convert_clock_type_type gpr_convert_clock_type_import;
gpr_time_cmp_type gpr_time_cmp_import;
gpr_time_max_type gpr_time_max_import;
gpr_time_min_type gpr_time_min_import;
gpr_time_add_type gpr_time_add_import;
gpr_time_sub_type gpr_time_sub_import;
gpr_time_from_micros_type gpr_time_from_micros_import;
gpr_time_from_nanos_type gpr_time_from_nanos_import;
gpr_time_from_millis_type gpr_time_from_millis_import;
gpr_time_from_seconds_type gpr_time_from_seconds_import;
gpr_time_from_minutes_type gpr_time_from_minutes_import;
gpr_time_from_hours_type gpr_time_from_hours_import;
gpr_time_to_millis_type gpr_time_to_millis_import;
gpr_time_similar_type gpr_time_similar_import;
gpr_sleep_until_type gpr_sleep_until_import;
gpr_timespec_to_micros_type gpr_timespec_to_micros_import;
gpr_avl_create_type gpr_avl_create_import;
gpr_avl_ref_type gpr_avl_ref_import;
gpr_avl_unref_type gpr_avl_unref_import;
gpr_avl_add_type gpr_avl_add_import;
gpr_avl_remove_type gpr_avl_remove_import;
gpr_avl_get_type gpr_avl_get_import;
gpr_cmdline_create_type gpr_cmdline_create_import;
gpr_cmdline_add_int_type gpr_cmdline_add_int_import;
gpr_cmdline_add_flag_type gpr_cmdline_add_flag_import;
gpr_cmdline_add_string_type gpr_cmdline_add_string_import;
gpr_cmdline_on_extra_arg_type gpr_cmdline_on_extra_arg_import;
gpr_cmdline_set_survive_failure_type gpr_cmdline_set_survive_failure_import;
gpr_cmdline_parse_type gpr_cmdline_parse_import;
gpr_cmdline_destroy_type gpr_cmdline_destroy_import;
gpr_cmdline_usage_string_type gpr_cmdline_usage_string_import;
gpr_cpu_num_cores_type gpr_cpu_num_cores_import;
gpr_cpu_current_cpu_type gpr_cpu_current_cpu_import;
gpr_histogram_create_type gpr_histogram_create_import;
gpr_histogram_destroy_type gpr_histogram_destroy_import;
gpr_histogram_add_type gpr_histogram_add_import;
gpr_histogram_merge_type gpr_histogram_merge_import;
gpr_histogram_percentile_type gpr_histogram_percentile_import;
gpr_histogram_mean_type gpr_histogram_mean_import;
gpr_histogram_stddev_type gpr_histogram_stddev_import;
gpr_histogram_variance_type gpr_histogram_variance_import;
gpr_histogram_maximum_type gpr_histogram_maximum_import;
gpr_histogram_minimum_type gpr_histogram_minimum_import;
gpr_histogram_count_type gpr_histogram_count_import;
gpr_histogram_sum_type gpr_histogram_sum_import;
gpr_histogram_sum_of_squares_type gpr_histogram_sum_of_squares_import;
gpr_histogram_get_contents_type gpr_histogram_get_contents_import;
gpr_histogram_merge_contents_type gpr_histogram_merge_contents_import;
gpr_join_host_port_type gpr_join_host_port_import;
gpr_split_host_port_type gpr_split_host_port_import;
gpr_format_message_type gpr_format_message_import;
gpr_strdup_type gpr_strdup_import;
gpr_asprintf_type gpr_asprintf_import;
gpr_subprocess_binary_extension_type gpr_subprocess_binary_extension_import;
gpr_subprocess_create_type gpr_subprocess_create_import;
gpr_subprocess_destroy_type gpr_subprocess_destroy_import;
gpr_subprocess_join_type gpr_subprocess_join_import;
gpr_subprocess_interrupt_type gpr_subprocess_interrupt_import;
gpr_thd_new_type gpr_thd_new_import;
gpr_thd_options_default_type gpr_thd_options_default_import;
gpr_thd_options_set_detached_type gpr_thd_options_set_detached_import;
gpr_thd_options_set_joinable_type gpr_thd_options_set_joinable_import;
gpr_thd_options_is_detached_type gpr_thd_options_is_detached_import;
gpr_thd_options_is_joinable_type gpr_thd_options_is_joinable_import;
gpr_thd_currentid_type gpr_thd_currentid_import;
gpr_thd_join_type gpr_thd_join_import;
void pygrpc_load_imports(HMODULE library) {
census_initialize_import = (census_initialize_type) GetProcAddress(library, "census_initialize");
census_shutdown_import = (census_shutdown_type) GetProcAddress(library, "census_shutdown");
census_supported_import = (census_supported_type) GetProcAddress(library, "census_supported");
census_enabled_import = (census_enabled_type) GetProcAddress(library, "census_enabled");
census_context_serialize_import = (census_context_serialize_type) GetProcAddress(library, "census_context_serialize");
census_trace_mask_import = (census_trace_mask_type) GetProcAddress(library, "census_trace_mask");
census_set_trace_mask_import = (census_set_trace_mask_type) GetProcAddress(library, "census_set_trace_mask");
census_start_rpc_op_timestamp_import = (census_start_rpc_op_timestamp_type) GetProcAddress(library, "census_start_rpc_op_timestamp");
census_start_client_rpc_op_import = (census_start_client_rpc_op_type) GetProcAddress(library, "census_start_client_rpc_op");
census_set_rpc_client_peer_import = (census_set_rpc_client_peer_type) GetProcAddress(library, "census_set_rpc_client_peer");
census_start_server_rpc_op_import = (census_start_server_rpc_op_type) GetProcAddress(library, "census_start_server_rpc_op");
census_start_op_import = (census_start_op_type) GetProcAddress(library, "census_start_op");
census_end_op_import = (census_end_op_type) GetProcAddress(library, "census_end_op");
census_trace_print_import = (census_trace_print_type) GetProcAddress(library, "census_trace_print");
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_tag_set_create_import = (census_tag_set_create_type) GetProcAddress(library, "census_tag_set_create");
census_tag_set_destroy_import = (census_tag_set_destroy_type) GetProcAddress(library, "census_tag_set_destroy");
census_tag_set_get_create_status_import = (census_tag_set_get_create_status_type) GetProcAddress(library, "census_tag_set_get_create_status");
census_tag_set_initialize_iterator_import = (census_tag_set_initialize_iterator_type) GetProcAddress(library, "census_tag_set_initialize_iterator");
census_tag_set_next_tag_import = (census_tag_set_next_tag_type) GetProcAddress(library, "census_tag_set_next_tag");
census_tag_set_get_tag_by_key_import = (census_tag_set_get_tag_by_key_type) GetProcAddress(library, "census_tag_set_get_tag_by_key");
census_tag_set_encode_import = (census_tag_set_encode_type) GetProcAddress(library, "census_tag_set_encode");
census_tag_set_decode_import = (census_tag_set_decode_type) GetProcAddress(library, "census_tag_set_decode");
census_context_tag_set_import = (census_context_tag_set_type) GetProcAddress(library, "census_context_tag_set");
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");
grpc_compression_options_init_import = (grpc_compression_options_init_type) GetProcAddress(library, "grpc_compression_options_init");
grpc_compression_options_enable_algorithm_import = (grpc_compression_options_enable_algorithm_type) GetProcAddress(library, "grpc_compression_options_enable_algorithm");
grpc_compression_options_disable_algorithm_import = (grpc_compression_options_disable_algorithm_type) GetProcAddress(library, "grpc_compression_options_disable_algorithm");
grpc_compression_options_is_algorithm_enabled_import = (grpc_compression_options_is_algorithm_enabled_type) GetProcAddress(library, "grpc_compression_options_is_algorithm_enabled");
grpc_metadata_array_init_import = (grpc_metadata_array_init_type) GetProcAddress(library, "grpc_metadata_array_init");
grpc_metadata_array_destroy_import = (grpc_metadata_array_destroy_type) GetProcAddress(library, "grpc_metadata_array_destroy");
grpc_call_details_init_import = (grpc_call_details_init_type) GetProcAddress(library, "grpc_call_details_init");
grpc_call_details_destroy_import = (grpc_call_details_destroy_type) GetProcAddress(library, "grpc_call_details_destroy");
grpc_register_plugin_import = (grpc_register_plugin_type) GetProcAddress(library, "grpc_register_plugin");
grpc_init_import = (grpc_init_type) GetProcAddress(library, "grpc_init");
grpc_shutdown_import = (grpc_shutdown_type) GetProcAddress(library, "grpc_shutdown");
grpc_version_string_import = (grpc_version_string_type) GetProcAddress(library, "grpc_version_string");
grpc_completion_queue_create_import = (grpc_completion_queue_create_type) GetProcAddress(library, "grpc_completion_queue_create");
grpc_completion_queue_next_import = (grpc_completion_queue_next_type) GetProcAddress(library, "grpc_completion_queue_next");
grpc_completion_queue_pluck_import = (grpc_completion_queue_pluck_type) GetProcAddress(library, "grpc_completion_queue_pluck");
grpc_completion_queue_shutdown_import = (grpc_completion_queue_shutdown_type) GetProcAddress(library, "grpc_completion_queue_shutdown");
grpc_completion_queue_destroy_import = (grpc_completion_queue_destroy_type) GetProcAddress(library, "grpc_completion_queue_destroy");
grpc_alarm_create_import = (grpc_alarm_create_type) GetProcAddress(library, "grpc_alarm_create");
grpc_alarm_cancel_import = (grpc_alarm_cancel_type) GetProcAddress(library, "grpc_alarm_cancel");
grpc_alarm_destroy_import = (grpc_alarm_destroy_type) GetProcAddress(library, "grpc_alarm_destroy");
grpc_channel_check_connectivity_state_import = (grpc_channel_check_connectivity_state_type) GetProcAddress(library, "grpc_channel_check_connectivity_state");
grpc_channel_watch_connectivity_state_import = (grpc_channel_watch_connectivity_state_type) GetProcAddress(library, "grpc_channel_watch_connectivity_state");
grpc_channel_create_call_import = (grpc_channel_create_call_type) GetProcAddress(library, "grpc_channel_create_call");
grpc_channel_ping_import = (grpc_channel_ping_type) GetProcAddress(library, "grpc_channel_ping");
grpc_channel_register_call_import = (grpc_channel_register_call_type) GetProcAddress(library, "grpc_channel_register_call");
grpc_channel_create_registered_call_import = (grpc_channel_create_registered_call_type) GetProcAddress(library, "grpc_channel_create_registered_call");
grpc_call_start_batch_import = (grpc_call_start_batch_type) GetProcAddress(library, "grpc_call_start_batch");
grpc_call_get_peer_import = (grpc_call_get_peer_type) GetProcAddress(library, "grpc_call_get_peer");
grpc_census_call_set_context_import = (grpc_census_call_set_context_type) GetProcAddress(library, "grpc_census_call_set_context");
grpc_census_call_get_context_import = (grpc_census_call_get_context_type) GetProcAddress(library, "grpc_census_call_get_context");
grpc_channel_get_target_import = (grpc_channel_get_target_type) GetProcAddress(library, "grpc_channel_get_target");
grpc_insecure_channel_create_import = (grpc_insecure_channel_create_type) GetProcAddress(library, "grpc_insecure_channel_create");
grpc_lame_client_channel_create_import = (grpc_lame_client_channel_create_type) GetProcAddress(library, "grpc_lame_client_channel_create");
grpc_channel_destroy_import = (grpc_channel_destroy_type) GetProcAddress(library, "grpc_channel_destroy");
grpc_call_cancel_import = (grpc_call_cancel_type) GetProcAddress(library, "grpc_call_cancel");
grpc_call_cancel_with_status_import = (grpc_call_cancel_with_status_type) GetProcAddress(library, "grpc_call_cancel_with_status");
grpc_call_destroy_import = (grpc_call_destroy_type) GetProcAddress(library, "grpc_call_destroy");
grpc_server_request_call_import = (grpc_server_request_call_type) GetProcAddress(library, "grpc_server_request_call");
grpc_server_register_method_import = (grpc_server_register_method_type) GetProcAddress(library, "grpc_server_register_method");
grpc_server_request_registered_call_import = (grpc_server_request_registered_call_type) GetProcAddress(library, "grpc_server_request_registered_call");
grpc_server_create_import = (grpc_server_create_type) GetProcAddress(library, "grpc_server_create");
grpc_server_register_completion_queue_import = (grpc_server_register_completion_queue_type) GetProcAddress(library, "grpc_server_register_completion_queue");
grpc_server_add_insecure_http2_port_import = (grpc_server_add_insecure_http2_port_type) GetProcAddress(library, "grpc_server_add_insecure_http2_port");
grpc_server_start_import = (grpc_server_start_type) GetProcAddress(library, "grpc_server_start");
grpc_server_shutdown_and_notify_import = (grpc_server_shutdown_and_notify_type) GetProcAddress(library, "grpc_server_shutdown_and_notify");
grpc_server_cancel_all_calls_import = (grpc_server_cancel_all_calls_type) GetProcAddress(library, "grpc_server_cancel_all_calls");
grpc_server_destroy_import = (grpc_server_destroy_type) GetProcAddress(library, "grpc_server_destroy");
grpc_tracer_set_enabled_import = (grpc_tracer_set_enabled_type) GetProcAddress(library, "grpc_tracer_set_enabled");
grpc_header_key_is_legal_import = (grpc_header_key_is_legal_type) GetProcAddress(library, "grpc_header_key_is_legal");
grpc_header_nonbin_value_is_legal_import = (grpc_header_nonbin_value_is_legal_type) GetProcAddress(library, "grpc_header_nonbin_value_is_legal");
grpc_is_binary_header_import = (grpc_is_binary_header_type) GetProcAddress(library, "grpc_is_binary_header");
grpc_auth_property_iterator_next_import = (grpc_auth_property_iterator_next_type) GetProcAddress(library, "grpc_auth_property_iterator_next");
grpc_auth_context_property_iterator_import = (grpc_auth_context_property_iterator_type) GetProcAddress(library, "grpc_auth_context_property_iterator");
grpc_auth_context_peer_identity_import = (grpc_auth_context_peer_identity_type) GetProcAddress(library, "grpc_auth_context_peer_identity");
grpc_auth_context_find_properties_by_name_import = (grpc_auth_context_find_properties_by_name_type) GetProcAddress(library, "grpc_auth_context_find_properties_by_name");
grpc_auth_context_peer_identity_property_name_import = (grpc_auth_context_peer_identity_property_name_type) GetProcAddress(library, "grpc_auth_context_peer_identity_property_name");
grpc_auth_context_peer_is_authenticated_import = (grpc_auth_context_peer_is_authenticated_type) GetProcAddress(library, "grpc_auth_context_peer_is_authenticated");
grpc_call_auth_context_import = (grpc_call_auth_context_type) GetProcAddress(library, "grpc_call_auth_context");
grpc_auth_context_release_import = (grpc_auth_context_release_type) GetProcAddress(library, "grpc_auth_context_release");
grpc_auth_context_add_property_import = (grpc_auth_context_add_property_type) GetProcAddress(library, "grpc_auth_context_add_property");
grpc_auth_context_add_cstring_property_import = (grpc_auth_context_add_cstring_property_type) GetProcAddress(library, "grpc_auth_context_add_cstring_property");
grpc_auth_context_set_peer_identity_property_name_import = (grpc_auth_context_set_peer_identity_property_name_type) GetProcAddress(library, "grpc_auth_context_set_peer_identity_property_name");
grpc_channel_credentials_release_import = (grpc_channel_credentials_release_type) GetProcAddress(library, "grpc_channel_credentials_release");
grpc_google_default_credentials_create_import = (grpc_google_default_credentials_create_type) GetProcAddress(library, "grpc_google_default_credentials_create");
grpc_ssl_credentials_create_import = (grpc_ssl_credentials_create_type) GetProcAddress(library, "grpc_ssl_credentials_create");
grpc_call_credentials_release_import = (grpc_call_credentials_release_type) GetProcAddress(library, "grpc_call_credentials_release");
grpc_composite_channel_credentials_create_import = (grpc_composite_channel_credentials_create_type) GetProcAddress(library, "grpc_composite_channel_credentials_create");
grpc_composite_call_credentials_create_import = (grpc_composite_call_credentials_create_type) GetProcAddress(library, "grpc_composite_call_credentials_create");
grpc_google_compute_engine_credentials_create_import = (grpc_google_compute_engine_credentials_create_type) GetProcAddress(library, "grpc_google_compute_engine_credentials_create");
grpc_max_auth_token_lifetime_import = (grpc_max_auth_token_lifetime_type) GetProcAddress(library, "grpc_max_auth_token_lifetime");
grpc_service_account_jwt_access_credentials_create_import = (grpc_service_account_jwt_access_credentials_create_type) GetProcAddress(library, "grpc_service_account_jwt_access_credentials_create");
grpc_google_refresh_token_credentials_create_import = (grpc_google_refresh_token_credentials_create_type) GetProcAddress(library, "grpc_google_refresh_token_credentials_create");
grpc_access_token_credentials_create_import = (grpc_access_token_credentials_create_type) GetProcAddress(library, "grpc_access_token_credentials_create");
grpc_google_iam_credentials_create_import = (grpc_google_iam_credentials_create_type) GetProcAddress(library, "grpc_google_iam_credentials_create");
grpc_metadata_credentials_create_from_plugin_import = (grpc_metadata_credentials_create_from_plugin_type) GetProcAddress(library, "grpc_metadata_credentials_create_from_plugin");
grpc_secure_channel_create_import = (grpc_secure_channel_create_type) GetProcAddress(library, "grpc_secure_channel_create");
grpc_server_credentials_release_import = (grpc_server_credentials_release_type) GetProcAddress(library, "grpc_server_credentials_release");
grpc_ssl_server_credentials_create_import = (grpc_ssl_server_credentials_create_type) GetProcAddress(library, "grpc_ssl_server_credentials_create");
grpc_server_add_secure_http2_port_import = (grpc_server_add_secure_http2_port_type) GetProcAddress(library, "grpc_server_add_secure_http2_port");
grpc_call_set_credentials_import = (grpc_call_set_credentials_type) GetProcAddress(library, "grpc_call_set_credentials");
grpc_server_credentials_set_auth_metadata_processor_import = (grpc_server_credentials_set_auth_metadata_processor_type) GetProcAddress(library, "grpc_server_credentials_set_auth_metadata_processor");
gpr_malloc_import = (gpr_malloc_type) GetProcAddress(library, "gpr_malloc");
gpr_free_import = (gpr_free_type) GetProcAddress(library, "gpr_free");
gpr_realloc_import = (gpr_realloc_type) GetProcAddress(library, "gpr_realloc");
gpr_malloc_aligned_import = (gpr_malloc_aligned_type) GetProcAddress(library, "gpr_malloc_aligned");
gpr_free_aligned_import = (gpr_free_aligned_type) GetProcAddress(library, "gpr_free_aligned");
gpr_set_allocation_functions_import = (gpr_set_allocation_functions_type) GetProcAddress(library, "gpr_set_allocation_functions");
gpr_get_allocation_functions_import = (gpr_get_allocation_functions_type) GetProcAddress(library, "gpr_get_allocation_functions");
grpc_raw_byte_buffer_create_import = (grpc_raw_byte_buffer_create_type) GetProcAddress(library, "grpc_raw_byte_buffer_create");
grpc_raw_compressed_byte_buffer_create_import = (grpc_raw_compressed_byte_buffer_create_type) GetProcAddress(library, "grpc_raw_compressed_byte_buffer_create");
grpc_byte_buffer_copy_import = (grpc_byte_buffer_copy_type) GetProcAddress(library, "grpc_byte_buffer_copy");
grpc_byte_buffer_length_import = (grpc_byte_buffer_length_type) GetProcAddress(library, "grpc_byte_buffer_length");
grpc_byte_buffer_destroy_import = (grpc_byte_buffer_destroy_type) GetProcAddress(library, "grpc_byte_buffer_destroy");
grpc_byte_buffer_reader_init_import = (grpc_byte_buffer_reader_init_type) GetProcAddress(library, "grpc_byte_buffer_reader_init");
grpc_byte_buffer_reader_destroy_import = (grpc_byte_buffer_reader_destroy_type) GetProcAddress(library, "grpc_byte_buffer_reader_destroy");
grpc_byte_buffer_reader_next_import = (grpc_byte_buffer_reader_next_type) GetProcAddress(library, "grpc_byte_buffer_reader_next");
grpc_byte_buffer_reader_readall_import = (grpc_byte_buffer_reader_readall_type) GetProcAddress(library, "grpc_byte_buffer_reader_readall");
grpc_raw_byte_buffer_from_reader_import = (grpc_raw_byte_buffer_from_reader_type) GetProcAddress(library, "grpc_raw_byte_buffer_from_reader");
gpr_log_import = (gpr_log_type) GetProcAddress(library, "gpr_log");
gpr_log_message_import = (gpr_log_message_type) GetProcAddress(library, "gpr_log_message");
gpr_set_log_function_import = (gpr_set_log_function_type) GetProcAddress(library, "gpr_set_log_function");
gpr_slice_ref_import = (gpr_slice_ref_type) GetProcAddress(library, "gpr_slice_ref");
gpr_slice_unref_import = (gpr_slice_unref_type) GetProcAddress(library, "gpr_slice_unref");
gpr_slice_new_import = (gpr_slice_new_type) GetProcAddress(library, "gpr_slice_new");
gpr_slice_new_with_len_import = (gpr_slice_new_with_len_type) GetProcAddress(library, "gpr_slice_new_with_len");
gpr_slice_malloc_import = (gpr_slice_malloc_type) GetProcAddress(library, "gpr_slice_malloc");
gpr_slice_from_copied_string_import = (gpr_slice_from_copied_string_type) GetProcAddress(library, "gpr_slice_from_copied_string");
gpr_slice_from_copied_buffer_import = (gpr_slice_from_copied_buffer_type) GetProcAddress(library, "gpr_slice_from_copied_buffer");
gpr_slice_from_static_string_import = (gpr_slice_from_static_string_type) GetProcAddress(library, "gpr_slice_from_static_string");
gpr_slice_sub_import = (gpr_slice_sub_type) GetProcAddress(library, "gpr_slice_sub");
gpr_slice_sub_no_ref_import = (gpr_slice_sub_no_ref_type) GetProcAddress(library, "gpr_slice_sub_no_ref");
gpr_slice_split_tail_import = (gpr_slice_split_tail_type) GetProcAddress(library, "gpr_slice_split_tail");
gpr_slice_split_head_import = (gpr_slice_split_head_type) GetProcAddress(library, "gpr_slice_split_head");
gpr_empty_slice_import = (gpr_empty_slice_type) GetProcAddress(library, "gpr_empty_slice");
gpr_slice_cmp_import = (gpr_slice_cmp_type) GetProcAddress(library, "gpr_slice_cmp");
gpr_slice_str_cmp_import = (gpr_slice_str_cmp_type) GetProcAddress(library, "gpr_slice_str_cmp");
gpr_slice_buffer_init_import = (gpr_slice_buffer_init_type) GetProcAddress(library, "gpr_slice_buffer_init");
gpr_slice_buffer_destroy_import = (gpr_slice_buffer_destroy_type) GetProcAddress(library, "gpr_slice_buffer_destroy");
gpr_slice_buffer_add_import = (gpr_slice_buffer_add_type) GetProcAddress(library, "gpr_slice_buffer_add");
gpr_slice_buffer_add_indexed_import = (gpr_slice_buffer_add_indexed_type) GetProcAddress(library, "gpr_slice_buffer_add_indexed");
gpr_slice_buffer_addn_import = (gpr_slice_buffer_addn_type) GetProcAddress(library, "gpr_slice_buffer_addn");
gpr_slice_buffer_tiny_add_import = (gpr_slice_buffer_tiny_add_type) GetProcAddress(library, "gpr_slice_buffer_tiny_add");
gpr_slice_buffer_pop_import = (gpr_slice_buffer_pop_type) GetProcAddress(library, "gpr_slice_buffer_pop");
gpr_slice_buffer_reset_and_unref_import = (gpr_slice_buffer_reset_and_unref_type) GetProcAddress(library, "gpr_slice_buffer_reset_and_unref");
gpr_slice_buffer_swap_import = (gpr_slice_buffer_swap_type) GetProcAddress(library, "gpr_slice_buffer_swap");
gpr_slice_buffer_move_into_import = (gpr_slice_buffer_move_into_type) GetProcAddress(library, "gpr_slice_buffer_move_into");
gpr_slice_buffer_trim_end_import = (gpr_slice_buffer_trim_end_type) GetProcAddress(library, "gpr_slice_buffer_trim_end");
gpr_slice_buffer_move_first_import = (gpr_slice_buffer_move_first_type) GetProcAddress(library, "gpr_slice_buffer_move_first");
gpr_slice_buffer_take_first_import = (gpr_slice_buffer_take_first_type) GetProcAddress(library, "gpr_slice_buffer_take_first");
gpr_mu_init_import = (gpr_mu_init_type) GetProcAddress(library, "gpr_mu_init");
gpr_mu_destroy_import = (gpr_mu_destroy_type) GetProcAddress(library, "gpr_mu_destroy");
gpr_mu_lock_import = (gpr_mu_lock_type) GetProcAddress(library, "gpr_mu_lock");
gpr_mu_unlock_import = (gpr_mu_unlock_type) GetProcAddress(library, "gpr_mu_unlock");
gpr_mu_trylock_import = (gpr_mu_trylock_type) GetProcAddress(library, "gpr_mu_trylock");
gpr_cv_init_import = (gpr_cv_init_type) GetProcAddress(library, "gpr_cv_init");
gpr_cv_destroy_import = (gpr_cv_destroy_type) GetProcAddress(library, "gpr_cv_destroy");
gpr_cv_wait_import = (gpr_cv_wait_type) GetProcAddress(library, "gpr_cv_wait");
gpr_cv_signal_import = (gpr_cv_signal_type) GetProcAddress(library, "gpr_cv_signal");
gpr_cv_broadcast_import = (gpr_cv_broadcast_type) GetProcAddress(library, "gpr_cv_broadcast");
gpr_once_init_import = (gpr_once_init_type) GetProcAddress(library, "gpr_once_init");
gpr_event_init_import = (gpr_event_init_type) GetProcAddress(library, "gpr_event_init");
gpr_event_set_import = (gpr_event_set_type) GetProcAddress(library, "gpr_event_set");
gpr_event_get_import = (gpr_event_get_type) GetProcAddress(library, "gpr_event_get");
gpr_event_wait_import = (gpr_event_wait_type) GetProcAddress(library, "gpr_event_wait");
gpr_ref_init_import = (gpr_ref_init_type) GetProcAddress(library, "gpr_ref_init");
gpr_ref_import = (gpr_ref_type) GetProcAddress(library, "gpr_ref");
gpr_refn_import = (gpr_refn_type) GetProcAddress(library, "gpr_refn");
gpr_unref_import = (gpr_unref_type) GetProcAddress(library, "gpr_unref");
gpr_stats_init_import = (gpr_stats_init_type) GetProcAddress(library, "gpr_stats_init");
gpr_stats_inc_import = (gpr_stats_inc_type) GetProcAddress(library, "gpr_stats_inc");
gpr_stats_read_import = (gpr_stats_read_type) GetProcAddress(library, "gpr_stats_read");
gpr_time_0_import = (gpr_time_0_type) GetProcAddress(library, "gpr_time_0");
gpr_inf_future_import = (gpr_inf_future_type) GetProcAddress(library, "gpr_inf_future");
gpr_inf_past_import = (gpr_inf_past_type) GetProcAddress(library, "gpr_inf_past");
gpr_time_init_import = (gpr_time_init_type) GetProcAddress(library, "gpr_time_init");
gpr_now_import = (gpr_now_type) GetProcAddress(library, "gpr_now");
gpr_convert_clock_type_import = (gpr_convert_clock_type_type) GetProcAddress(library, "gpr_convert_clock_type");
gpr_time_cmp_import = (gpr_time_cmp_type) GetProcAddress(library, "gpr_time_cmp");
gpr_time_max_import = (gpr_time_max_type) GetProcAddress(library, "gpr_time_max");
gpr_time_min_import = (gpr_time_min_type) GetProcAddress(library, "gpr_time_min");
gpr_time_add_import = (gpr_time_add_type) GetProcAddress(library, "gpr_time_add");
gpr_time_sub_import = (gpr_time_sub_type) GetProcAddress(library, "gpr_time_sub");
gpr_time_from_micros_import = (gpr_time_from_micros_type) GetProcAddress(library, "gpr_time_from_micros");
gpr_time_from_nanos_import = (gpr_time_from_nanos_type) GetProcAddress(library, "gpr_time_from_nanos");
gpr_time_from_millis_import = (gpr_time_from_millis_type) GetProcAddress(library, "gpr_time_from_millis");
gpr_time_from_seconds_import = (gpr_time_from_seconds_type) GetProcAddress(library, "gpr_time_from_seconds");
gpr_time_from_minutes_import = (gpr_time_from_minutes_type) GetProcAddress(library, "gpr_time_from_minutes");
gpr_time_from_hours_import = (gpr_time_from_hours_type) GetProcAddress(library, "gpr_time_from_hours");
gpr_time_to_millis_import = (gpr_time_to_millis_type) GetProcAddress(library, "gpr_time_to_millis");
gpr_time_similar_import = (gpr_time_similar_type) GetProcAddress(library, "gpr_time_similar");
gpr_sleep_until_import = (gpr_sleep_until_type) GetProcAddress(library, "gpr_sleep_until");
gpr_timespec_to_micros_import = (gpr_timespec_to_micros_type) GetProcAddress(library, "gpr_timespec_to_micros");
gpr_avl_create_import = (gpr_avl_create_type) GetProcAddress(library, "gpr_avl_create");
gpr_avl_ref_import = (gpr_avl_ref_type) GetProcAddress(library, "gpr_avl_ref");
gpr_avl_unref_import = (gpr_avl_unref_type) GetProcAddress(library, "gpr_avl_unref");
gpr_avl_add_import = (gpr_avl_add_type) GetProcAddress(library, "gpr_avl_add");
gpr_avl_remove_import = (gpr_avl_remove_type) GetProcAddress(library, "gpr_avl_remove");
gpr_avl_get_import = (gpr_avl_get_type) GetProcAddress(library, "gpr_avl_get");
gpr_cmdline_create_import = (gpr_cmdline_create_type) GetProcAddress(library, "gpr_cmdline_create");
gpr_cmdline_add_int_import = (gpr_cmdline_add_int_type) GetProcAddress(library, "gpr_cmdline_add_int");
gpr_cmdline_add_flag_import = (gpr_cmdline_add_flag_type) GetProcAddress(library, "gpr_cmdline_add_flag");
gpr_cmdline_add_string_import = (gpr_cmdline_add_string_type) GetProcAddress(library, "gpr_cmdline_add_string");
gpr_cmdline_on_extra_arg_import = (gpr_cmdline_on_extra_arg_type) GetProcAddress(library, "gpr_cmdline_on_extra_arg");
gpr_cmdline_set_survive_failure_import = (gpr_cmdline_set_survive_failure_type) GetProcAddress(library, "gpr_cmdline_set_survive_failure");
gpr_cmdline_parse_import = (gpr_cmdline_parse_type) GetProcAddress(library, "gpr_cmdline_parse");
gpr_cmdline_destroy_import = (gpr_cmdline_destroy_type) GetProcAddress(library, "gpr_cmdline_destroy");
gpr_cmdline_usage_string_import = (gpr_cmdline_usage_string_type) GetProcAddress(library, "gpr_cmdline_usage_string");
gpr_cpu_num_cores_import = (gpr_cpu_num_cores_type) GetProcAddress(library, "gpr_cpu_num_cores");
gpr_cpu_current_cpu_import = (gpr_cpu_current_cpu_type) GetProcAddress(library, "gpr_cpu_current_cpu");
gpr_histogram_create_import = (gpr_histogram_create_type) GetProcAddress(library, "gpr_histogram_create");
gpr_histogram_destroy_import = (gpr_histogram_destroy_type) GetProcAddress(library, "gpr_histogram_destroy");
gpr_histogram_add_import = (gpr_histogram_add_type) GetProcAddress(library, "gpr_histogram_add");
gpr_histogram_merge_import = (gpr_histogram_merge_type) GetProcAddress(library, "gpr_histogram_merge");
gpr_histogram_percentile_import = (gpr_histogram_percentile_type) GetProcAddress(library, "gpr_histogram_percentile");
gpr_histogram_mean_import = (gpr_histogram_mean_type) GetProcAddress(library, "gpr_histogram_mean");
gpr_histogram_stddev_import = (gpr_histogram_stddev_type) GetProcAddress(library, "gpr_histogram_stddev");
gpr_histogram_variance_import = (gpr_histogram_variance_type) GetProcAddress(library, "gpr_histogram_variance");
gpr_histogram_maximum_import = (gpr_histogram_maximum_type) GetProcAddress(library, "gpr_histogram_maximum");
gpr_histogram_minimum_import = (gpr_histogram_minimum_type) GetProcAddress(library, "gpr_histogram_minimum");
gpr_histogram_count_import = (gpr_histogram_count_type) GetProcAddress(library, "gpr_histogram_count");
gpr_histogram_sum_import = (gpr_histogram_sum_type) GetProcAddress(library, "gpr_histogram_sum");
gpr_histogram_sum_of_squares_import = (gpr_histogram_sum_of_squares_type) GetProcAddress(library, "gpr_histogram_sum_of_squares");
gpr_histogram_get_contents_import = (gpr_histogram_get_contents_type) GetProcAddress(library, "gpr_histogram_get_contents");
gpr_histogram_merge_contents_import = (gpr_histogram_merge_contents_type) GetProcAddress(library, "gpr_histogram_merge_contents");
gpr_join_host_port_import = (gpr_join_host_port_type) GetProcAddress(library, "gpr_join_host_port");
gpr_split_host_port_import = (gpr_split_host_port_type) GetProcAddress(library, "gpr_split_host_port");
gpr_format_message_import = (gpr_format_message_type) GetProcAddress(library, "gpr_format_message");
gpr_strdup_import = (gpr_strdup_type) GetProcAddress(library, "gpr_strdup");
gpr_asprintf_import = (gpr_asprintf_type) GetProcAddress(library, "gpr_asprintf");
gpr_subprocess_binary_extension_import = (gpr_subprocess_binary_extension_type) GetProcAddress(library, "gpr_subprocess_binary_extension");
gpr_subprocess_create_import = (gpr_subprocess_create_type) GetProcAddress(library, "gpr_subprocess_create");
gpr_subprocess_destroy_import = (gpr_subprocess_destroy_type) GetProcAddress(library, "gpr_subprocess_destroy");
gpr_subprocess_join_import = (gpr_subprocess_join_type) GetProcAddress(library, "gpr_subprocess_join");
gpr_subprocess_interrupt_import = (gpr_subprocess_interrupt_type) GetProcAddress(library, "gpr_subprocess_interrupt");
gpr_thd_new_import = (gpr_thd_new_type) GetProcAddress(library, "gpr_thd_new");
gpr_thd_options_default_import = (gpr_thd_options_default_type) GetProcAddress(library, "gpr_thd_options_default");
gpr_thd_options_set_detached_import = (gpr_thd_options_set_detached_type) GetProcAddress(library, "gpr_thd_options_set_detached");
gpr_thd_options_set_joinable_import = (gpr_thd_options_set_joinable_type) GetProcAddress(library, "gpr_thd_options_set_joinable");
gpr_thd_options_is_detached_import = (gpr_thd_options_is_detached_type) GetProcAddress(library, "gpr_thd_options_is_detached");
gpr_thd_options_is_joinable_import = (gpr_thd_options_is_joinable_type) GetProcAddress(library, "gpr_thd_options_is_joinable");
gpr_thd_currentid_import = (gpr_thd_currentid_type) GetProcAddress(library, "gpr_thd_currentid");
gpr_thd_join_import = (gpr_thd_join_type) GetProcAddress(library, "gpr_thd_join");
}
#endif /* !GPR_WIN32 */

@ -0,0 +1,860 @@
/*
*
* 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 PYGRPC_CYTHON_WINDOWS_IMPORTS_H_
#define PYGRPC_CYTHON_WINDOWS_IMPORTS_H_
#include <grpc/support/port_platform.h>
#ifdef GPR_WIN32
#include <windows.h>
#include <grpc/census.h>
#include <grpc/compression.h>
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
#include <grpc/impl/codegen/alloc.h>
#include <grpc/impl/codegen/byte_buffer.h>
#include <grpc/impl/codegen/log.h>
#include <grpc/impl/codegen/slice.h>
#include <grpc/impl/codegen/slice_buffer.h>
#include <grpc/impl/codegen/sync.h>
#include <grpc/impl/codegen/time.h>
#include <grpc/support/avl.h>
#include <grpc/support/cmdline.h>
#include <grpc/support/cpu.h>
#include <grpc/support/histogram.h>
#include <grpc/support/host_port.h>
#include <grpc/support/log_win32.h>
#include <grpc/support/string_util.h>
#include <grpc/support/subprocess.h>
#include <grpc/support/thd.h>
typedef int(*census_initialize_type)(int features);
extern census_initialize_type census_initialize_import;
#define census_initialize census_initialize_import
typedef void(*census_shutdown_type)(void);
extern census_shutdown_type census_shutdown_import;
#define census_shutdown census_shutdown_import
typedef int(*census_supported_type)(void);
extern census_supported_type census_supported_import;
#define census_supported census_supported_import
typedef int(*census_enabled_type)(void);
extern census_enabled_type census_enabled_import;
#define census_enabled census_enabled_import
typedef size_t(*census_context_serialize_type)(const census_context *context, char *buffer, size_t buf_size);
extern census_context_serialize_type census_context_serialize_import;
#define census_context_serialize census_context_serialize_import
typedef int(*census_trace_mask_type)(const census_context *context);
extern census_trace_mask_type census_trace_mask_import;
#define census_trace_mask census_trace_mask_import
typedef void(*census_set_trace_mask_type)(int trace_mask);
extern census_set_trace_mask_type census_set_trace_mask_import;
#define census_set_trace_mask census_set_trace_mask_import
typedef census_timestamp(*census_start_rpc_op_timestamp_type)(void);
extern census_start_rpc_op_timestamp_type census_start_rpc_op_timestamp_import;
#define census_start_rpc_op_timestamp census_start_rpc_op_timestamp_import
typedef census_context *(*census_start_client_rpc_op_type)(const census_context *context, int64_t rpc_name_id, const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask, const census_timestamp *start_time);
extern census_start_client_rpc_op_type census_start_client_rpc_op_import;
#define census_start_client_rpc_op census_start_client_rpc_op_import
typedef void(*census_set_rpc_client_peer_type)(census_context *context, const char *peer);
extern census_set_rpc_client_peer_type census_set_rpc_client_peer_import;
#define census_set_rpc_client_peer census_set_rpc_client_peer_import
typedef census_context *(*census_start_server_rpc_op_type)(const char *buffer, int64_t rpc_name_id, const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask, census_timestamp *start_time);
extern census_start_server_rpc_op_type census_start_server_rpc_op_import;
#define census_start_server_rpc_op census_start_server_rpc_op_import
typedef census_context *(*census_start_op_type)(census_context *context, const char *family, const char *name, int trace_mask);
extern census_start_op_type census_start_op_import;
#define census_start_op census_start_op_import
typedef void(*census_end_op_type)(census_context *context, int status);
extern census_end_op_type census_end_op_import;
#define census_end_op census_end_op_import
typedef void(*census_trace_print_type)(census_context *context, uint32_t type, const char *buffer, size_t n);
extern census_trace_print_type census_trace_print_import;
#define census_trace_print census_trace_print_import
typedef int(*census_trace_scan_start_type)(int consume);
extern census_trace_scan_start_type census_trace_scan_start_import;
#define census_trace_scan_start census_trace_scan_start_import
typedef int(*census_get_trace_record_type)(census_trace_record *trace_record);
extern census_get_trace_record_type census_get_trace_record_import;
#define census_get_trace_record 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 census_tag_set *(*census_tag_set_create_type)(const census_tag_set *base, const census_tag *tags, int ntags, census_tag_set_create_status const **status);
extern census_tag_set_create_type census_tag_set_create_import;
#define census_tag_set_create census_tag_set_create_import
typedef void(*census_tag_set_destroy_type)(census_tag_set *tags);
extern census_tag_set_destroy_type census_tag_set_destroy_import;
#define census_tag_set_destroy census_tag_set_destroy_import
typedef const census_tag_set_create_status *(*census_tag_set_get_create_status_type)(const census_tag_set *tags);
extern census_tag_set_get_create_status_type census_tag_set_get_create_status_import;
#define census_tag_set_get_create_status census_tag_set_get_create_status_import
typedef void(*census_tag_set_initialize_iterator_type)(const census_tag_set *tags, census_tag_set_iterator *iterator);
extern census_tag_set_initialize_iterator_type census_tag_set_initialize_iterator_import;
#define census_tag_set_initialize_iterator census_tag_set_initialize_iterator_import
typedef int(*census_tag_set_next_tag_type)(census_tag_set_iterator *iterator, census_tag *tag);
extern census_tag_set_next_tag_type census_tag_set_next_tag_import;
#define census_tag_set_next_tag census_tag_set_next_tag_import
typedef int(*census_tag_set_get_tag_by_key_type)(const census_tag_set *tags, const char *key, census_tag *tag);
extern census_tag_set_get_tag_by_key_type census_tag_set_get_tag_by_key_import;
#define census_tag_set_get_tag_by_key census_tag_set_get_tag_by_key_import
typedef char *(*census_tag_set_encode_type)(const census_tag_set *tags, char *buffer, size_t buf_size, size_t *print_buf_size, size_t *bin_buf_size);
extern census_tag_set_encode_type census_tag_set_encode_import;
#define census_tag_set_encode census_tag_set_encode_import
typedef census_tag_set *(*census_tag_set_decode_type)(const char *buffer, size_t size, const char *bin_buffer, size_t bin_size);
extern census_tag_set_decode_type census_tag_set_decode_import;
#define census_tag_set_decode census_tag_set_decode_import
typedef census_tag_set *(*census_context_tag_set_type)(census_context *context);
extern census_context_tag_set_type census_context_tag_set_import;
#define census_context_tag_set census_context_tag_set_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_tag_set *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_tag_set *(*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
typedef int(*grpc_compression_algorithm_name_type)(grpc_compression_algorithm algorithm, char **name);
extern grpc_compression_algorithm_name_type grpc_compression_algorithm_name_import;
#define grpc_compression_algorithm_name grpc_compression_algorithm_name_import
typedef grpc_compression_algorithm(*grpc_compression_algorithm_for_level_type)(grpc_compression_level level);
extern grpc_compression_algorithm_for_level_type grpc_compression_algorithm_for_level_import;
#define grpc_compression_algorithm_for_level grpc_compression_algorithm_for_level_import
typedef void(*grpc_compression_options_init_type)(grpc_compression_options *opts);
extern grpc_compression_options_init_type grpc_compression_options_init_import;
#define grpc_compression_options_init grpc_compression_options_init_import
typedef void(*grpc_compression_options_enable_algorithm_type)(grpc_compression_options *opts, grpc_compression_algorithm algorithm);
extern grpc_compression_options_enable_algorithm_type grpc_compression_options_enable_algorithm_import;
#define grpc_compression_options_enable_algorithm grpc_compression_options_enable_algorithm_import
typedef void(*grpc_compression_options_disable_algorithm_type)(grpc_compression_options *opts, grpc_compression_algorithm algorithm);
extern grpc_compression_options_disable_algorithm_type grpc_compression_options_disable_algorithm_import;
#define grpc_compression_options_disable_algorithm grpc_compression_options_disable_algorithm_import
typedef int(*grpc_compression_options_is_algorithm_enabled_type)(const grpc_compression_options *opts, grpc_compression_algorithm algorithm);
extern grpc_compression_options_is_algorithm_enabled_type grpc_compression_options_is_algorithm_enabled_import;
#define grpc_compression_options_is_algorithm_enabled grpc_compression_options_is_algorithm_enabled_import
typedef void(*grpc_metadata_array_init_type)(grpc_metadata_array *array);
extern grpc_metadata_array_init_type grpc_metadata_array_init_import;
#define grpc_metadata_array_init grpc_metadata_array_init_import
typedef void(*grpc_metadata_array_destroy_type)(grpc_metadata_array *array);
extern grpc_metadata_array_destroy_type grpc_metadata_array_destroy_import;
#define grpc_metadata_array_destroy grpc_metadata_array_destroy_import
typedef void(*grpc_call_details_init_type)(grpc_call_details *details);
extern grpc_call_details_init_type grpc_call_details_init_import;
#define grpc_call_details_init grpc_call_details_init_import
typedef void(*grpc_call_details_destroy_type)(grpc_call_details *details);
extern grpc_call_details_destroy_type grpc_call_details_destroy_import;
#define grpc_call_details_destroy grpc_call_details_destroy_import
typedef void(*grpc_register_plugin_type)(void (*init)(void), void (*destroy)(void));
extern grpc_register_plugin_type grpc_register_plugin_import;
#define grpc_register_plugin grpc_register_plugin_import
typedef void(*grpc_init_type)(void);
extern grpc_init_type grpc_init_import;
#define grpc_init grpc_init_import
typedef void(*grpc_shutdown_type)(void);
extern grpc_shutdown_type grpc_shutdown_import;
#define grpc_shutdown grpc_shutdown_import
typedef const char *(*grpc_version_string_type)(void);
extern grpc_version_string_type grpc_version_string_import;
#define grpc_version_string grpc_version_string_import
typedef grpc_completion_queue *(*grpc_completion_queue_create_type)(void *reserved);
extern grpc_completion_queue_create_type grpc_completion_queue_create_import;
#define grpc_completion_queue_create grpc_completion_queue_create_import
typedef grpc_event(*grpc_completion_queue_next_type)(grpc_completion_queue *cq, gpr_timespec deadline, void *reserved);
extern grpc_completion_queue_next_type grpc_completion_queue_next_import;
#define grpc_completion_queue_next grpc_completion_queue_next_import
typedef grpc_event(*grpc_completion_queue_pluck_type)(grpc_completion_queue *cq, void *tag, gpr_timespec deadline, void *reserved);
extern grpc_completion_queue_pluck_type grpc_completion_queue_pluck_import;
#define grpc_completion_queue_pluck grpc_completion_queue_pluck_import
typedef void(*grpc_completion_queue_shutdown_type)(grpc_completion_queue *cq);
extern grpc_completion_queue_shutdown_type grpc_completion_queue_shutdown_import;
#define grpc_completion_queue_shutdown grpc_completion_queue_shutdown_import
typedef void(*grpc_completion_queue_destroy_type)(grpc_completion_queue *cq);
extern grpc_completion_queue_destroy_type grpc_completion_queue_destroy_import;
#define grpc_completion_queue_destroy grpc_completion_queue_destroy_import
typedef grpc_alarm *(*grpc_alarm_create_type)(grpc_completion_queue *cq, gpr_timespec deadline, void *tag);
extern grpc_alarm_create_type grpc_alarm_create_import;
#define grpc_alarm_create grpc_alarm_create_import
typedef void(*grpc_alarm_cancel_type)(grpc_alarm *alarm);
extern grpc_alarm_cancel_type grpc_alarm_cancel_import;
#define grpc_alarm_cancel grpc_alarm_cancel_import
typedef void(*grpc_alarm_destroy_type)(grpc_alarm *alarm);
extern grpc_alarm_destroy_type grpc_alarm_destroy_import;
#define grpc_alarm_destroy grpc_alarm_destroy_import
typedef grpc_connectivity_state(*grpc_channel_check_connectivity_state_type)(grpc_channel *channel, int try_to_connect);
extern grpc_channel_check_connectivity_state_type grpc_channel_check_connectivity_state_import;
#define grpc_channel_check_connectivity_state grpc_channel_check_connectivity_state_import
typedef void(*grpc_channel_watch_connectivity_state_type)(grpc_channel *channel, grpc_connectivity_state last_observed_state, gpr_timespec deadline, grpc_completion_queue *cq, void *tag);
extern grpc_channel_watch_connectivity_state_type grpc_channel_watch_connectivity_state_import;
#define grpc_channel_watch_connectivity_state grpc_channel_watch_connectivity_state_import
typedef grpc_call *(*grpc_channel_create_call_type)(grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, grpc_completion_queue *completion_queue, const char *method, const char *host, gpr_timespec deadline, void *reserved);
extern grpc_channel_create_call_type grpc_channel_create_call_import;
#define grpc_channel_create_call grpc_channel_create_call_import
typedef void(*grpc_channel_ping_type)(grpc_channel *channel, grpc_completion_queue *cq, void *tag, void *reserved);
extern grpc_channel_ping_type grpc_channel_ping_import;
#define grpc_channel_ping grpc_channel_ping_import
typedef void *(*grpc_channel_register_call_type)(grpc_channel *channel, const char *method, const char *host, void *reserved);
extern grpc_channel_register_call_type grpc_channel_register_call_import;
#define grpc_channel_register_call grpc_channel_register_call_import
typedef grpc_call *(*grpc_channel_create_registered_call_type)(grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, grpc_completion_queue *completion_queue, void *registered_call_handle, gpr_timespec deadline, void *reserved);
extern grpc_channel_create_registered_call_type grpc_channel_create_registered_call_import;
#define grpc_channel_create_registered_call grpc_channel_create_registered_call_import
typedef grpc_call_error(*grpc_call_start_batch_type)(grpc_call *call, const grpc_op *ops, size_t nops, void *tag, void *reserved);
extern grpc_call_start_batch_type grpc_call_start_batch_import;
#define grpc_call_start_batch grpc_call_start_batch_import
typedef char *(*grpc_call_get_peer_type)(grpc_call *call);
extern grpc_call_get_peer_type grpc_call_get_peer_import;
#define grpc_call_get_peer grpc_call_get_peer_import
typedef void(*grpc_census_call_set_context_type)(grpc_call *call, struct census_context *context);
extern grpc_census_call_set_context_type grpc_census_call_set_context_import;
#define grpc_census_call_set_context grpc_census_call_set_context_import
typedef struct census_context *(*grpc_census_call_get_context_type)(grpc_call *call);
extern grpc_census_call_get_context_type grpc_census_call_get_context_import;
#define grpc_census_call_get_context grpc_census_call_get_context_import
typedef char *(*grpc_channel_get_target_type)(grpc_channel *channel);
extern grpc_channel_get_target_type grpc_channel_get_target_import;
#define grpc_channel_get_target grpc_channel_get_target_import
typedef grpc_channel *(*grpc_insecure_channel_create_type)(const char *target, const grpc_channel_args *args, void *reserved);
extern grpc_insecure_channel_create_type grpc_insecure_channel_create_import;
#define grpc_insecure_channel_create grpc_insecure_channel_create_import
typedef grpc_channel *(*grpc_lame_client_channel_create_type)(const char *target, grpc_status_code error_code, const char *error_message);
extern grpc_lame_client_channel_create_type grpc_lame_client_channel_create_import;
#define grpc_lame_client_channel_create grpc_lame_client_channel_create_import
typedef void(*grpc_channel_destroy_type)(grpc_channel *channel);
extern grpc_channel_destroy_type grpc_channel_destroy_import;
#define grpc_channel_destroy grpc_channel_destroy_import
typedef grpc_call_error(*grpc_call_cancel_type)(grpc_call *call, void *reserved);
extern grpc_call_cancel_type grpc_call_cancel_import;
#define grpc_call_cancel grpc_call_cancel_import
typedef grpc_call_error(*grpc_call_cancel_with_status_type)(grpc_call *call, grpc_status_code status, const char *description, void *reserved);
extern grpc_call_cancel_with_status_type grpc_call_cancel_with_status_import;
#define grpc_call_cancel_with_status grpc_call_cancel_with_status_import
typedef void(*grpc_call_destroy_type)(grpc_call *call);
extern grpc_call_destroy_type grpc_call_destroy_import;
#define grpc_call_destroy grpc_call_destroy_import
typedef grpc_call_error(*grpc_server_request_call_type)(grpc_server *server, grpc_call **call, grpc_call_details *details, grpc_metadata_array *request_metadata, grpc_completion_queue *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void *tag_new);
extern grpc_server_request_call_type grpc_server_request_call_import;
#define grpc_server_request_call grpc_server_request_call_import
typedef void *(*grpc_server_register_method_type)(grpc_server *server, const char *method, const char *host);
extern grpc_server_register_method_type grpc_server_register_method_import;
#define grpc_server_register_method grpc_server_register_method_import
typedef grpc_call_error(*grpc_server_request_registered_call_type)(grpc_server *server, void *registered_method, grpc_call **call, gpr_timespec *deadline, grpc_metadata_array *request_metadata, grpc_byte_buffer **optional_payload, grpc_completion_queue *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void *tag_new);
extern grpc_server_request_registered_call_type grpc_server_request_registered_call_import;
#define grpc_server_request_registered_call grpc_server_request_registered_call_import
typedef grpc_server *(*grpc_server_create_type)(const grpc_channel_args *args, void *reserved);
extern grpc_server_create_type grpc_server_create_import;
#define grpc_server_create grpc_server_create_import
typedef void(*grpc_server_register_completion_queue_type)(grpc_server *server, grpc_completion_queue *cq, void *reserved);
extern grpc_server_register_completion_queue_type grpc_server_register_completion_queue_import;
#define grpc_server_register_completion_queue grpc_server_register_completion_queue_import
typedef int(*grpc_server_add_insecure_http2_port_type)(grpc_server *server, const char *addr);
extern grpc_server_add_insecure_http2_port_type grpc_server_add_insecure_http2_port_import;
#define grpc_server_add_insecure_http2_port grpc_server_add_insecure_http2_port_import
typedef void(*grpc_server_start_type)(grpc_server *server);
extern grpc_server_start_type grpc_server_start_import;
#define grpc_server_start grpc_server_start_import
typedef void(*grpc_server_shutdown_and_notify_type)(grpc_server *server, grpc_completion_queue *cq, void *tag);
extern grpc_server_shutdown_and_notify_type grpc_server_shutdown_and_notify_import;
#define grpc_server_shutdown_and_notify grpc_server_shutdown_and_notify_import
typedef void(*grpc_server_cancel_all_calls_type)(grpc_server *server);
extern grpc_server_cancel_all_calls_type grpc_server_cancel_all_calls_import;
#define grpc_server_cancel_all_calls grpc_server_cancel_all_calls_import
typedef void(*grpc_server_destroy_type)(grpc_server *server);
extern grpc_server_destroy_type grpc_server_destroy_import;
#define grpc_server_destroy grpc_server_destroy_import
typedef int(*grpc_tracer_set_enabled_type)(const char *name, int enabled);
extern grpc_tracer_set_enabled_type grpc_tracer_set_enabled_import;
#define grpc_tracer_set_enabled grpc_tracer_set_enabled_import
typedef int(*grpc_header_key_is_legal_type)(const char *key, size_t length);
extern grpc_header_key_is_legal_type grpc_header_key_is_legal_import;
#define grpc_header_key_is_legal grpc_header_key_is_legal_import
typedef int(*grpc_header_nonbin_value_is_legal_type)(const char *value, size_t length);
extern grpc_header_nonbin_value_is_legal_type grpc_header_nonbin_value_is_legal_import;
#define grpc_header_nonbin_value_is_legal grpc_header_nonbin_value_is_legal_import
typedef int(*grpc_is_binary_header_type)(const char *key, size_t length);
extern grpc_is_binary_header_type grpc_is_binary_header_import;
#define grpc_is_binary_header grpc_is_binary_header_import
typedef const grpc_auth_property *(*grpc_auth_property_iterator_next_type)(grpc_auth_property_iterator *it);
extern grpc_auth_property_iterator_next_type grpc_auth_property_iterator_next_import;
#define grpc_auth_property_iterator_next grpc_auth_property_iterator_next_import
typedef grpc_auth_property_iterator(*grpc_auth_context_property_iterator_type)(const grpc_auth_context *ctx);
extern grpc_auth_context_property_iterator_type grpc_auth_context_property_iterator_import;
#define grpc_auth_context_property_iterator grpc_auth_context_property_iterator_import
typedef grpc_auth_property_iterator(*grpc_auth_context_peer_identity_type)(const grpc_auth_context *ctx);
extern grpc_auth_context_peer_identity_type grpc_auth_context_peer_identity_import;
#define grpc_auth_context_peer_identity grpc_auth_context_peer_identity_import
typedef grpc_auth_property_iterator(*grpc_auth_context_find_properties_by_name_type)(const grpc_auth_context *ctx, const char *name);
extern grpc_auth_context_find_properties_by_name_type grpc_auth_context_find_properties_by_name_import;
#define grpc_auth_context_find_properties_by_name grpc_auth_context_find_properties_by_name_import
typedef const char *(*grpc_auth_context_peer_identity_property_name_type)(const grpc_auth_context *ctx);
extern grpc_auth_context_peer_identity_property_name_type grpc_auth_context_peer_identity_property_name_import;
#define grpc_auth_context_peer_identity_property_name grpc_auth_context_peer_identity_property_name_import
typedef int(*grpc_auth_context_peer_is_authenticated_type)(const grpc_auth_context *ctx);
extern grpc_auth_context_peer_is_authenticated_type grpc_auth_context_peer_is_authenticated_import;
#define grpc_auth_context_peer_is_authenticated grpc_auth_context_peer_is_authenticated_import
typedef grpc_auth_context *(*grpc_call_auth_context_type)(grpc_call *call);
extern grpc_call_auth_context_type grpc_call_auth_context_import;
#define grpc_call_auth_context grpc_call_auth_context_import
typedef void(*grpc_auth_context_release_type)(grpc_auth_context *context);
extern grpc_auth_context_release_type grpc_auth_context_release_import;
#define grpc_auth_context_release grpc_auth_context_release_import
typedef void(*grpc_auth_context_add_property_type)(grpc_auth_context *ctx, const char *name, const char *value, size_t value_length);
extern grpc_auth_context_add_property_type grpc_auth_context_add_property_import;
#define grpc_auth_context_add_property grpc_auth_context_add_property_import
typedef void(*grpc_auth_context_add_cstring_property_type)(grpc_auth_context *ctx, const char *name, const char *value);
extern grpc_auth_context_add_cstring_property_type grpc_auth_context_add_cstring_property_import;
#define grpc_auth_context_add_cstring_property grpc_auth_context_add_cstring_property_import
typedef int(*grpc_auth_context_set_peer_identity_property_name_type)(grpc_auth_context *ctx, const char *name);
extern grpc_auth_context_set_peer_identity_property_name_type grpc_auth_context_set_peer_identity_property_name_import;
#define grpc_auth_context_set_peer_identity_property_name grpc_auth_context_set_peer_identity_property_name_import
typedef void(*grpc_channel_credentials_release_type)(grpc_channel_credentials *creds);
extern grpc_channel_credentials_release_type grpc_channel_credentials_release_import;
#define grpc_channel_credentials_release grpc_channel_credentials_release_import
typedef grpc_channel_credentials *(*grpc_google_default_credentials_create_type)(void);
extern grpc_google_default_credentials_create_type grpc_google_default_credentials_create_import;
#define grpc_google_default_credentials_create grpc_google_default_credentials_create_import
typedef grpc_channel_credentials *(*grpc_ssl_credentials_create_type)(const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair, void *reserved);
extern grpc_ssl_credentials_create_type grpc_ssl_credentials_create_import;
#define grpc_ssl_credentials_create grpc_ssl_credentials_create_import
typedef void(*grpc_call_credentials_release_type)(grpc_call_credentials *creds);
extern grpc_call_credentials_release_type grpc_call_credentials_release_import;
#define grpc_call_credentials_release grpc_call_credentials_release_import
typedef grpc_channel_credentials *(*grpc_composite_channel_credentials_create_type)(grpc_channel_credentials *channel_creds, grpc_call_credentials *call_creds, void *reserved);
extern grpc_composite_channel_credentials_create_type grpc_composite_channel_credentials_create_import;
#define grpc_composite_channel_credentials_create grpc_composite_channel_credentials_create_import
typedef grpc_call_credentials *(*grpc_composite_call_credentials_create_type)(grpc_call_credentials *creds1, grpc_call_credentials *creds2, void *reserved);
extern grpc_composite_call_credentials_create_type grpc_composite_call_credentials_create_import;
#define grpc_composite_call_credentials_create grpc_composite_call_credentials_create_import
typedef grpc_call_credentials *(*grpc_google_compute_engine_credentials_create_type)(void *reserved);
extern grpc_google_compute_engine_credentials_create_type grpc_google_compute_engine_credentials_create_import;
#define grpc_google_compute_engine_credentials_create grpc_google_compute_engine_credentials_create_import
typedef gpr_timespec(*grpc_max_auth_token_lifetime_type)();
extern grpc_max_auth_token_lifetime_type grpc_max_auth_token_lifetime_import;
#define grpc_max_auth_token_lifetime grpc_max_auth_token_lifetime_import
typedef grpc_call_credentials *(*grpc_service_account_jwt_access_credentials_create_type)(const char *json_key, gpr_timespec token_lifetime, void *reserved);
extern grpc_service_account_jwt_access_credentials_create_type grpc_service_account_jwt_access_credentials_create_import;
#define grpc_service_account_jwt_access_credentials_create grpc_service_account_jwt_access_credentials_create_import
typedef grpc_call_credentials *(*grpc_google_refresh_token_credentials_create_type)(const char *json_refresh_token, void *reserved);
extern grpc_google_refresh_token_credentials_create_type grpc_google_refresh_token_credentials_create_import;
#define grpc_google_refresh_token_credentials_create grpc_google_refresh_token_credentials_create_import
typedef grpc_call_credentials *(*grpc_access_token_credentials_create_type)(const char *access_token, void *reserved);
extern grpc_access_token_credentials_create_type grpc_access_token_credentials_create_import;
#define grpc_access_token_credentials_create grpc_access_token_credentials_create_import
typedef grpc_call_credentials *(*grpc_google_iam_credentials_create_type)(const char *authorization_token, const char *authority_selector, void *reserved);
extern grpc_google_iam_credentials_create_type grpc_google_iam_credentials_create_import;
#define grpc_google_iam_credentials_create grpc_google_iam_credentials_create_import
typedef grpc_call_credentials *(*grpc_metadata_credentials_create_from_plugin_type)(grpc_metadata_credentials_plugin plugin, void *reserved);
extern grpc_metadata_credentials_create_from_plugin_type grpc_metadata_credentials_create_from_plugin_import;
#define grpc_metadata_credentials_create_from_plugin grpc_metadata_credentials_create_from_plugin_import
typedef grpc_channel *(*grpc_secure_channel_create_type)(grpc_channel_credentials *creds, const char *target, const grpc_channel_args *args, void *reserved);
extern grpc_secure_channel_create_type grpc_secure_channel_create_import;
#define grpc_secure_channel_create grpc_secure_channel_create_import
typedef void(*grpc_server_credentials_release_type)(grpc_server_credentials *creds);
extern grpc_server_credentials_release_type grpc_server_credentials_release_import;
#define grpc_server_credentials_release grpc_server_credentials_release_import
typedef grpc_server_credentials *(*grpc_ssl_server_credentials_create_type)(const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, size_t num_key_cert_pairs, int force_client_auth, void *reserved);
extern grpc_ssl_server_credentials_create_type grpc_ssl_server_credentials_create_import;
#define grpc_ssl_server_credentials_create grpc_ssl_server_credentials_create_import
typedef int(*grpc_server_add_secure_http2_port_type)(grpc_server *server, const char *addr, grpc_server_credentials *creds);
extern grpc_server_add_secure_http2_port_type grpc_server_add_secure_http2_port_import;
#define grpc_server_add_secure_http2_port grpc_server_add_secure_http2_port_import
typedef grpc_call_error(*grpc_call_set_credentials_type)(grpc_call *call, grpc_call_credentials *creds);
extern grpc_call_set_credentials_type grpc_call_set_credentials_import;
#define grpc_call_set_credentials grpc_call_set_credentials_import
typedef void(*grpc_server_credentials_set_auth_metadata_processor_type)(grpc_server_credentials *creds, grpc_auth_metadata_processor processor);
extern grpc_server_credentials_set_auth_metadata_processor_type grpc_server_credentials_set_auth_metadata_processor_import;
#define grpc_server_credentials_set_auth_metadata_processor grpc_server_credentials_set_auth_metadata_processor_import
typedef void *(*gpr_malloc_type)(size_t size);
extern gpr_malloc_type gpr_malloc_import;
#define gpr_malloc gpr_malloc_import
typedef void(*gpr_free_type)(void *ptr);
extern gpr_free_type gpr_free_import;
#define gpr_free gpr_free_import
typedef void *(*gpr_realloc_type)(void *p, size_t size);
extern gpr_realloc_type gpr_realloc_import;
#define gpr_realloc gpr_realloc_import
typedef void *(*gpr_malloc_aligned_type)(size_t size, size_t alignment_log);
extern gpr_malloc_aligned_type gpr_malloc_aligned_import;
#define gpr_malloc_aligned gpr_malloc_aligned_import
typedef void(*gpr_free_aligned_type)(void *ptr);
extern gpr_free_aligned_type gpr_free_aligned_import;
#define gpr_free_aligned gpr_free_aligned_import
typedef void(*gpr_set_allocation_functions_type)(gpr_allocation_functions functions);
extern gpr_set_allocation_functions_type gpr_set_allocation_functions_import;
#define gpr_set_allocation_functions gpr_set_allocation_functions_import
typedef gpr_allocation_functions(*gpr_get_allocation_functions_type)();
extern gpr_get_allocation_functions_type gpr_get_allocation_functions_import;
#define gpr_get_allocation_functions gpr_get_allocation_functions_import
typedef grpc_byte_buffer *(*grpc_raw_byte_buffer_create_type)(gpr_slice *slices, size_t nslices);
extern grpc_raw_byte_buffer_create_type grpc_raw_byte_buffer_create_import;
#define grpc_raw_byte_buffer_create grpc_raw_byte_buffer_create_import
typedef grpc_byte_buffer *(*grpc_raw_compressed_byte_buffer_create_type)(gpr_slice *slices, size_t nslices, grpc_compression_algorithm compression);
extern grpc_raw_compressed_byte_buffer_create_type grpc_raw_compressed_byte_buffer_create_import;
#define grpc_raw_compressed_byte_buffer_create grpc_raw_compressed_byte_buffer_create_import
typedef grpc_byte_buffer *(*grpc_byte_buffer_copy_type)(grpc_byte_buffer *bb);
extern grpc_byte_buffer_copy_type grpc_byte_buffer_copy_import;
#define grpc_byte_buffer_copy grpc_byte_buffer_copy_import
typedef size_t(*grpc_byte_buffer_length_type)(grpc_byte_buffer *bb);
extern grpc_byte_buffer_length_type grpc_byte_buffer_length_import;
#define grpc_byte_buffer_length grpc_byte_buffer_length_import
typedef void(*grpc_byte_buffer_destroy_type)(grpc_byte_buffer *byte_buffer);
extern grpc_byte_buffer_destroy_type grpc_byte_buffer_destroy_import;
#define grpc_byte_buffer_destroy grpc_byte_buffer_destroy_import
typedef void(*grpc_byte_buffer_reader_init_type)(grpc_byte_buffer_reader *reader, grpc_byte_buffer *buffer);
extern grpc_byte_buffer_reader_init_type grpc_byte_buffer_reader_init_import;
#define grpc_byte_buffer_reader_init grpc_byte_buffer_reader_init_import
typedef void(*grpc_byte_buffer_reader_destroy_type)(grpc_byte_buffer_reader *reader);
extern grpc_byte_buffer_reader_destroy_type grpc_byte_buffer_reader_destroy_import;
#define grpc_byte_buffer_reader_destroy grpc_byte_buffer_reader_destroy_import
typedef int(*grpc_byte_buffer_reader_next_type)(grpc_byte_buffer_reader *reader, gpr_slice *slice);
extern grpc_byte_buffer_reader_next_type grpc_byte_buffer_reader_next_import;
#define grpc_byte_buffer_reader_next grpc_byte_buffer_reader_next_import
typedef gpr_slice(*grpc_byte_buffer_reader_readall_type)(grpc_byte_buffer_reader *reader);
extern grpc_byte_buffer_reader_readall_type grpc_byte_buffer_reader_readall_import;
#define grpc_byte_buffer_reader_readall grpc_byte_buffer_reader_readall_import
typedef grpc_byte_buffer *(*grpc_raw_byte_buffer_from_reader_type)(grpc_byte_buffer_reader *reader);
extern grpc_raw_byte_buffer_from_reader_type grpc_raw_byte_buffer_from_reader_import;
#define grpc_raw_byte_buffer_from_reader grpc_raw_byte_buffer_from_reader_import
typedef void(*gpr_log_type)(const char *file, int line, gpr_log_severity severity, const char *format, ...);
extern gpr_log_type gpr_log_import;
#define gpr_log gpr_log_import
typedef void(*gpr_log_message_type)(const char *file, int line, gpr_log_severity severity, const char *message);
extern gpr_log_message_type gpr_log_message_import;
#define gpr_log_message gpr_log_message_import
typedef void(*gpr_set_log_function_type)(gpr_log_func func);
extern gpr_set_log_function_type gpr_set_log_function_import;
#define gpr_set_log_function gpr_set_log_function_import
typedef gpr_slice(*gpr_slice_ref_type)(gpr_slice s);
extern gpr_slice_ref_type gpr_slice_ref_import;
#define gpr_slice_ref gpr_slice_ref_import
typedef void(*gpr_slice_unref_type)(gpr_slice s);
extern gpr_slice_unref_type gpr_slice_unref_import;
#define gpr_slice_unref gpr_slice_unref_import
typedef gpr_slice(*gpr_slice_new_type)(void *p, size_t len, void (*destroy)(void *));
extern gpr_slice_new_type gpr_slice_new_import;
#define gpr_slice_new gpr_slice_new_import
typedef gpr_slice(*gpr_slice_new_with_len_type)(void *p, size_t len, void (*destroy)(void *, size_t));
extern gpr_slice_new_with_len_type gpr_slice_new_with_len_import;
#define gpr_slice_new_with_len gpr_slice_new_with_len_import
typedef gpr_slice(*gpr_slice_malloc_type)(size_t length);
extern gpr_slice_malloc_type gpr_slice_malloc_import;
#define gpr_slice_malloc gpr_slice_malloc_import
typedef gpr_slice(*gpr_slice_from_copied_string_type)(const char *source);
extern gpr_slice_from_copied_string_type gpr_slice_from_copied_string_import;
#define gpr_slice_from_copied_string gpr_slice_from_copied_string_import
typedef gpr_slice(*gpr_slice_from_copied_buffer_type)(const char *source, size_t len);
extern gpr_slice_from_copied_buffer_type gpr_slice_from_copied_buffer_import;
#define gpr_slice_from_copied_buffer gpr_slice_from_copied_buffer_import
typedef gpr_slice(*gpr_slice_from_static_string_type)(const char *source);
extern gpr_slice_from_static_string_type gpr_slice_from_static_string_import;
#define gpr_slice_from_static_string gpr_slice_from_static_string_import
typedef gpr_slice(*gpr_slice_sub_type)(gpr_slice s, size_t begin, size_t end);
extern gpr_slice_sub_type gpr_slice_sub_import;
#define gpr_slice_sub gpr_slice_sub_import
typedef gpr_slice(*gpr_slice_sub_no_ref_type)(gpr_slice s, size_t begin, size_t end);
extern gpr_slice_sub_no_ref_type gpr_slice_sub_no_ref_import;
#define gpr_slice_sub_no_ref gpr_slice_sub_no_ref_import
typedef gpr_slice(*gpr_slice_split_tail_type)(gpr_slice *s, size_t split);
extern gpr_slice_split_tail_type gpr_slice_split_tail_import;
#define gpr_slice_split_tail gpr_slice_split_tail_import
typedef gpr_slice(*gpr_slice_split_head_type)(gpr_slice *s, size_t split);
extern gpr_slice_split_head_type gpr_slice_split_head_import;
#define gpr_slice_split_head gpr_slice_split_head_import
typedef gpr_slice(*gpr_empty_slice_type)(void);
extern gpr_empty_slice_type gpr_empty_slice_import;
#define gpr_empty_slice gpr_empty_slice_import
typedef int(*gpr_slice_cmp_type)(gpr_slice a, gpr_slice b);
extern gpr_slice_cmp_type gpr_slice_cmp_import;
#define gpr_slice_cmp gpr_slice_cmp_import
typedef int(*gpr_slice_str_cmp_type)(gpr_slice a, const char *b);
extern gpr_slice_str_cmp_type gpr_slice_str_cmp_import;
#define gpr_slice_str_cmp gpr_slice_str_cmp_import
typedef void(*gpr_slice_buffer_init_type)(gpr_slice_buffer *sb);
extern gpr_slice_buffer_init_type gpr_slice_buffer_init_import;
#define gpr_slice_buffer_init gpr_slice_buffer_init_import
typedef void(*gpr_slice_buffer_destroy_type)(gpr_slice_buffer *sb);
extern gpr_slice_buffer_destroy_type gpr_slice_buffer_destroy_import;
#define gpr_slice_buffer_destroy gpr_slice_buffer_destroy_import
typedef void(*gpr_slice_buffer_add_type)(gpr_slice_buffer *sb, gpr_slice slice);
extern gpr_slice_buffer_add_type gpr_slice_buffer_add_import;
#define gpr_slice_buffer_add gpr_slice_buffer_add_import
typedef size_t(*gpr_slice_buffer_add_indexed_type)(gpr_slice_buffer *sb, gpr_slice slice);
extern gpr_slice_buffer_add_indexed_type gpr_slice_buffer_add_indexed_import;
#define gpr_slice_buffer_add_indexed gpr_slice_buffer_add_indexed_import
typedef void(*gpr_slice_buffer_addn_type)(gpr_slice_buffer *sb, gpr_slice *slices, size_t n);
extern gpr_slice_buffer_addn_type gpr_slice_buffer_addn_import;
#define gpr_slice_buffer_addn gpr_slice_buffer_addn_import
typedef uint8_t *(*gpr_slice_buffer_tiny_add_type)(gpr_slice_buffer *sb, size_t len);
extern gpr_slice_buffer_tiny_add_type gpr_slice_buffer_tiny_add_import;
#define gpr_slice_buffer_tiny_add gpr_slice_buffer_tiny_add_import
typedef void(*gpr_slice_buffer_pop_type)(gpr_slice_buffer *sb);
extern gpr_slice_buffer_pop_type gpr_slice_buffer_pop_import;
#define gpr_slice_buffer_pop gpr_slice_buffer_pop_import
typedef void(*gpr_slice_buffer_reset_and_unref_type)(gpr_slice_buffer *sb);
extern gpr_slice_buffer_reset_and_unref_type gpr_slice_buffer_reset_and_unref_import;
#define gpr_slice_buffer_reset_and_unref gpr_slice_buffer_reset_and_unref_import
typedef void(*gpr_slice_buffer_swap_type)(gpr_slice_buffer *a, gpr_slice_buffer *b);
extern gpr_slice_buffer_swap_type gpr_slice_buffer_swap_import;
#define gpr_slice_buffer_swap gpr_slice_buffer_swap_import
typedef void(*gpr_slice_buffer_move_into_type)(gpr_slice_buffer *src, gpr_slice_buffer *dst);
extern gpr_slice_buffer_move_into_type gpr_slice_buffer_move_into_import;
#define gpr_slice_buffer_move_into gpr_slice_buffer_move_into_import
typedef void(*gpr_slice_buffer_trim_end_type)(gpr_slice_buffer *src, size_t n, gpr_slice_buffer *garbage);
extern gpr_slice_buffer_trim_end_type gpr_slice_buffer_trim_end_import;
#define gpr_slice_buffer_trim_end gpr_slice_buffer_trim_end_import
typedef void(*gpr_slice_buffer_move_first_type)(gpr_slice_buffer *src, size_t n, gpr_slice_buffer *dst);
extern gpr_slice_buffer_move_first_type gpr_slice_buffer_move_first_import;
#define gpr_slice_buffer_move_first gpr_slice_buffer_move_first_import
typedef gpr_slice(*gpr_slice_buffer_take_first_type)(gpr_slice_buffer *src);
extern gpr_slice_buffer_take_first_type gpr_slice_buffer_take_first_import;
#define gpr_slice_buffer_take_first gpr_slice_buffer_take_first_import
typedef void(*gpr_mu_init_type)(gpr_mu *mu);
extern gpr_mu_init_type gpr_mu_init_import;
#define gpr_mu_init gpr_mu_init_import
typedef void(*gpr_mu_destroy_type)(gpr_mu *mu);
extern gpr_mu_destroy_type gpr_mu_destroy_import;
#define gpr_mu_destroy gpr_mu_destroy_import
typedef void(*gpr_mu_lock_type)(gpr_mu *mu);
extern gpr_mu_lock_type gpr_mu_lock_import;
#define gpr_mu_lock gpr_mu_lock_import
typedef void(*gpr_mu_unlock_type)(gpr_mu *mu);
extern gpr_mu_unlock_type gpr_mu_unlock_import;
#define gpr_mu_unlock gpr_mu_unlock_import
typedef int(*gpr_mu_trylock_type)(gpr_mu *mu);
extern gpr_mu_trylock_type gpr_mu_trylock_import;
#define gpr_mu_trylock gpr_mu_trylock_import
typedef void(*gpr_cv_init_type)(gpr_cv *cv);
extern gpr_cv_init_type gpr_cv_init_import;
#define gpr_cv_init gpr_cv_init_import
typedef void(*gpr_cv_destroy_type)(gpr_cv *cv);
extern gpr_cv_destroy_type gpr_cv_destroy_import;
#define gpr_cv_destroy gpr_cv_destroy_import
typedef int(*gpr_cv_wait_type)(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline);
extern gpr_cv_wait_type gpr_cv_wait_import;
#define gpr_cv_wait gpr_cv_wait_import
typedef void(*gpr_cv_signal_type)(gpr_cv *cv);
extern gpr_cv_signal_type gpr_cv_signal_import;
#define gpr_cv_signal gpr_cv_signal_import
typedef void(*gpr_cv_broadcast_type)(gpr_cv *cv);
extern gpr_cv_broadcast_type gpr_cv_broadcast_import;
#define gpr_cv_broadcast gpr_cv_broadcast_import
typedef void(*gpr_once_init_type)(gpr_once *once, void (*init_routine)(void));
extern gpr_once_init_type gpr_once_init_import;
#define gpr_once_init gpr_once_init_import
typedef void(*gpr_event_init_type)(gpr_event *ev);
extern gpr_event_init_type gpr_event_init_import;
#define gpr_event_init gpr_event_init_import
typedef void(*gpr_event_set_type)(gpr_event *ev, void *value);
extern gpr_event_set_type gpr_event_set_import;
#define gpr_event_set gpr_event_set_import
typedef void *(*gpr_event_get_type)(gpr_event *ev);
extern gpr_event_get_type gpr_event_get_import;
#define gpr_event_get gpr_event_get_import
typedef void *(*gpr_event_wait_type)(gpr_event *ev, gpr_timespec abs_deadline);
extern gpr_event_wait_type gpr_event_wait_import;
#define gpr_event_wait gpr_event_wait_import
typedef void(*gpr_ref_init_type)(gpr_refcount *r, int n);
extern gpr_ref_init_type gpr_ref_init_import;
#define gpr_ref_init gpr_ref_init_import
typedef void(*gpr_ref_type)(gpr_refcount *r);
extern gpr_ref_type gpr_ref_import;
#define gpr_ref gpr_ref_import
typedef void(*gpr_refn_type)(gpr_refcount *r, int n);
extern gpr_refn_type gpr_refn_import;
#define gpr_refn gpr_refn_import
typedef int(*gpr_unref_type)(gpr_refcount *r);
extern gpr_unref_type gpr_unref_import;
#define gpr_unref gpr_unref_import
typedef void(*gpr_stats_init_type)(gpr_stats_counter *c, intptr_t n);
extern gpr_stats_init_type gpr_stats_init_import;
#define gpr_stats_init gpr_stats_init_import
typedef void(*gpr_stats_inc_type)(gpr_stats_counter *c, intptr_t inc);
extern gpr_stats_inc_type gpr_stats_inc_import;
#define gpr_stats_inc gpr_stats_inc_import
typedef intptr_t(*gpr_stats_read_type)(const gpr_stats_counter *c);
extern gpr_stats_read_type gpr_stats_read_import;
#define gpr_stats_read gpr_stats_read_import
typedef gpr_timespec(*gpr_time_0_type)(gpr_clock_type type);
extern gpr_time_0_type gpr_time_0_import;
#define gpr_time_0 gpr_time_0_import
typedef gpr_timespec(*gpr_inf_future_type)(gpr_clock_type type);
extern gpr_inf_future_type gpr_inf_future_import;
#define gpr_inf_future gpr_inf_future_import
typedef gpr_timespec(*gpr_inf_past_type)(gpr_clock_type type);
extern gpr_inf_past_type gpr_inf_past_import;
#define gpr_inf_past gpr_inf_past_import
typedef void(*gpr_time_init_type)(void);
extern gpr_time_init_type gpr_time_init_import;
#define gpr_time_init gpr_time_init_import
typedef gpr_timespec(*gpr_now_type)(gpr_clock_type clock);
extern gpr_now_type gpr_now_import;
#define gpr_now gpr_now_import
typedef gpr_timespec(*gpr_convert_clock_type_type)(gpr_timespec t, gpr_clock_type target_clock);
extern gpr_convert_clock_type_type gpr_convert_clock_type_import;
#define gpr_convert_clock_type gpr_convert_clock_type_import
typedef int(*gpr_time_cmp_type)(gpr_timespec a, gpr_timespec b);
extern gpr_time_cmp_type gpr_time_cmp_import;
#define gpr_time_cmp gpr_time_cmp_import
typedef gpr_timespec(*gpr_time_max_type)(gpr_timespec a, gpr_timespec b);
extern gpr_time_max_type gpr_time_max_import;
#define gpr_time_max gpr_time_max_import
typedef gpr_timespec(*gpr_time_min_type)(gpr_timespec a, gpr_timespec b);
extern gpr_time_min_type gpr_time_min_import;
#define gpr_time_min gpr_time_min_import
typedef gpr_timespec(*gpr_time_add_type)(gpr_timespec a, gpr_timespec b);
extern gpr_time_add_type gpr_time_add_import;
#define gpr_time_add gpr_time_add_import
typedef gpr_timespec(*gpr_time_sub_type)(gpr_timespec a, gpr_timespec b);
extern gpr_time_sub_type gpr_time_sub_import;
#define gpr_time_sub gpr_time_sub_import
typedef gpr_timespec(*gpr_time_from_micros_type)(long x, gpr_clock_type clock_type);
extern gpr_time_from_micros_type gpr_time_from_micros_import;
#define gpr_time_from_micros gpr_time_from_micros_import
typedef gpr_timespec(*gpr_time_from_nanos_type)(long x, gpr_clock_type clock_type);
extern gpr_time_from_nanos_type gpr_time_from_nanos_import;
#define gpr_time_from_nanos gpr_time_from_nanos_import
typedef gpr_timespec(*gpr_time_from_millis_type)(long x, gpr_clock_type clock_type);
extern gpr_time_from_millis_type gpr_time_from_millis_import;
#define gpr_time_from_millis gpr_time_from_millis_import
typedef gpr_timespec(*gpr_time_from_seconds_type)(long x, gpr_clock_type clock_type);
extern gpr_time_from_seconds_type gpr_time_from_seconds_import;
#define gpr_time_from_seconds gpr_time_from_seconds_import
typedef gpr_timespec(*gpr_time_from_minutes_type)(long x, gpr_clock_type clock_type);
extern gpr_time_from_minutes_type gpr_time_from_minutes_import;
#define gpr_time_from_minutes gpr_time_from_minutes_import
typedef gpr_timespec(*gpr_time_from_hours_type)(long x, gpr_clock_type clock_type);
extern gpr_time_from_hours_type gpr_time_from_hours_import;
#define gpr_time_from_hours gpr_time_from_hours_import
typedef int32_t(*gpr_time_to_millis_type)(gpr_timespec timespec);
extern gpr_time_to_millis_type gpr_time_to_millis_import;
#define gpr_time_to_millis gpr_time_to_millis_import
typedef int(*gpr_time_similar_type)(gpr_timespec a, gpr_timespec b, gpr_timespec threshold);
extern gpr_time_similar_type gpr_time_similar_import;
#define gpr_time_similar gpr_time_similar_import
typedef void(*gpr_sleep_until_type)(gpr_timespec until);
extern gpr_sleep_until_type gpr_sleep_until_import;
#define gpr_sleep_until gpr_sleep_until_import
typedef double(*gpr_timespec_to_micros_type)(gpr_timespec t);
extern gpr_timespec_to_micros_type gpr_timespec_to_micros_import;
#define gpr_timespec_to_micros gpr_timespec_to_micros_import
typedef gpr_avl(*gpr_avl_create_type)(const gpr_avl_vtable *vtable);
extern gpr_avl_create_type gpr_avl_create_import;
#define gpr_avl_create gpr_avl_create_import
typedef gpr_avl(*gpr_avl_ref_type)(gpr_avl avl);
extern gpr_avl_ref_type gpr_avl_ref_import;
#define gpr_avl_ref gpr_avl_ref_import
typedef void(*gpr_avl_unref_type)(gpr_avl avl);
extern gpr_avl_unref_type gpr_avl_unref_import;
#define gpr_avl_unref gpr_avl_unref_import
typedef gpr_avl(*gpr_avl_add_type)(gpr_avl avl, void *key, void *value);
extern gpr_avl_add_type gpr_avl_add_import;
#define gpr_avl_add gpr_avl_add_import
typedef gpr_avl(*gpr_avl_remove_type)(gpr_avl avl, void *key);
extern gpr_avl_remove_type gpr_avl_remove_import;
#define gpr_avl_remove gpr_avl_remove_import
typedef void *(*gpr_avl_get_type)(gpr_avl avl, void *key);
extern gpr_avl_get_type gpr_avl_get_import;
#define gpr_avl_get gpr_avl_get_import
typedef gpr_cmdline *(*gpr_cmdline_create_type)(const char *description);
extern gpr_cmdline_create_type gpr_cmdline_create_import;
#define gpr_cmdline_create gpr_cmdline_create_import
typedef void(*gpr_cmdline_add_int_type)(gpr_cmdline *cl, const char *name, const char *help, int *value);
extern gpr_cmdline_add_int_type gpr_cmdline_add_int_import;
#define gpr_cmdline_add_int gpr_cmdline_add_int_import
typedef void(*gpr_cmdline_add_flag_type)(gpr_cmdline *cl, const char *name, const char *help, int *value);
extern gpr_cmdline_add_flag_type gpr_cmdline_add_flag_import;
#define gpr_cmdline_add_flag gpr_cmdline_add_flag_import
typedef void(*gpr_cmdline_add_string_type)(gpr_cmdline *cl, const char *name, const char *help, char **value);
extern gpr_cmdline_add_string_type gpr_cmdline_add_string_import;
#define gpr_cmdline_add_string gpr_cmdline_add_string_import
typedef void(*gpr_cmdline_on_extra_arg_type)(gpr_cmdline *cl, const char *name, const char *help, void (*on_extra_arg)(void *user_data, const char *arg), void *user_data);
extern gpr_cmdline_on_extra_arg_type gpr_cmdline_on_extra_arg_import;
#define gpr_cmdline_on_extra_arg gpr_cmdline_on_extra_arg_import
typedef void(*gpr_cmdline_set_survive_failure_type)(gpr_cmdline *cl);
extern gpr_cmdline_set_survive_failure_type gpr_cmdline_set_survive_failure_import;
#define gpr_cmdline_set_survive_failure gpr_cmdline_set_survive_failure_import
typedef int(*gpr_cmdline_parse_type)(gpr_cmdline *cl, int argc, char **argv);
extern gpr_cmdline_parse_type gpr_cmdline_parse_import;
#define gpr_cmdline_parse gpr_cmdline_parse_import
typedef void(*gpr_cmdline_destroy_type)(gpr_cmdline *cl);
extern gpr_cmdline_destroy_type gpr_cmdline_destroy_import;
#define gpr_cmdline_destroy gpr_cmdline_destroy_import
typedef char *(*gpr_cmdline_usage_string_type)(gpr_cmdline *cl, const char *argv0);
extern gpr_cmdline_usage_string_type gpr_cmdline_usage_string_import;
#define gpr_cmdline_usage_string gpr_cmdline_usage_string_import
typedef unsigned(*gpr_cpu_num_cores_type)(void);
extern gpr_cpu_num_cores_type gpr_cpu_num_cores_import;
#define gpr_cpu_num_cores gpr_cpu_num_cores_import
typedef unsigned(*gpr_cpu_current_cpu_type)(void);
extern gpr_cpu_current_cpu_type gpr_cpu_current_cpu_import;
#define gpr_cpu_current_cpu gpr_cpu_current_cpu_import
typedef gpr_histogram *(*gpr_histogram_create_type)(double resolution, double max_bucket_start);
extern gpr_histogram_create_type gpr_histogram_create_import;
#define gpr_histogram_create gpr_histogram_create_import
typedef void(*gpr_histogram_destroy_type)(gpr_histogram *h);
extern gpr_histogram_destroy_type gpr_histogram_destroy_import;
#define gpr_histogram_destroy gpr_histogram_destroy_import
typedef void(*gpr_histogram_add_type)(gpr_histogram *h, double x);
extern gpr_histogram_add_type gpr_histogram_add_import;
#define gpr_histogram_add gpr_histogram_add_import
typedef int(*gpr_histogram_merge_type)(gpr_histogram *dst, const gpr_histogram *src);
extern gpr_histogram_merge_type gpr_histogram_merge_import;
#define gpr_histogram_merge gpr_histogram_merge_import
typedef double(*gpr_histogram_percentile_type)(gpr_histogram *histogram, double percentile);
extern gpr_histogram_percentile_type gpr_histogram_percentile_import;
#define gpr_histogram_percentile gpr_histogram_percentile_import
typedef double(*gpr_histogram_mean_type)(gpr_histogram *histogram);
extern gpr_histogram_mean_type gpr_histogram_mean_import;
#define gpr_histogram_mean gpr_histogram_mean_import
typedef double(*gpr_histogram_stddev_type)(gpr_histogram *histogram);
extern gpr_histogram_stddev_type gpr_histogram_stddev_import;
#define gpr_histogram_stddev gpr_histogram_stddev_import
typedef double(*gpr_histogram_variance_type)(gpr_histogram *histogram);
extern gpr_histogram_variance_type gpr_histogram_variance_import;
#define gpr_histogram_variance gpr_histogram_variance_import
typedef double(*gpr_histogram_maximum_type)(gpr_histogram *histogram);
extern gpr_histogram_maximum_type gpr_histogram_maximum_import;
#define gpr_histogram_maximum gpr_histogram_maximum_import
typedef double(*gpr_histogram_minimum_type)(gpr_histogram *histogram);
extern gpr_histogram_minimum_type gpr_histogram_minimum_import;
#define gpr_histogram_minimum gpr_histogram_minimum_import
typedef double(*gpr_histogram_count_type)(gpr_histogram *histogram);
extern gpr_histogram_count_type gpr_histogram_count_import;
#define gpr_histogram_count gpr_histogram_count_import
typedef double(*gpr_histogram_sum_type)(gpr_histogram *histogram);
extern gpr_histogram_sum_type gpr_histogram_sum_import;
#define gpr_histogram_sum gpr_histogram_sum_import
typedef double(*gpr_histogram_sum_of_squares_type)(gpr_histogram *histogram);
extern gpr_histogram_sum_of_squares_type gpr_histogram_sum_of_squares_import;
#define gpr_histogram_sum_of_squares gpr_histogram_sum_of_squares_import
typedef const uint32_t *(*gpr_histogram_get_contents_type)(gpr_histogram *histogram, size_t *count);
extern gpr_histogram_get_contents_type gpr_histogram_get_contents_import;
#define gpr_histogram_get_contents gpr_histogram_get_contents_import
typedef void(*gpr_histogram_merge_contents_type)(gpr_histogram *histogram, const uint32_t *data, size_t data_count, double min_seen, double max_seen, double sum, double sum_of_squares, double count);
extern gpr_histogram_merge_contents_type gpr_histogram_merge_contents_import;
#define gpr_histogram_merge_contents gpr_histogram_merge_contents_import
typedef int(*gpr_join_host_port_type)(char **out, const char *host, int port);
extern gpr_join_host_port_type gpr_join_host_port_import;
#define gpr_join_host_port gpr_join_host_port_import
typedef int(*gpr_split_host_port_type)(const char *name, char **host, char **port);
extern gpr_split_host_port_type gpr_split_host_port_import;
#define gpr_split_host_port gpr_split_host_port_import
typedef char *(*gpr_format_message_type)(int messageid);
extern gpr_format_message_type gpr_format_message_import;
#define gpr_format_message gpr_format_message_import
typedef char *(*gpr_strdup_type)(const char *src);
extern gpr_strdup_type gpr_strdup_import;
#define gpr_strdup gpr_strdup_import
typedef int(*gpr_asprintf_type)(char **strp, const char *format, ...);
extern gpr_asprintf_type gpr_asprintf_import;
#define gpr_asprintf gpr_asprintf_import
typedef const char *(*gpr_subprocess_binary_extension_type)();
extern gpr_subprocess_binary_extension_type gpr_subprocess_binary_extension_import;
#define gpr_subprocess_binary_extension gpr_subprocess_binary_extension_import
typedef gpr_subprocess *(*gpr_subprocess_create_type)(int argc, const char **argv);
extern gpr_subprocess_create_type gpr_subprocess_create_import;
#define gpr_subprocess_create gpr_subprocess_create_import
typedef void(*gpr_subprocess_destroy_type)(gpr_subprocess *p);
extern gpr_subprocess_destroy_type gpr_subprocess_destroy_import;
#define gpr_subprocess_destroy gpr_subprocess_destroy_import
typedef int(*gpr_subprocess_join_type)(gpr_subprocess *p);
extern gpr_subprocess_join_type gpr_subprocess_join_import;
#define gpr_subprocess_join gpr_subprocess_join_import
typedef void(*gpr_subprocess_interrupt_type)(gpr_subprocess *p);
extern gpr_subprocess_interrupt_type gpr_subprocess_interrupt_import;
#define gpr_subprocess_interrupt gpr_subprocess_interrupt_import
typedef int(*gpr_thd_new_type)(gpr_thd_id *t, void (*thd_body)(void *arg), void *arg, const gpr_thd_options *options);
extern gpr_thd_new_type gpr_thd_new_import;
#define gpr_thd_new gpr_thd_new_import
typedef gpr_thd_options(*gpr_thd_options_default_type)(void);
extern gpr_thd_options_default_type gpr_thd_options_default_import;
#define gpr_thd_options_default gpr_thd_options_default_import
typedef void(*gpr_thd_options_set_detached_type)(gpr_thd_options *options);
extern gpr_thd_options_set_detached_type gpr_thd_options_set_detached_import;
#define gpr_thd_options_set_detached gpr_thd_options_set_detached_import
typedef void(*gpr_thd_options_set_joinable_type)(gpr_thd_options *options);
extern gpr_thd_options_set_joinable_type gpr_thd_options_set_joinable_import;
#define gpr_thd_options_set_joinable gpr_thd_options_set_joinable_import
typedef int(*gpr_thd_options_is_detached_type)(const gpr_thd_options *options);
extern gpr_thd_options_is_detached_type gpr_thd_options_is_detached_import;
#define gpr_thd_options_is_detached gpr_thd_options_is_detached_import
typedef int(*gpr_thd_options_is_joinable_type)(const gpr_thd_options *options);
extern gpr_thd_options_is_joinable_type gpr_thd_options_is_joinable_import;
#define gpr_thd_options_is_joinable gpr_thd_options_is_joinable_import
typedef gpr_thd_id(*gpr_thd_currentid_type)(void);
extern gpr_thd_currentid_type gpr_thd_currentid_import;
#define gpr_thd_currentid gpr_thd_currentid_import
typedef void(*gpr_thd_join_type)(gpr_thd_id t);
extern gpr_thd_join_type gpr_thd_join_import;
#define gpr_thd_join gpr_thd_join_import
void pygrpc_load_imports(HMODULE library);
#else /* !GPR_WIN32 */
#include <grpc/support/alloc.h>
#include <grpc/support/slice.h>
#include <grpc/support/time.h>
#include <grpc/status.h>
#include <grpc/byte_buffer.h>
#include <grpc/byte_buffer_reader.h>
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
#endif /* !GPR_WIN32 */
#endif

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -31,17 +31,29 @@
*
*/
#ifndef GRPC_INTERNAL_CORE_CENSUS_CONTEXT_H
#define GRPC_INTERNAL_CORE_CENSUS_CONTEXT_H
#include "loader.h"
#include <grpc/census.h>
#if GPR_WIN32
#define GRPC_CENSUS_MAX_ON_THE_WIRE_TAG_BYTES 2048
int pygrpc_load_core(char *path) {
HMODULE grpc_c;
#ifdef GPR_ARCH_32
/* Close your eyes for a moment, it'll all be over soon. */
char *six = strrchr(path, '6');
*six++ = '3';
*six = '2';
#endif
grpc_c = LoadLibraryA(path);
if (grpc_c) {
pygrpc_load_imports(grpc_c);
return 1;
}
/* census_context is the in-memory representation of information needed to
* maintain tracing, RPC statistics and resource usage information. */
struct census_context {
census_tag_set *tags; /* Opaque data structure for census tags. */
};
return 0;
}
#endif /* GRPC_INTERNAL_CORE_CENSUS_CONTEXT_H */
#else
int pygrpc_load_core(char *path) { return 1; }
#endif

@ -0,0 +1,45 @@
/*
*
* 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 PYGRPC_LOADER_H_
#define PYGRPC_LOADER_H_
#include "imports.generated.h"
/* Additional inclusions not covered by "imports.generated.h" */
#include <grpc/byte_buffer_reader.h>
/* Attempts to load the core if necessary, and return non-zero upon succes. */
int pygrpc_load_core(char *path);
#endif /* GRPC_RB_BYTE_BUFFER_H_ */

@ -225,7 +225,6 @@ CORE_SOURCE_FILES = [
'src/core/census/initialize.c',
'src/core/census/operation.c',
'src/core/census/placeholders.c',
'src/core/census/tag_set.c',
'src/core/census/tracing.c',
'src/boringssl/err_data.c',
'third_party/boringssl/crypto/aes/aes.c',

@ -67,14 +67,15 @@ else
end
unless File.exist?(File.join(grpc_lib_dir, 'libgrpc.a')) or windows
for var in %w( CC AR ) do
ENV[var] = RbConfig::CONFIG[var]
end
ENV['AR'] = RbConfig::CONFIG['AR'] + ' rcs'
ENV['CC'] = RbConfig::CONFIG['CC']
ENV['LD'] = ENV['CC']
ENV['AR'] = 'libtool -o' if RUBY_PLATFORM =~ /darwin/
ENV['EMBED_OPENSSL'] = 'true'
ENV['EMBED_ZLIB'] = 'true'
ENV['ARCH_FLAGS'] = '-arch i386 -arch x86_64' if RUBY_PLATFORM =~ /darwin/
output_dir = File.expand_path(RbConfig::CONFIG['topdir'])
grpc_lib_dir = File.join(output_dir, 'libs', grpc_config)
@ -107,6 +108,7 @@ puts 'Generating Makefile for ' + output
create_makefile(output)
strip_tool = RbConfig::CONFIG['STRIP']
strip_tool = 'strip -x' if RUBY_PLATFORM =~ /darwin/
if grpc_config == 'opt'
File.open('Makefile.new', 'w') do |o|

@ -41,7 +41,14 @@ census_initialize_type census_initialize_import;
census_shutdown_type census_shutdown_import;
census_supported_type census_supported_import;
census_enabled_type census_enabled_import;
census_context_serialize_type census_context_serialize_import;
census_context_create_type census_context_create_import;
census_context_destroy_type census_context_destroy_import;
census_context_get_status_type census_context_get_status_import;
census_context_initialize_iterator_type census_context_initialize_iterator_import;
census_context_next_tag_type census_context_next_tag_import;
census_context_get_tag_type census_context_get_tag_import;
census_context_encode_type census_context_encode_import;
census_context_decode_type census_context_decode_import;
census_trace_mask_type census_trace_mask_import;
census_set_trace_mask_type census_set_trace_mask_import;
census_start_rpc_op_timestamp_type census_start_rpc_op_timestamp_import;
@ -54,15 +61,6 @@ 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_tag_set_create_type census_tag_set_create_import;
census_tag_set_destroy_type census_tag_set_destroy_import;
census_tag_set_get_create_status_type census_tag_set_get_create_status_import;
census_tag_set_initialize_iterator_type census_tag_set_initialize_iterator_import;
census_tag_set_next_tag_type census_tag_set_next_tag_import;
census_tag_set_get_tag_by_key_type census_tag_set_get_tag_by_key_import;
census_tag_set_encode_type census_tag_set_encode_import;
census_tag_set_decode_type census_tag_set_decode_import;
census_context_tag_set_type census_context_tag_set_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;
@ -303,7 +301,14 @@ void grpc_rb_load_imports(HMODULE library) {
census_shutdown_import = (census_shutdown_type) GetProcAddress(library, "census_shutdown");
census_supported_import = (census_supported_type) GetProcAddress(library, "census_supported");
census_enabled_import = (census_enabled_type) GetProcAddress(library, "census_enabled");
census_context_serialize_import = (census_context_serialize_type) GetProcAddress(library, "census_context_serialize");
census_context_create_import = (census_context_create_type) GetProcAddress(library, "census_context_create");
census_context_destroy_import = (census_context_destroy_type) GetProcAddress(library, "census_context_destroy");
census_context_get_status_import = (census_context_get_status_type) GetProcAddress(library, "census_context_get_status");
census_context_initialize_iterator_import = (census_context_initialize_iterator_type) GetProcAddress(library, "census_context_initialize_iterator");
census_context_next_tag_import = (census_context_next_tag_type) GetProcAddress(library, "census_context_next_tag");
census_context_get_tag_import = (census_context_get_tag_type) GetProcAddress(library, "census_context_get_tag");
census_context_encode_import = (census_context_encode_type) GetProcAddress(library, "census_context_encode");
census_context_decode_import = (census_context_decode_type) GetProcAddress(library, "census_context_decode");
census_trace_mask_import = (census_trace_mask_type) GetProcAddress(library, "census_trace_mask");
census_set_trace_mask_import = (census_set_trace_mask_type) GetProcAddress(library, "census_set_trace_mask");
census_start_rpc_op_timestamp_import = (census_start_rpc_op_timestamp_type) GetProcAddress(library, "census_start_rpc_op_timestamp");
@ -316,15 +321,6 @@ 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_tag_set_create_import = (census_tag_set_create_type) GetProcAddress(library, "census_tag_set_create");
census_tag_set_destroy_import = (census_tag_set_destroy_type) GetProcAddress(library, "census_tag_set_destroy");
census_tag_set_get_create_status_import = (census_tag_set_get_create_status_type) GetProcAddress(library, "census_tag_set_get_create_status");
census_tag_set_initialize_iterator_import = (census_tag_set_initialize_iterator_type) GetProcAddress(library, "census_tag_set_initialize_iterator");
census_tag_set_next_tag_import = (census_tag_set_next_tag_type) GetProcAddress(library, "census_tag_set_next_tag");
census_tag_set_get_tag_by_key_import = (census_tag_set_get_tag_by_key_type) GetProcAddress(library, "census_tag_set_get_tag_by_key");
census_tag_set_encode_import = (census_tag_set_encode_type) GetProcAddress(library, "census_tag_set_encode");
census_tag_set_decode_import = (census_tag_set_decode_type) GetProcAddress(library, "census_tag_set_decode");
census_context_tag_set_import = (census_context_tag_set_type) GetProcAddress(library, "census_context_tag_set");
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");

@ -73,9 +73,30 @@ extern census_supported_type census_supported_import;
typedef int(*census_enabled_type)(void);
extern census_enabled_type census_enabled_import;
#define census_enabled census_enabled_import
typedef size_t(*census_context_serialize_type)(const census_context *context, char *buffer, size_t buf_size);
extern census_context_serialize_type census_context_serialize_import;
#define census_context_serialize census_context_serialize_import
typedef census_context *(*census_context_create_type)(const census_context *base, const census_tag *tags, int ntags, census_context_status const **status);
extern census_context_create_type census_context_create_import;
#define census_context_create census_context_create_import
typedef void(*census_context_destroy_type)(census_context *context);
extern census_context_destroy_type census_context_destroy_import;
#define census_context_destroy census_context_destroy_import
typedef const census_context_status *(*census_context_get_status_type)(const census_context *context);
extern census_context_get_status_type census_context_get_status_import;
#define census_context_get_status census_context_get_status_import
typedef void(*census_context_initialize_iterator_type)(const census_context *context, census_context_iterator *iterator);
extern census_context_initialize_iterator_type census_context_initialize_iterator_import;
#define census_context_initialize_iterator census_context_initialize_iterator_import
typedef int(*census_context_next_tag_type)(census_context_iterator *iterator, census_tag *tag);
extern census_context_next_tag_type census_context_next_tag_import;
#define census_context_next_tag census_context_next_tag_import
typedef int(*census_context_get_tag_type)(const census_context *context, const char *key, census_tag *tag);
extern census_context_get_tag_type census_context_get_tag_import;
#define census_context_get_tag census_context_get_tag_import
typedef char *(*census_context_encode_type)(const census_context *context, char *buffer, size_t buf_size, size_t *print_buf_size, size_t *bin_buf_size);
extern census_context_encode_type census_context_encode_import;
#define census_context_encode census_context_encode_import
typedef census_context *(*census_context_decode_type)(const char *buffer, size_t size, const char *bin_buffer, size_t bin_size);
extern census_context_decode_type census_context_decode_import;
#define census_context_decode census_context_decode_import
typedef int(*census_trace_mask_type)(const census_context *context);
extern census_trace_mask_type census_trace_mask_import;
#define census_trace_mask census_trace_mask_import
@ -112,37 +133,10 @@ 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 census_tag_set *(*census_tag_set_create_type)(const census_tag_set *base, const census_tag *tags, int ntags, census_tag_set_create_status const **status);
extern census_tag_set_create_type census_tag_set_create_import;
#define census_tag_set_create census_tag_set_create_import
typedef void(*census_tag_set_destroy_type)(census_tag_set *tags);
extern census_tag_set_destroy_type census_tag_set_destroy_import;
#define census_tag_set_destroy census_tag_set_destroy_import
typedef const census_tag_set_create_status *(*census_tag_set_get_create_status_type)(const census_tag_set *tags);
extern census_tag_set_get_create_status_type census_tag_set_get_create_status_import;
#define census_tag_set_get_create_status census_tag_set_get_create_status_import
typedef void(*census_tag_set_initialize_iterator_type)(const census_tag_set *tags, census_tag_set_iterator *iterator);
extern census_tag_set_initialize_iterator_type census_tag_set_initialize_iterator_import;
#define census_tag_set_initialize_iterator census_tag_set_initialize_iterator_import
typedef int(*census_tag_set_next_tag_type)(census_tag_set_iterator *iterator, census_tag *tag);
extern census_tag_set_next_tag_type census_tag_set_next_tag_import;
#define census_tag_set_next_tag census_tag_set_next_tag_import
typedef int(*census_tag_set_get_tag_by_key_type)(const census_tag_set *tags, const char *key, census_tag *tag);
extern census_tag_set_get_tag_by_key_type census_tag_set_get_tag_by_key_import;
#define census_tag_set_get_tag_by_key census_tag_set_get_tag_by_key_import
typedef char *(*census_tag_set_encode_type)(const census_tag_set *tags, char *buffer, size_t buf_size, size_t *print_buf_size, size_t *bin_buf_size);
extern census_tag_set_encode_type census_tag_set_encode_import;
#define census_tag_set_encode census_tag_set_encode_import
typedef census_tag_set *(*census_tag_set_decode_type)(const char *buffer, size_t size, const char *bin_buffer, size_t bin_size);
extern census_tag_set_decode_type census_tag_set_decode_import;
#define census_tag_set_decode census_tag_set_decode_import
typedef census_tag_set *(*census_context_tag_set_type)(census_context *context);
extern census_context_tag_set_type census_context_tag_set_import;
#define census_context_tag_set census_context_tag_set_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_tag_set *tags, const census_aggregation *aggregations, size_t naggregations);
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);
@ -154,7 +148,7 @@ extern census_view_metric_type 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_tag_set *(*census_view_tags_type)(const census_view *view);
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);

@ -151,15 +151,21 @@
LD = $(LD_$(CONFIG))
endif
LDXX ?= $(LDXX_$(CONFIG))
ifeq ($(SYSTEM),Linux)
ifeq ($(origin AR), default)
AR = ar
AR = ar rcs
endif
ifeq ($(SYSTEM),Linux)
STRIP ?= strip --strip-unneeded
else
ifeq ($(SYSTEM),Darwin)
ifeq ($(origin AR), default)
AR = libtool -o
endif
STRIP ?= strip -x
else
ifeq ($(origin AR), default)
AR = ar rcs
endif
STRIP ?= strip
endif
endif
@ -468,6 +474,7 @@
ifeq ($(EMBED_ZLIB),true)
ZLIB_DEP = $(LIBDIR)/$(CONFIG)/libz.a
ZLIB_MERGE_LIBS = $(LIBDIR)/$(CONFIG)/libz.a
ZLIB_MERGE_OBJS = $(LIBZ_OBJS)
CPPFLAGS += -Ithird_party/zlib
LDFLAGS += -L$(LIBDIR)/$(CONFIG)/zlib
else
@ -510,6 +517,7 @@
ifeq ($(EMBED_OPENSSL),true)
OPENSSL_DEP += $(LIBDIR)/$(CONFIG)/libboringssl.a
OPENSSL_MERGE_LIBS += $(LIBDIR)/$(CONFIG)/libboringssl.a
OPENSSL_MERGE_OBJS += $(LIBBORINGSSL_OBJS)
# need to prefix these to ensure overriding system libraries
CPPFLAGS := -Ithird_party/boringssl/include $(CPPFLAGS)
else # EMBED_OPENSSL=false
@ -1333,7 +1341,7 @@
% endfor
endif
install-pkg-config_c: pr pc_c pc_c_unsecure pc_c_zookeeper
install-pkg-config_c: pc_c pc_c_unsecure pc_c_zookeeper
$(E) "[INSTALL] Installing C pkg-config files"
$(Q) $(INSTALL) -d $(prefix)/lib/pkgconfig
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc $(prefix)/lib/pkgconfig/grpc.pc
@ -1474,38 +1482,25 @@
% if lib.language == 'c++':
$(PROTOBUF_DEP)\
% endif
$(LIB${lib.name.upper()}_OBJS)
$(LIB${lib.name.upper()}_OBJS) \
% if lib.get('baselib', False):
$(ZLIB_MERGE_OBJS) \
% if lib.get('secure', 'check') == True:
$(OPENSSL_MERGE_OBJS) \
% endif
% endif
$(E) "[AR] Creating $@"
$(Q) mkdir -p `dirname $@`
$(Q) rm -f $(LIBDIR)/$(CONFIG)/lib${lib.name}.a
$(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/lib${lib.name}.a $(LIB${lib.name.upper()}_OBJS)
$(Q) $(AR) $(LIBDIR)/$(CONFIG)/lib${lib.name}.a $(LIB${lib.name.upper()}_OBJS) \
% if lib.get('baselib', False):
$(Q) rm -rf $(BUILDDIR_ABSOLUTE)/tmp-merge-${lib.name}
$(Q) ( mkdir -p $(BUILDDIR_ABSOLUTE)/tmp-merge-${lib.name}/grpc ; <%text>\</%text>
cd $(BUILDDIR_ABSOLUTE)/tmp-merge-${lib.name}/grpc ; <%text>\</%text>
$(AR) x $(LIBDIR)/$(CONFIG)/lib${lib.name}.a )
$(Q) for l in $(ZLIB_MERGE_LIBS) ; do ( <%text>\</%text>
mkdir -p $(BUILDDIR_ABSOLUTE)/tmp-merge-${lib.name}/zlib ; <%text>\</%text>
cd $(BUILDDIR_ABSOLUTE)/tmp-merge-${lib.name}/zlib ; <%text>\</%text>
<%text>$(AR) x $${l}</%text> ) ; done
$(Q) for l in $(ZLIB_MERGE_LIBS) ; do ( <%text>\</%text>
mkdir -p $(BUILDDIR_ABSOLUTE)/tmp-merge-${lib.name}/zlib ; <%text>\</%text>
cd $(BUILDDIR_ABSOLUTE)/tmp-merge-${lib.name}/zlib ; <%text>\</%text>
<%text>$(AR) x $${l}</%text> ) ; done
$(ZLIB_MERGE_OBJS) \
% if lib.get('secure', 'check') == True:
$(Q) for l in $(OPENSSL_MERGE_LIBS) ; do ( <%text>\</%text>
mkdir -p $(BUILDDIR_ABSOLUTE)/tmp-merge-${lib.name}/ssl ; <%text>\</%text>
cd $(BUILDDIR_ABSOLUTE)/tmp-merge-${lib.name}/ssl ; <%text>\</%text>
<%text>$(AR) x $${l}</%text> ) ; done
$(Q) for l in $(OPENSSL_MERGE_LIBS) ; do ( <%text>\</%text>
mkdir -p $(BUILDDIR_ABSOLUTE)/tmp-merge-${lib.name}/ssl ; <%text>\</%text>
cd $(BUILDDIR_ABSOLUTE)/tmp-merge-${lib.name}/ssl ; <%text>\</%text>
<%text>$(AR) x $${l}</%text> ) ; done
% endif
$(Q) rm -f $(LIBDIR)/$(CONFIG)/lib${lib.name}.a $(BUILDDIR_ABSOLUTE)/tmp-merge-${lib.name}/*/__.SYMDEF*
$(Q) ar rcs $(LIBDIR)/$(CONFIG)/lib${lib.name}.a $(BUILDDIR_ABSOLUTE)/tmp-merge-${lib.name}/*/*
$(Q) rm -rf $(BUILDDIR_ABSOLUTE)/tmp-merge-${lib.name}
$(OPENSSL_MERGE_OBJS) \
% endif
% endif
ifeq ($(SYSTEM),Darwin)
$(Q) ranlib $(LIBDIR)/$(CONFIG)/lib${lib.name}.a
endif

@ -0,0 +1,52 @@
%YAML 1.2
--- |
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <grpc/support/port_platform.h>
#include "imports.generated.h"
#ifdef GPR_WIN32
%for api in c_apis:
${api.name}_type ${api.name}_import;
%endfor
void pygrpc_load_imports(HMODULE library) {
%for api in c_apis:
${api.name}_import = (${api.name}_type) GetProcAddress(library, "${api.name}");
%endfor
}
#endif /* !GPR_WIN32 */

@ -0,0 +1,70 @@
%YAML 1.2
--- |
/*
*
* 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 PYGRPC_CYTHON_WINDOWS_IMPORTS_H_
#define PYGRPC_CYTHON_WINDOWS_IMPORTS_H_
#include <grpc/support/port_platform.h>
#ifdef GPR_WIN32
#include <windows.h>
%for header in sorted(set(api.header for api in c_apis)):
#include <${'/'.join(header.split('/')[1:])}>
%endfor
%for api in c_apis:
typedef ${api.return_type}(*${api.name}_type)(${api.arguments});
extern ${api.name}_type ${api.name}_import;
#define ${api.name} ${api.name}_import
%endfor
void pygrpc_load_imports(HMODULE library);
#else /* !GPR_WIN32 */
#include <grpc/support/alloc.h>
#include <grpc/support/slice.h>
#include <grpc/support/time.h>
#include <grpc/status.h>
#include <grpc/byte_buffer.h>
#include <grpc/byte_buffer_reader.h>
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
#endif /* !GPR_WIN32 */
#endif

@ -31,7 +31,7 @@
*
*/
// Test census_tag_set functions, including encoding/decoding
// Test census_context functions, including encoding/decoding
#include <grpc/census.h>
#include <grpc/support/log.h>
@ -46,7 +46,7 @@ static uint8_t one_byte_val = 7;
static uint32_t four_byte_val = 0x12345678;
static uint64_t eight_byte_val = 0x1234567890abcdef;
// A set of tags Used to create a basic tag_set for testing. Each tag has a
// A set of tags Used to create a basic context for testing. Each tag has a
// unique set of flags. Note that replace_add_delete_test() relies on specific
// offsets into this array - if you add or delete entries, you will also need
// to change the test.
@ -65,7 +65,7 @@ static census_tag basic_tags[BASIC_TAG_COUNT] = {
/* 7 */ {"k7", (char *)&four_byte_val, 4,
CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS | CENSUS_TAG_BINARY}};
// Set of tags used to modify the basic tag_set. Note that
// Set of tags used to modify the basic context. Note that
// replace_add_delete_test() relies on specific offsets into this array - if
// you add or delete entries, you will also need to change the test. Other
// tests that rely on specific instances have XXX_XXX_OFFSET definitions (also
@ -99,35 +99,34 @@ static bool compare_tag(const census_tag *t1, const census_tag *t2) {
t1->flags == t2->flags);
}
// Utility function to validate a tag exists in tag set.
static bool validate_tag(const census_tag_set *cts, const census_tag *tag) {
// Utility function to validate a tag exists in context.
static bool validate_tag(const census_context *context, const census_tag *tag) {
census_tag tag2;
if (census_tag_set_get_tag_by_key(cts, tag->key, &tag2) != 1) return false;
if (census_context_get_tag(context, tag->key, &tag2) != 1) return false;
return compare_tag(tag, &tag2);
}
// Create an empty tag_set.
// Create an empty context.
static void empty_test(void) {
struct census_tag_set *cts = census_tag_set_create(NULL, NULL, 0, NULL);
GPR_ASSERT(cts != NULL);
const census_tag_set_create_status *status =
census_tag_set_get_create_status(cts);
census_tag_set_create_status expected = {0, 0, 0, 0, 0, 0, 0, 0};
struct census_context *context = census_context_create(NULL, NULL, 0, NULL);
GPR_ASSERT(context != NULL);
const census_context_status *status = census_context_get_status(context);
census_context_status expected = {0, 0, 0, 0, 0, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag_set_destroy(cts);
census_context_destroy(context);
}
// Test create and iteration over basic tag set.
// Test create and iteration over basic context.
static void basic_test(void) {
const census_tag_set_create_status *status;
struct census_tag_set *cts =
census_tag_set_create(NULL, basic_tags, BASIC_TAG_COUNT, &status);
census_tag_set_create_status expected = {2, 2, 4, 0, 8, 0, 0, 0};
const census_context_status *status;
struct census_context *context =
census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, &status);
census_context_status expected = {2, 2, 4, 0, 8, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag_set_iterator it;
census_tag_set_initialize_iterator(cts, &it);
census_context_iterator it;
census_context_initialize_iterator(context, &it);
census_tag tag;
while (census_tag_set_next_tag(&it, &tag)) {
while (census_context_next_tag(&it, &tag)) {
// can't rely on tag return order: make sure it matches exactly one.
int matches = 0;
for (int i = 0; i < BASIC_TAG_COUNT; i++) {
@ -135,29 +134,28 @@ static void basic_test(void) {
}
GPR_ASSERT(matches == 1);
}
census_tag_set_destroy(cts);
census_context_destroy(context);
}
// Test that census_tag_set_get_tag_by_key().
// Test census_context_get_tag().
static void lookup_by_key_test(void) {
struct census_tag_set *cts =
census_tag_set_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
struct census_context *context =
census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
census_tag tag;
for (int i = 0; i < BASIC_TAG_COUNT; i++) {
GPR_ASSERT(census_tag_set_get_tag_by_key(cts, basic_tags[i].key, &tag) ==
1);
GPR_ASSERT(census_context_get_tag(context, basic_tags[i].key, &tag) == 1);
GPR_ASSERT(compare_tag(&tag, &basic_tags[i]));
}
// non-existent keys
GPR_ASSERT(census_tag_set_get_tag_by_key(cts, "key", &tag) == 0);
GPR_ASSERT(census_tag_set_get_tag_by_key(cts, "key01", &tag) == 0);
GPR_ASSERT(census_tag_set_get_tag_by_key(cts, "k9", &tag) == 0);
GPR_ASSERT(census_tag_set_get_tag_by_key(cts, "random", &tag) == 0);
GPR_ASSERT(census_tag_set_get_tag_by_key(cts, "", &tag) == 0);
census_tag_set_destroy(cts);
GPR_ASSERT(census_context_get_tag(context, "key", &tag) == 0);
GPR_ASSERT(census_context_get_tag(context, "key01", &tag) == 0);
GPR_ASSERT(census_context_get_tag(context, "k9", &tag) == 0);
GPR_ASSERT(census_context_get_tag(context, "random", &tag) == 0);
GPR_ASSERT(census_context_get_tag(context, "", &tag) == 0);
census_context_destroy(context);
}
// Try creating tag set with invalid entries.
// Try creating context with invalid entries.
static void invalid_test(void) {
char key[300];
memset(key, 'k', 299);
@ -168,155 +166,156 @@ static void invalid_test(void) {
// long keys, short value. Key lengths (including terminator) should be
// <= 255 (CENSUS_MAX_TAG_KV_LEN)
GPR_ASSERT(strlen(key) == 299);
const census_tag_set_create_status *status;
struct census_tag_set *cts = census_tag_set_create(NULL, &tag, 1, &status);
census_tag_set_create_status expected = {0, 0, 0, 0, 0, 0, 1, 0};
const census_context_status *status;
struct census_context *context =
census_context_create(NULL, &tag, 1, &status);
census_context_status expected = {0, 0, 0, 0, 0, 0, 1, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag_set_destroy(cts);
census_context_destroy(context);
key[CENSUS_MAX_TAG_KV_LEN] = 0;
GPR_ASSERT(strlen(key) == CENSUS_MAX_TAG_KV_LEN);
cts = census_tag_set_create(NULL, &tag, 1, &status);
context = census_context_create(NULL, &tag, 1, &status);
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag_set_destroy(cts);
census_context_destroy(context);
key[CENSUS_MAX_TAG_KV_LEN - 1] = 0;
GPR_ASSERT(strlen(key) == CENSUS_MAX_TAG_KV_LEN - 1);
cts = census_tag_set_create(NULL, &tag, 1, &status);
census_tag_set_create_status expected2 = {0, 0, 1, 0, 1, 0, 0, 0};
context = census_context_create(NULL, &tag, 1, &status);
census_context_status expected2 = {0, 0, 1, 0, 1, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected2, sizeof(expected2)) == 0);
census_tag_set_destroy(cts);
census_context_destroy(context);
// now try with long values
tag.value_len = 300;
cts = census_tag_set_create(NULL, &tag, 1, &status);
context = census_context_create(NULL, &tag, 1, &status);
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag_set_destroy(cts);
census_context_destroy(context);
tag.value_len = CENSUS_MAX_TAG_KV_LEN + 1;
cts = census_tag_set_create(NULL, &tag, 1, &status);
context = census_context_create(NULL, &tag, 1, &status);
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag_set_destroy(cts);
census_context_destroy(context);
tag.value_len = CENSUS_MAX_TAG_KV_LEN;
cts = census_tag_set_create(NULL, &tag, 1, &status);
context = census_context_create(NULL, &tag, 1, &status);
GPR_ASSERT(memcmp(status, &expected2, sizeof(expected2)) == 0);
census_tag_set_destroy(cts);
census_context_destroy(context);
// 0 length key.
key[0] = 0;
cts = census_tag_set_create(NULL, &tag, 1, &status);
context = census_context_create(NULL, &tag, 1, &status);
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag_set_destroy(cts);
census_context_destroy(context);
}
// Make a copy of a tag set
// Make a copy of a context
static void copy_test(void) {
struct census_tag_set *cts =
census_tag_set_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_tag_set_create_status *status;
struct census_tag_set *cts2 = census_tag_set_create(cts, NULL, 0, &status);
census_tag_set_create_status expected = {2, 2, 4, 0, 0, 0, 0, 0};
struct census_context *context =
census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_context_status *status;
struct census_context *context2 =
census_context_create(context, NULL, 0, &status);
census_context_status expected = {2, 2, 4, 0, 0, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
for (int i = 0; i < BASIC_TAG_COUNT; i++) {
census_tag tag;
GPR_ASSERT(census_tag_set_get_tag_by_key(cts2, basic_tags[i].key, &tag) ==
1);
GPR_ASSERT(census_context_get_tag(context2, basic_tags[i].key, &tag) == 1);
GPR_ASSERT(compare_tag(&tag, &basic_tags[i]));
}
census_tag_set_destroy(cts);
census_tag_set_destroy(cts2);
census_context_destroy(context);
census_context_destroy(context2);
}
// replace a single tag value
static void replace_value_test(void) {
struct census_tag_set *cts =
census_tag_set_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_tag_set_create_status *status;
struct census_tag_set *cts2 = census_tag_set_create(
cts, modify_tags + REPLACE_VALUE_OFFSET, 1, &status);
census_tag_set_create_status expected = {2, 2, 4, 0, 0, 1, 0, 0};
struct census_context *context =
census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_context_status *status;
struct census_context *context2 = census_context_create(
context, modify_tags + REPLACE_VALUE_OFFSET, 1, &status);
census_context_status expected = {2, 2, 4, 0, 0, 1, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag tag;
GPR_ASSERT(census_tag_set_get_tag_by_key(
cts2, modify_tags[REPLACE_VALUE_OFFSET].key, &tag) == 1);
GPR_ASSERT(census_context_get_tag(
context2, modify_tags[REPLACE_VALUE_OFFSET].key, &tag) == 1);
GPR_ASSERT(compare_tag(&tag, &modify_tags[REPLACE_VALUE_OFFSET]));
census_tag_set_destroy(cts);
census_tag_set_destroy(cts2);
census_context_destroy(context);
census_context_destroy(context2);
}
// replace a single tags flags
static void replace_flags_test(void) {
struct census_tag_set *cts =
census_tag_set_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_tag_set_create_status *status;
struct census_tag_set *cts2 =
census_tag_set_create(cts, modify_tags + REPLACE_FLAG_OFFSET, 1, &status);
census_tag_set_create_status expected = {1, 2, 5, 0, 0, 1, 0, 0};
struct census_context *context =
census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_context_status *status;
struct census_context *context2 = census_context_create(
context, modify_tags + REPLACE_FLAG_OFFSET, 1, &status);
census_context_status expected = {1, 2, 5, 0, 0, 1, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag tag;
GPR_ASSERT(census_tag_set_get_tag_by_key(
cts2, modify_tags[REPLACE_FLAG_OFFSET].key, &tag) == 1);
GPR_ASSERT(census_context_get_tag(
context2, modify_tags[REPLACE_FLAG_OFFSET].key, &tag) == 1);
GPR_ASSERT(compare_tag(&tag, &modify_tags[REPLACE_FLAG_OFFSET]));
census_tag_set_destroy(cts);
census_tag_set_destroy(cts2);
census_context_destroy(context);
census_context_destroy(context2);
}
// delete a single tag.
static void delete_tag_test(void) {
struct census_tag_set *cts =
census_tag_set_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_tag_set_create_status *status;
struct census_tag_set *cts2 =
census_tag_set_create(cts, modify_tags + DELETE_TAG_OFFSET, 1, &status);
census_tag_set_create_status expected = {2, 1, 4, 1, 0, 0, 0, 0};
struct census_context *context =
census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_context_status *status;
struct census_context *context2 = census_context_create(
context, modify_tags + DELETE_TAG_OFFSET, 1, &status);
census_context_status expected = {2, 1, 4, 1, 0, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag tag;
GPR_ASSERT(census_tag_set_get_tag_by_key(
cts2, modify_tags[DELETE_TAG_OFFSET].key, &tag) == 0);
census_tag_set_destroy(cts);
census_tag_set_destroy(cts2);
GPR_ASSERT(census_context_get_tag(
context2, modify_tags[DELETE_TAG_OFFSET].key, &tag) == 0);
census_context_destroy(context);
census_context_destroy(context2);
}
// add a single new tag.
static void add_tag_test(void) {
struct census_tag_set *cts =
census_tag_set_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_tag_set_create_status *status;
struct census_tag_set *cts2 =
census_tag_set_create(cts, modify_tags + ADD_TAG_OFFSET, 1, &status);
census_tag_set_create_status expected = {2, 2, 5, 0, 1, 0, 0, 0};
struct census_context *context =
census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_context_status *status;
struct census_context *context2 =
census_context_create(context, modify_tags + ADD_TAG_OFFSET, 1, &status);
census_context_status expected = {2, 2, 5, 0, 1, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag tag;
GPR_ASSERT(census_tag_set_get_tag_by_key(
cts2, modify_tags[ADD_TAG_OFFSET].key, &tag) == 1);
GPR_ASSERT(census_context_get_tag(context2, modify_tags[ADD_TAG_OFFSET].key,
&tag) == 1);
GPR_ASSERT(compare_tag(&tag, &modify_tags[ADD_TAG_OFFSET]));
census_tag_set_destroy(cts);
census_tag_set_destroy(cts2);
census_context_destroy(context);
census_context_destroy(context2);
}
// test many changes at once.
static void replace_add_delete_test(void) {
struct census_tag_set *cts =
census_tag_set_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_tag_set_create_status *status;
struct census_tag_set *cts2 =
census_tag_set_create(cts, modify_tags, MODIFY_TAG_COUNT, &status);
census_tag_set_create_status expected = {2, 1, 6, 2, 3, 4, 0, 2};
struct census_context *context =
census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_context_status *status;
struct census_context *context2 =
census_context_create(context, modify_tags, MODIFY_TAG_COUNT, &status);
census_context_status expected = {2, 1, 6, 2, 3, 4, 0, 2};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
// validate tag set contents. Use specific indices into the two arrays
// validate context contents. Use specific indices into the two arrays
// holding tag values.
GPR_ASSERT(validate_tag(cts2, &basic_tags[3]));
GPR_ASSERT(validate_tag(cts2, &basic_tags[4]));
GPR_ASSERT(validate_tag(cts2, &modify_tags[0]));
GPR_ASSERT(validate_tag(cts2, &modify_tags[1]));
GPR_ASSERT(validate_tag(cts2, &modify_tags[6]));
GPR_ASSERT(validate_tag(cts2, &modify_tags[7]));
GPR_ASSERT(validate_tag(cts2, &modify_tags[8]));
GPR_ASSERT(validate_tag(cts2, &modify_tags[9]));
GPR_ASSERT(validate_tag(cts2, &modify_tags[10]));
GPR_ASSERT(!validate_tag(cts2, &basic_tags[0]));
GPR_ASSERT(!validate_tag(cts2, &basic_tags[1]));
GPR_ASSERT(!validate_tag(cts2, &basic_tags[2]));
GPR_ASSERT(!validate_tag(cts2, &basic_tags[5]));
GPR_ASSERT(!validate_tag(cts2, &basic_tags[6]));
GPR_ASSERT(!validate_tag(cts2, &basic_tags[7]));
census_tag_set_destroy(cts);
census_tag_set_destroy(cts2);
GPR_ASSERT(validate_tag(context2, &basic_tags[3]));
GPR_ASSERT(validate_tag(context2, &basic_tags[4]));
GPR_ASSERT(validate_tag(context2, &modify_tags[0]));
GPR_ASSERT(validate_tag(context2, &modify_tags[1]));
GPR_ASSERT(validate_tag(context2, &modify_tags[6]));
GPR_ASSERT(validate_tag(context2, &modify_tags[7]));
GPR_ASSERT(validate_tag(context2, &modify_tags[8]));
GPR_ASSERT(validate_tag(context2, &modify_tags[9]));
GPR_ASSERT(validate_tag(context2, &modify_tags[10]));
GPR_ASSERT(!validate_tag(context2, &basic_tags[0]));
GPR_ASSERT(!validate_tag(context2, &basic_tags[1]));
GPR_ASSERT(!validate_tag(context2, &basic_tags[2]));
GPR_ASSERT(!validate_tag(context2, &basic_tags[5]));
GPR_ASSERT(!validate_tag(context2, &basic_tags[6]));
GPR_ASSERT(!validate_tag(context2, &basic_tags[7]));
census_context_destroy(context);
census_context_destroy(context2);
}
#define BUF_SIZE 200
@ -324,38 +323,37 @@ static void replace_add_delete_test(void) {
// test encode/decode.
static void encode_decode_test(void) {
char buffer[BUF_SIZE];
struct census_tag_set *cts =
census_tag_set_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
struct census_context *context =
census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
size_t print_bsize;
size_t bin_bsize;
// Test with too small a buffer
GPR_ASSERT(census_tag_set_encode(cts, buffer, 2, &print_bsize, &bin_bsize) ==
NULL);
char *b_buffer =
census_tag_set_encode(cts, buffer, BUF_SIZE, &print_bsize, &bin_bsize);
GPR_ASSERT(census_context_encode(context, buffer, 2, &print_bsize,
&bin_bsize) == NULL);
char *b_buffer = census_context_encode(context, buffer, BUF_SIZE,
&print_bsize, &bin_bsize);
GPR_ASSERT(b_buffer != NULL && print_bsize > 0 && bin_bsize > 0 &&
print_bsize + bin_bsize <= BUF_SIZE &&
b_buffer == buffer + print_bsize);
census_tag_set *cts2 =
census_tag_set_decode(buffer, print_bsize, b_buffer, bin_bsize);
GPR_ASSERT(cts2 != NULL);
const census_tag_set_create_status *status =
census_tag_set_get_create_status(cts2);
census_tag_set_create_status expected = {2, 2, 0, 0, 0, 0, 0, 0};
census_context *context2 =
census_context_decode(buffer, print_bsize, b_buffer, bin_bsize);
GPR_ASSERT(context2 != NULL);
const census_context_status *status = census_context_get_status(context2);
census_context_status expected = {2, 2, 0, 0, 0, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
for (int i = 0; i < BASIC_TAG_COUNT; i++) {
census_tag tag;
if (CENSUS_TAG_IS_PROPAGATED(basic_tags[i].flags)) {
GPR_ASSERT(census_tag_set_get_tag_by_key(cts2, basic_tags[i].key, &tag) ==
GPR_ASSERT(census_context_get_tag(context2, basic_tags[i].key, &tag) ==
1);
GPR_ASSERT(compare_tag(&tag, &basic_tags[i]));
} else {
GPR_ASSERT(census_tag_set_get_tag_by_key(cts2, basic_tags[i].key, &tag) ==
GPR_ASSERT(census_context_get_tag(context2, basic_tags[i].key, &tag) ==
0);
}
}
census_tag_set_destroy(cts2);
census_tag_set_destroy(cts);
census_context_destroy(context2);
census_context_destroy(context);
}
int main(int argc, char *argv[]) {

@ -32,6 +32,7 @@
*/
#include <memory>
#include <thread>
#include <grpc++/channel.h>
#include <grpc++/client_context.h>
@ -104,7 +105,10 @@ class Verifier : public PollingCheckRegion {
expectations_[tag(i)] = expect_ok;
return *this;
}
void Verify(CompletionQueue* cq) {
void Verify(CompletionQueue* cq) { Verify(cq, false); }
void Verify(CompletionQueue* cq, bool ignore_ok) {
GPR_ASSERT(!expectations_.empty());
while (!expectations_.empty()) {
bool ok;
@ -122,7 +126,9 @@ class Verifier : public PollingCheckRegion {
}
auto it = expectations_.find(got_tag);
EXPECT_TRUE(it != expectations_.end());
EXPECT_EQ(it->second, ok);
if (!ignore_ok) {
EXPECT_EQ(it->second, ok);
}
expectations_.erase(it);
}
}
@ -217,7 +223,7 @@ class AsyncEnd2endTest : public ::testing::TestWithParam<bool> {
grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
send_request.set_message("Hello");
std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader(
stub_->AsyncEcho(&cli_ctx, send_request, cq_.get()));
service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(),
@ -270,7 +276,7 @@ TEST_P(AsyncEnd2endTest, AsyncNextRpc) {
grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
send_request.set_message("Hello");
std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader(
stub_->AsyncEcho(&cli_ctx, send_request, cq_.get()));
std::chrono::system_clock::time_point time_now(
@ -315,7 +321,7 @@ TEST_P(AsyncEnd2endTest, SimpleClientStreaming) {
ServerAsyncReader<EchoResponse, EchoRequest> srv_stream(&srv_ctx);
send_request.set_message("Hello");
std::unique_ptr<ClientAsyncWriter<EchoRequest> > cli_stream(
std::unique_ptr<ClientAsyncWriter<EchoRequest>> cli_stream(
stub_->AsyncRequestStream(&cli_ctx, &recv_response, cq_.get(), tag(1)));
service_.RequestRequestStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(),
@ -368,7 +374,7 @@ TEST_P(AsyncEnd2endTest, SimpleServerStreaming) {
ServerAsyncWriter<EchoResponse> srv_stream(&srv_ctx);
send_request.set_message("Hello");
std::unique_ptr<ClientAsyncReader<EchoResponse> > cli_stream(
std::unique_ptr<ClientAsyncReader<EchoResponse>> cli_stream(
stub_->AsyncResponseStream(&cli_ctx, send_request, cq_.get(), tag(1)));
service_.RequestResponseStream(&srv_ctx, &recv_request, &srv_stream,
@ -418,7 +424,7 @@ TEST_P(AsyncEnd2endTest, SimpleBidiStreaming) {
ServerAsyncReaderWriter<EchoResponse, EchoRequest> srv_stream(&srv_ctx);
send_request.set_message("Hello");
std::unique_ptr<ClientAsyncReaderWriter<EchoRequest, EchoResponse> >
std::unique_ptr<ClientAsyncReaderWriter<EchoRequest, EchoResponse>>
cli_stream(stub_->AsyncBidiStream(&cli_ctx, cq_.get(), tag(1)));
service_.RequestBidiStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(),
@ -476,7 +482,7 @@ TEST_P(AsyncEnd2endTest, ClientInitialMetadataRpc) {
cli_ctx.AddMetadata(meta1.first, meta1.second);
cli_ctx.AddMetadata(meta2.first, meta2.second);
std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader(
stub_->AsyncEcho(&cli_ctx, send_request, cq_.get()));
service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(),
@ -519,7 +525,7 @@ TEST_P(AsyncEnd2endTest, ServerInitialMetadataRpc) {
std::pair<grpc::string, grpc::string> meta1("key1", "val1");
std::pair<grpc::string, grpc::string> meta2("key2", "val2");
std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader(
stub_->AsyncEcho(&cli_ctx, send_request, cq_.get()));
service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(),
@ -568,7 +574,7 @@ TEST_P(AsyncEnd2endTest, ServerTrailingMetadataRpc) {
std::pair<grpc::string, grpc::string> meta1("key1", "val1");
std::pair<grpc::string, grpc::string> meta2("key2", "val2");
std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader(
stub_->AsyncEcho(&cli_ctx, send_request, cq_.get()));
service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(),
@ -629,7 +635,7 @@ TEST_P(AsyncEnd2endTest, MetadataRpc) {
cli_ctx.AddMetadata(meta1.first, meta1.second);
cli_ctx.AddMetadata(meta2.first, meta2.second);
std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader(
stub_->AsyncEcho(&cli_ctx, send_request, cq_.get()));
service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(),
@ -690,7 +696,7 @@ TEST_P(AsyncEnd2endTest, ServerCheckCancellation) {
grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
send_request.set_message("Hello");
std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader(
stub_->AsyncEcho(&cli_ctx, send_request, cq_.get()));
srv_ctx.AsyncNotifyWhenDone(tag(5));
@ -725,7 +731,7 @@ TEST_P(AsyncEnd2endTest, ServerCheckDone) {
grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
send_request.set_message("Hello");
std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader(
stub_->AsyncEcho(&cli_ctx, send_request, cq_.get()));
srv_ctx.AsyncNotifyWhenDone(tag(5));
@ -759,7 +765,7 @@ TEST_P(AsyncEnd2endTest, UnimplementedRpc) {
ClientContext cli_ctx;
send_request.set_message("Hello");
std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader(
stub->AsyncUnimplemented(&cli_ctx, send_request, cq_.get()));
response_reader->Finish(&recv_response, &recv_status, tag(4));
@ -769,8 +775,384 @@ TEST_P(AsyncEnd2endTest, UnimplementedRpc) {
EXPECT_EQ("", recv_status.error_message());
}
// This class is for testing scenarios where RPCs are cancelled on the server
// by calling ServerContext::TryCancel()
class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest {
protected:
typedef enum {
DO_NOT_CANCEL = 0,
CANCEL_BEFORE_PROCESSING,
CANCEL_DURING_PROCESSING,
CANCEL_AFTER_PROCESSING
} ServerTryCancelRequestPhase;
void ServerTryCancel(ServerContext* context) {
EXPECT_FALSE(context->IsCancelled());
context->TryCancel();
gpr_log(GPR_INFO, "Server called TryCancel()");
EXPECT_TRUE(context->IsCancelled());
}
// Helper for testing client-streaming RPCs which are cancelled on the server.
// Depending on the value of server_try_cancel parameter, this will test one
// of the following three scenarios:
// CANCEL_BEFORE_PROCESSING: Rpc is cancelled by the server before reading
// any messages from the client
//
// CANCEL_DURING_PROCESSING: Rpc is cancelled by the server while reading
// messages from the client
//
// CANCEL_AFTER PROCESSING: Rpc is cancelled by server after reading all
// messages from the client (but before sending any status back to the
// client)
void TestClientStreamingServerCancel(
ServerTryCancelRequestPhase server_try_cancel) {
ResetStub();
EchoRequest send_request;
EchoRequest recv_request;
EchoResponse send_response;
EchoResponse recv_response;
Status recv_status;
ClientContext cli_ctx;
ServerContext srv_ctx;
ServerAsyncReader<EchoResponse, EchoRequest> srv_stream(&srv_ctx);
// Initiate the 'RequestStream' call on client
std::unique_ptr<ClientAsyncWriter<EchoRequest>> cli_stream(
stub_->AsyncRequestStream(&cli_ctx, &recv_response, cq_.get(), tag(1)));
Verifier(GetParam()).Expect(1, true).Verify(cq_.get());
// On the server, request to be notified of 'RequestStream' calls
// and receive the 'RequestStream' call just made by the client
service_.RequestRequestStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(),
tag(2));
Verifier(GetParam()).Expect(2, true).Verify(cq_.get());
// Client sends 3 messages (tags 3, 4 and 5)
for (int tag_idx = 3; tag_idx <= 5; tag_idx++) {
send_request.set_message("Ping " + std::to_string(tag_idx));
cli_stream->Write(send_request, tag(tag_idx));
Verifier(GetParam()).Expect(tag_idx, true).Verify(cq_.get());
}
cli_stream->WritesDone(tag(6));
Verifier(GetParam()).Expect(6, true).Verify(cq_.get());
bool expected_server_cq_result = true;
bool ignore_cq_result = false;
if (server_try_cancel == CANCEL_BEFORE_PROCESSING) {
ServerTryCancel(&srv_ctx);
// Since cancellation is done before server reads any results, we know
// for sure that all cq results will return false from this point forward
expected_server_cq_result = false;
}
std::thread* server_try_cancel_thd = NULL;
if (server_try_cancel == CANCEL_DURING_PROCESSING) {
server_try_cancel_thd = new std::thread(
&AsyncEnd2endServerTryCancelTest::ServerTryCancel, this, &srv_ctx);
// Server will cancel the RPC in a parallel thread while reading the
// requests from the client. Since the cancellation can happen at anytime,
// some of the cq results (i.e those until cancellation) might be true but
// its non deterministic. So better to ignore the cq results
ignore_cq_result = true;
}
// Server reads 3 messages (tags 6, 7 and 8)
for (int tag_idx = 6; tag_idx <= 8; tag_idx++) {
srv_stream.Read(&recv_request, tag(tag_idx));
Verifier(GetParam())
.Expect(tag_idx, expected_server_cq_result)
.Verify(cq_.get(), ignore_cq_result);
}
if (server_try_cancel_thd != NULL) {
server_try_cancel_thd->join();
delete server_try_cancel_thd;
}
if (server_try_cancel == CANCEL_AFTER_PROCESSING) {
ServerTryCancel(&srv_ctx);
}
// The RPC has been cancelled at this point for sure (i.e irrespective of
// the value of `server_try_cancel` is). So, from this point forward, we
// know that cq results are supposed to return false on server.
// Server sends the final message and cancelled status (but the RPC is
// already cancelled at this point. So we expect the operation to fail)
srv_stream.Finish(send_response, Status::CANCELLED, tag(9));
Verifier(GetParam()).Expect(9, false).Verify(cq_.get());
// Client will see the cancellation
cli_stream->Finish(&recv_status, tag(10));
// TODO(sreek): The expectation here should be true. This is a bug (github
// issue #4972)
Verifier(GetParam()).Expect(10, false).Verify(cq_.get());
EXPECT_FALSE(recv_status.ok());
EXPECT_EQ(::grpc::StatusCode::CANCELLED, recv_status.error_code());
}
// Helper for testing server-streaming RPCs which are cancelled on the server.
// Depending on the value of server_try_cancel parameter, this will test one
// of the following three scenarios:
// CANCEL_BEFORE_PROCESSING: Rpc is cancelled by the server before sending
// any messages to the client
//
// CANCEL_DURING_PROCESSING: Rpc is cancelled by the server while sending
// messages to the client
//
// CANCEL_AFTER PROCESSING: Rpc is cancelled by server after sending all
// messages to the client (but before sending any status back to the
// client)
void TestServerStreamingServerCancel(
ServerTryCancelRequestPhase server_try_cancel) {
ResetStub();
EchoRequest send_request;
EchoRequest recv_request;
EchoResponse send_response;
EchoResponse recv_response;
Status recv_status;
ClientContext cli_ctx;
ServerContext srv_ctx;
ServerAsyncWriter<EchoResponse> srv_stream(&srv_ctx);
send_request.set_message("Ping");
// Initiate the 'ResponseStream' call on the client
std::unique_ptr<ClientAsyncReader<EchoResponse>> cli_stream(
stub_->AsyncResponseStream(&cli_ctx, send_request, cq_.get(), tag(1)));
Verifier(GetParam()).Expect(1, true).Verify(cq_.get());
// On the server, request to be notified of 'ResponseStream' calls and
// receive the call just made by the client
service_.RequestResponseStream(&srv_ctx, &recv_request, &srv_stream,
cq_.get(), cq_.get(), tag(2));
Verifier(GetParam()).Expect(2, true).Verify(cq_.get());
EXPECT_EQ(send_request.message(), recv_request.message());
bool expected_cq_result = true;
bool ignore_cq_result = false;
if (server_try_cancel == CANCEL_BEFORE_PROCESSING) {
ServerTryCancel(&srv_ctx);
// We know for sure that all cq results will be false from this point
// since the server cancelled the RPC
expected_cq_result = false;
}
std::thread* server_try_cancel_thd = NULL;
if (server_try_cancel == CANCEL_DURING_PROCESSING) {
server_try_cancel_thd = new std::thread(
&AsyncEnd2endServerTryCancelTest::ServerTryCancel, this, &srv_ctx);
// Server will cancel the RPC in a parallel thread while writing responses
// to the client. Since the cancellation can happen at anytime, some of
// the cq results (i.e those until cancellation) might be true but it is
// non deterministic. So better to ignore the cq results
ignore_cq_result = true;
}
// Server sends three messages (tags 3, 4 and 5)
for (int tag_idx = 3; tag_idx <= 5; tag_idx++) {
send_response.set_message("Pong " + std::to_string(tag_idx));
srv_stream.Write(send_response, tag(tag_idx));
Verifier(GetParam())
.Expect(tag_idx, expected_cq_result)
.Verify(cq_.get(), ignore_cq_result);
}
if (server_try_cancel_thd != NULL) {
server_try_cancel_thd->join();
delete server_try_cancel_thd;
}
if (server_try_cancel == CANCEL_AFTER_PROCESSING) {
ServerTryCancel(&srv_ctx);
}
// Client attemts to read the three messages from the server
for (int tag_idx = 6; tag_idx <= 8; tag_idx++) {
cli_stream->Read(&recv_response, tag(tag_idx));
Verifier(GetParam())
.Expect(tag_idx, expected_cq_result)
.Verify(cq_.get(), ignore_cq_result);
}
// The RPC has been cancelled at this point for sure (i.e irrespective of
// the value of `server_try_cancel` is). So, from this point forward, we
// know that cq results are supposed to return false on server.
// Server finishes the stream (but the RPC is already cancelled)
srv_stream.Finish(Status::CANCELLED, tag(9));
Verifier(GetParam()).Expect(9, false).Verify(cq_.get());
// Client will see the cancellation
cli_stream->Finish(&recv_status, tag(10));
Verifier(GetParam()).Expect(10, true).Verify(cq_.get());
EXPECT_FALSE(recv_status.ok());
EXPECT_EQ(::grpc::StatusCode::CANCELLED, recv_status.error_code());
}
// Helper for testing bidirectinal-streaming RPCs which are cancelled on the
// server.
//
// Depending on the value of server_try_cancel parameter, this will
// test one of the following three scenarios:
// CANCEL_BEFORE_PROCESSING: Rpc is cancelled by the server before reading/
// writing any messages from/to the client
//
// CANCEL_DURING_PROCESSING: Rpc is cancelled by the server while reading
// messages from the client
//
// CANCEL_AFTER PROCESSING: Rpc is cancelled by server after reading all
// messages from the client (but before sending any status back to the
// client)
void TestBidiStreamingServerCancel(
ServerTryCancelRequestPhase server_try_cancel) {
ResetStub();
EchoRequest send_request;
EchoRequest recv_request;
EchoResponse send_response;
EchoResponse recv_response;
Status recv_status;
ClientContext cli_ctx;
ServerContext srv_ctx;
ServerAsyncReaderWriter<EchoResponse, EchoRequest> srv_stream(&srv_ctx);
// Initiate the call from the client side
std::unique_ptr<ClientAsyncReaderWriter<EchoRequest, EchoResponse>>
cli_stream(stub_->AsyncBidiStream(&cli_ctx, cq_.get(), tag(1)));
Verifier(GetParam()).Expect(1, true).Verify(cq_.get());
// On the server, request to be notified of the 'BidiStream' call and
// receive the call just made by the client
service_.RequestBidiStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(),
tag(2));
Verifier(GetParam()).Expect(2, true).Verify(cq_.get());
// Client sends the first and the only message
send_request.set_message("Ping");
cli_stream->Write(send_request, tag(3));
Verifier(GetParam()).Expect(3, true).Verify(cq_.get());
bool expected_cq_result = true;
bool ignore_cq_result = false;
if (server_try_cancel == CANCEL_BEFORE_PROCESSING) {
ServerTryCancel(&srv_ctx);
// We know for sure that all cq results will be false from this point
// since the server cancelled the RPC
expected_cq_result = false;
}
std::thread* server_try_cancel_thd = NULL;
if (server_try_cancel == CANCEL_DURING_PROCESSING) {
server_try_cancel_thd = new std::thread(
&AsyncEnd2endServerTryCancelTest::ServerTryCancel, this, &srv_ctx);
// Since server is going to cancel the RPC in a parallel thread, some of
// the cq results (i.e those until the cancellation) might be true. Since
// that number is non-deterministic, it is better to ignore the cq results
ignore_cq_result = true;
}
srv_stream.Read(&recv_request, tag(4));
Verifier(GetParam())
.Expect(4, expected_cq_result)
.Verify(cq_.get(), ignore_cq_result);
send_response.set_message("Pong");
srv_stream.Write(send_response, tag(5));
Verifier(GetParam())
.Expect(5, expected_cq_result)
.Verify(cq_.get(), ignore_cq_result);
cli_stream->Read(&recv_response, tag(6));
Verifier(GetParam())
.Expect(6, expected_cq_result)
.Verify(cq_.get(), ignore_cq_result);
// This is expected to succeed in all cases
cli_stream->WritesDone(tag(7));
Verifier(GetParam()).Expect(7, true).Verify(cq_.get());
// This is expected to fail in all cases i.e for all values of
// server_try_cancel. This is becasue at this point, either there are no
// more msgs from the client (because client called WritesDone) or the RPC
// is cancelled on the server
srv_stream.Read(&recv_request, tag(8));
Verifier(GetParam()).Expect(8, false).Verify(cq_.get());
if (server_try_cancel_thd != NULL) {
server_try_cancel_thd->join();
delete server_try_cancel_thd;
}
if (server_try_cancel == CANCEL_AFTER_PROCESSING) {
ServerTryCancel(&srv_ctx);
}
// The RPC has been cancelled at this point for sure (i.e irrespective of
// the value of `server_try_cancel` is). So, from this point forward, we
// know that cq results are supposed to return false on server.
srv_stream.Finish(Status::CANCELLED, tag(9));
Verifier(GetParam()).Expect(9, false).Verify(cq_.get());
cli_stream->Finish(&recv_status, tag(10));
Verifier(GetParam()).Expect(10, true).Verify(cq_.get());
EXPECT_FALSE(recv_status.ok());
EXPECT_EQ(grpc::StatusCode::CANCELLED, recv_status.error_code());
}
};
TEST_P(AsyncEnd2endServerTryCancelTest, ClientStreamingServerTryCancelBefore) {
TestClientStreamingServerCancel(CANCEL_BEFORE_PROCESSING);
}
TEST_P(AsyncEnd2endServerTryCancelTest, ClientStreamingServerTryCancelDuring) {
TestClientStreamingServerCancel(CANCEL_DURING_PROCESSING);
}
TEST_P(AsyncEnd2endServerTryCancelTest, ClientStreamingServerTryCancelAfter) {
TestClientStreamingServerCancel(CANCEL_AFTER_PROCESSING);
}
TEST_P(AsyncEnd2endServerTryCancelTest, ServerStreamingServerTryCancelBefore) {
TestServerStreamingServerCancel(CANCEL_BEFORE_PROCESSING);
}
TEST_P(AsyncEnd2endServerTryCancelTest, ServerStreamingServerTryCancelDuring) {
TestServerStreamingServerCancel(CANCEL_DURING_PROCESSING);
}
TEST_P(AsyncEnd2endServerTryCancelTest, ServerStreamingServerTryCancelAfter) {
TestServerStreamingServerCancel(CANCEL_AFTER_PROCESSING);
}
TEST_P(AsyncEnd2endServerTryCancelTest, ServerBidiStreamingTryCancelBefore) {
TestBidiStreamingServerCancel(CANCEL_BEFORE_PROCESSING);
}
TEST_P(AsyncEnd2endServerTryCancelTest, ServerBidiStreamingTryCancelDuring) {
TestBidiStreamingServerCancel(CANCEL_DURING_PROCESSING);
}
TEST_P(AsyncEnd2endServerTryCancelTest, ServerBidiStreamingTryCancelAfter) {
TestBidiStreamingServerCancel(CANCEL_AFTER_PROCESSING);
}
INSTANTIATE_TEST_CASE_P(AsyncEnd2end, AsyncEnd2endTest,
::testing::Values(false, true));
INSTANTIATE_TEST_CASE_P(AsyncEnd2endServerTryCancel,
AsyncEnd2endServerTryCancelTest,
::testing::Values(false));
} // namespace
} // namespace testing

@ -306,6 +306,301 @@ static void SendRpc(grpc::testing::EchoTestService::Stub* stub, int num_rpcs,
}
}
// This class is for testing scenarios where RPCs are cancelled on the server
// by calling ServerContext::TryCancel()
class End2endServerTryCancelTest : public End2endTest {
protected:
// Helper for testing client-streaming RPCs which are cancelled on the server.
// Depending on the value of server_try_cancel parameter, this will test one
// of the following three scenarios:
// CANCEL_BEFORE_PROCESSING: Rpc is cancelled by the server before reading
// any messages from the client
//
// CANCEL_DURING_PROCESSING: Rpc is cancelled by the server while reading
// messages from the client
//
// CANCEL_AFTER PROCESSING: Rpc is cancelled by server after reading all
// the messages from the client
//
// NOTE: Do not call this function with server_try_cancel == DO_NOT_CANCEL.
void TestRequestStreamServerCancel(
ServerTryCancelRequestPhase server_try_cancel, int num_msgs_to_send) {
ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
// Send server_try_cancel value in the client metadata
context.AddMetadata(kServerTryCancelRequest,
std::to_string(server_try_cancel));
auto stream = stub_->RequestStream(&context, &response);
int num_msgs_sent = 0;
while (num_msgs_sent < num_msgs_to_send) {
request.set_message("hello");
if (!stream->Write(request)) {
break;
}
num_msgs_sent++;
}
gpr_log(GPR_INFO, "Sent %d messages", num_msgs_sent);
stream->WritesDone();
Status s = stream->Finish();
// At this point, we know for sure that RPC was cancelled by the server
// since we passed server_try_cancel value in the metadata. Depending on the
// value of server_try_cancel, the RPC might have been cancelled by the
// server at different stages. The following validates our expectations of
// number of messages sent in various cancellation scenarios:
switch (server_try_cancel) {
case CANCEL_BEFORE_PROCESSING:
case CANCEL_DURING_PROCESSING:
// If the RPC is cancelled by server before / during messages from the
// client, it means that the client most likely did not get a chance to
// send all the messages it wanted to send. i.e num_msgs_sent <=
// num_msgs_to_send
EXPECT_LE(num_msgs_sent, num_msgs_to_send);
break;
case CANCEL_AFTER_PROCESSING:
// If the RPC was cancelled after all messages were read by the server,
// the client did get a chance to send all its messages
EXPECT_EQ(num_msgs_sent, num_msgs_to_send);
break;
default:
gpr_log(GPR_ERROR, "Invalid server_try_cancel value: %d",
server_try_cancel);
EXPECT_TRUE(server_try_cancel > DO_NOT_CANCEL &&
server_try_cancel <= CANCEL_AFTER_PROCESSING);
break;
}
EXPECT_FALSE(s.ok());
EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
}
// Helper for testing server-streaming RPCs which are cancelled on the server.
// Depending on the value of server_try_cancel parameter, this will test one
// of the following three scenarios:
// CANCEL_BEFORE_PROCESSING: Rpc is cancelled by the server before writing
// any messages to the client
//
// CANCEL_DURING_PROCESSING: Rpc is cancelled by the server while writing
// messages to the client
//
// CANCEL_AFTER PROCESSING: Rpc is cancelled by server after writing all
// the messages to the client
//
// NOTE: Do not call this function with server_try_cancel == DO_NOT_CANCEL.
void TestResponseStreamServerCancel(
ServerTryCancelRequestPhase server_try_cancel) {
ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
// Send server_try_cancel in the client metadata
context.AddMetadata(kServerTryCancelRequest,
std::to_string(server_try_cancel));
request.set_message("hello");
auto stream = stub_->ResponseStream(&context, request);
int num_msgs_read = 0;
while (num_msgs_read < kNumResponseStreamsMsgs) {
if (!stream->Read(&response)) {
break;
}
EXPECT_EQ(response.message(),
request.message() + std::to_string(num_msgs_read));
num_msgs_read++;
}
gpr_log(GPR_INFO, "Read %d messages", num_msgs_read);
Status s = stream->Finish();
// Depending on the value of server_try_cancel, the RPC might have been
// cancelled by the server at different stages. The following validates our
// expectations of number of messages read in various cancellation
// scenarios:
switch (server_try_cancel) {
case CANCEL_BEFORE_PROCESSING:
// Server cancelled before sending any messages. Which means the client
// wouldn't have read any
EXPECT_EQ(num_msgs_read, 0);
break;
case CANCEL_DURING_PROCESSING:
// Server cancelled while writing messages. Client must have read less
// than or equal to the expected number of messages
EXPECT_LE(num_msgs_read, kNumResponseStreamsMsgs);
break;
case CANCEL_AFTER_PROCESSING:
// Server cancelled after writing all messages. Client must have read
// all messages
EXPECT_EQ(num_msgs_read, kNumResponseStreamsMsgs);
break;
default: {
gpr_log(GPR_ERROR, "Invalid server_try_cancel value: %d",
server_try_cancel);
EXPECT_TRUE(server_try_cancel > DO_NOT_CANCEL &&
server_try_cancel <= CANCEL_AFTER_PROCESSING);
break;
}
}
EXPECT_FALSE(s.ok());
EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
}
// Helper for testing bidirectional-streaming RPCs which are cancelled on the
// server. Depending on the value of server_try_cancel parameter, this will
// test one of the following three scenarios:
// CANCEL_BEFORE_PROCESSING: Rpc is cancelled by the server before reading/
// writing any messages from/to the client
//
// CANCEL_DURING_PROCESSING: Rpc is cancelled by the server while reading/
// writing messages from/to the client
//
// CANCEL_AFTER PROCESSING: Rpc is cancelled by server after reading/writing
// all the messages from/to the client
//
// NOTE: Do not call this function with server_try_cancel == DO_NOT_CANCEL.
void TestBidiStreamServerCancel(ServerTryCancelRequestPhase server_try_cancel,
int num_messages) {
ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
// Send server_try_cancel in the client metadata
context.AddMetadata(kServerTryCancelRequest,
std::to_string(server_try_cancel));
auto stream = stub_->BidiStream(&context);
int num_msgs_read = 0;
int num_msgs_sent = 0;
while (num_msgs_sent < num_messages) {
request.set_message("hello " + std::to_string(num_msgs_sent));
if (!stream->Write(request)) {
break;
}
num_msgs_sent++;
if (!stream->Read(&response)) {
break;
}
num_msgs_read++;
EXPECT_EQ(response.message(), request.message());
}
gpr_log(GPR_INFO, "Sent %d messages", num_msgs_sent);
gpr_log(GPR_INFO, "Read %d messages", num_msgs_read);
stream->WritesDone();
Status s = stream->Finish();
// Depending on the value of server_try_cancel, the RPC might have been
// cancelled by the server at different stages. The following validates our
// expectations of number of messages read in various cancellation
// scenarios:
switch (server_try_cancel) {
case CANCEL_BEFORE_PROCESSING:
EXPECT_EQ(num_msgs_read, 0);
break;
case CANCEL_DURING_PROCESSING:
EXPECT_LE(num_msgs_sent, num_messages);
EXPECT_LE(num_msgs_read, num_msgs_sent);
break;
case CANCEL_AFTER_PROCESSING:
EXPECT_EQ(num_msgs_sent, num_messages);
EXPECT_EQ(num_msgs_read, num_msgs_sent);
break;
default:
gpr_log(GPR_ERROR, "Invalid server_try_cancel value: %d",
server_try_cancel);
EXPECT_TRUE(server_try_cancel > DO_NOT_CANCEL &&
server_try_cancel <= CANCEL_AFTER_PROCESSING);
break;
}
EXPECT_FALSE(s.ok());
EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
}
};
TEST_P(End2endServerTryCancelTest, RequestEchoServerCancel) {
ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
context.AddMetadata(kServerTryCancelRequest,
std::to_string(CANCEL_BEFORE_PROCESSING));
Status s = stub_->Echo(&context, request, &response);
EXPECT_FALSE(s.ok());
EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
}
// Server to cancel before doing reading the request
TEST_P(End2endServerTryCancelTest, RequestStreamServerCancelBeforeReads) {
TestRequestStreamServerCancel(CANCEL_BEFORE_PROCESSING, 1);
}
// Server to cancel while reading a request from the stream in parallel
TEST_P(End2endServerTryCancelTest, RequestStreamServerCancelDuringRead) {
TestRequestStreamServerCancel(CANCEL_DURING_PROCESSING, 10);
}
// Server to cancel after reading all the requests but before returning to the
// client
TEST_P(End2endServerTryCancelTest, RequestStreamServerCancelAfterReads) {
TestRequestStreamServerCancel(CANCEL_AFTER_PROCESSING, 4);
}
// Server to cancel before sending any response messages
TEST_P(End2endServerTryCancelTest, ResponseStreamServerCancelBefore) {
TestResponseStreamServerCancel(CANCEL_BEFORE_PROCESSING);
}
// Server to cancel while writing a response to the stream in parallel
TEST_P(End2endServerTryCancelTest, ResponseStreamServerCancelDuring) {
TestResponseStreamServerCancel(CANCEL_DURING_PROCESSING);
}
// Server to cancel after writing all the respones to the stream but before
// returning to the client
TEST_P(End2endServerTryCancelTest, ResponseStreamServerCancelAfter) {
TestResponseStreamServerCancel(CANCEL_AFTER_PROCESSING);
}
// Server to cancel before reading/writing any requests/responses on the stream
TEST_P(End2endServerTryCancelTest, BidiStreamServerCancelBefore) {
TestBidiStreamServerCancel(CANCEL_BEFORE_PROCESSING, 2);
}
// Server to cancel while reading/writing requests/responses on the stream in
// parallel
TEST_P(End2endServerTryCancelTest, BidiStreamServerCancelDuring) {
TestBidiStreamServerCancel(CANCEL_DURING_PROCESSING, 10);
}
// Server to cancel after reading/writing all requests/responses on the stream
// but before returning to the client
TEST_P(End2endServerTryCancelTest, BidiStreamServerCancelAfter) {
TestBidiStreamServerCancel(CANCEL_AFTER_PROCESSING, 5);
}
TEST_P(End2endTest, MultipleRpcsWithVariedBinaryMetadataValue) {
ResetStub();
std::vector<std::thread*> threads;
@ -1059,6 +1354,9 @@ INSTANTIATE_TEST_CASE_P(End2end, End2endTest,
::testing::Values(TestScenario(false, false),
TestScenario(false, true)));
INSTANTIATE_TEST_CASE_P(End2endServerTryCancel, End2endServerTryCancelTest,
::testing::Values(TestScenario(false, false)));
INSTANTIATE_TEST_CASE_P(ProxyEnd2end, ProxyEnd2endTest,
::testing::Values(TestScenario(false, false),
TestScenario(false, true),

@ -33,6 +33,8 @@
#include "test/cpp/end2end/test_service_impl.h"
#include <thread>
#include <grpc++/security/credentials.h>
#include <grpc++/server_context.h>
#include <grpc/grpc.h>
@ -82,6 +84,17 @@ void CheckServerAuthContext(const ServerContext* context,
Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request,
EchoResponse* response) {
int server_try_cancel = GetIntValueFromMetadata(
kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL);
if (server_try_cancel > DO_NOT_CANCEL) {
// Since this is a unary RPC, by the time this server handler is called,
// the 'request' message is already read from the client. So the scenarios
// in server_try_cancel don't make much sense. Just cancel the RPC as long
// as server_try_cancel is not DO_NOT_CANCEL
ServerTryCancel(context);
return Status::CANCELLED;
}
response->set_message(request->message());
MaybeEchoDeadline(context, request, response);
if (host_) {
@ -143,18 +156,39 @@ Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request,
Status TestServiceImpl::RequestStream(ServerContext* context,
ServerReader<EchoRequest>* reader,
EchoResponse* response) {
// If 'server_try_cancel' is set in the metadata, the RPC is cancelled by
// the server by calling ServerContext::TryCancel() depending on the value:
// CANCEL_BEFORE_PROCESSING: The RPC is cancelled before the server reads
// any message from the client
// CANCEL_DURING_PROCESSING: The RPC is cancelled while the server is
// reading messages from the client
// CANCEL_AFTER_PROCESSING: The RPC is cancelled after the server reads
// all the messages from the client
int server_try_cancel = GetIntValueFromMetadata(
kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL);
// If 'cancel_after_reads' is set in the metadata AND non-zero, the server
// will cancel the RPC (by just returning Status::CANCELLED - doesn't call
// ServerContext::TryCancel()) after reading the number of records specified
// by the 'cancel_after_reads' value set in the metadata.
int cancel_after_reads = GetIntValueFromMetadata(
kServerCancelAfterReads, context->client_metadata(), 0);
EchoRequest request;
response->set_message("");
int cancel_after_reads = 0;
const std::multimap<grpc::string_ref, grpc::string_ref>&
client_initial_metadata = context->client_metadata();
if (client_initial_metadata.find(kServerCancelAfterReads) !=
client_initial_metadata.end()) {
std::istringstream iss(ToString(
client_initial_metadata.find(kServerCancelAfterReads)->second));
iss >> cancel_after_reads;
gpr_log(GPR_INFO, "cancel_after_reads %d", cancel_after_reads);
if (server_try_cancel == CANCEL_BEFORE_PROCESSING) {
ServerTryCancel(context);
return Status::CANCELLED;
}
std::thread* server_try_cancel_thd = NULL;
if (server_try_cancel == CANCEL_DURING_PROCESSING) {
server_try_cancel_thd =
new std::thread(&TestServiceImpl::ServerTryCancel, this, context);
}
int num_msgs_read = 0;
while (reader->Read(&request)) {
if (cancel_after_reads == 1) {
gpr_log(GPR_INFO, "return cancel status");
@ -164,21 +198,65 @@ Status TestServiceImpl::RequestStream(ServerContext* context,
}
response->mutable_message()->append(request.message());
}
gpr_log(GPR_INFO, "Read: %d messages", num_msgs_read);
if (server_try_cancel_thd != NULL) {
server_try_cancel_thd->join();
delete server_try_cancel_thd;
return Status::CANCELLED;
}
if (server_try_cancel == CANCEL_AFTER_PROCESSING) {
ServerTryCancel(context);
return Status::CANCELLED;
}
return Status::OK;
}
// Return 3 messages.
// Return 'kNumResponseStreamMsgs' messages.
// TODO(yangg) make it generic by adding a parameter into EchoRequest
Status TestServiceImpl::ResponseStream(ServerContext* context,
const EchoRequest* request,
ServerWriter<EchoResponse>* writer) {
// If server_try_cancel is set in the metadata, the RPC is cancelled by the
// server by calling ServerContext::TryCancel() depending on the value:
// CANCEL_BEFORE_PROCESSING: The RPC is cancelled before the server writes
// any messages to the client
// CANCEL_DURING_PROCESSING: The RPC is cancelled while the server is
// writing messages to the client
// CANCEL_AFTER_PROCESSING: The RPC is cancelled after the server writes
// all the messages to the client
int server_try_cancel = GetIntValueFromMetadata(
kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL);
if (server_try_cancel == CANCEL_BEFORE_PROCESSING) {
ServerTryCancel(context);
return Status::CANCELLED;
}
EchoResponse response;
response.set_message(request->message() + "0");
writer->Write(response);
response.set_message(request->message() + "1");
writer->Write(response);
response.set_message(request->message() + "2");
writer->Write(response);
std::thread* server_try_cancel_thd = NULL;
if (server_try_cancel == CANCEL_DURING_PROCESSING) {
server_try_cancel_thd =
new std::thread(&TestServiceImpl::ServerTryCancel, this, context);
}
for (int i = 0; i < kNumResponseStreamsMsgs; i++) {
response.set_message(request->message() + std::to_string(i));
writer->Write(response);
}
if (server_try_cancel_thd != NULL) {
server_try_cancel_thd->join();
delete server_try_cancel_thd;
return Status::CANCELLED;
}
if (server_try_cancel == CANCEL_AFTER_PROCESSING) {
ServerTryCancel(context);
return Status::CANCELLED;
}
return Status::OK;
}
@ -186,15 +264,70 @@ Status TestServiceImpl::ResponseStream(ServerContext* context,
Status TestServiceImpl::BidiStream(
ServerContext* context,
ServerReaderWriter<EchoResponse, EchoRequest>* stream) {
// If server_try_cancel is set in the metadata, the RPC is cancelled by the
// server by calling ServerContext::TryCancel() depending on the value:
// CANCEL_BEFORE_PROCESSING: The RPC is cancelled before the server reads/
// writes any messages from/to the client
// CANCEL_DURING_PROCESSING: The RPC is cancelled while the server is
// reading/writing messages from/to the client
// CANCEL_AFTER_PROCESSING: The RPC is cancelled after the server
// reads/writes all messages from/to the client
int server_try_cancel = GetIntValueFromMetadata(
kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL);
EchoRequest request;
EchoResponse response;
if (server_try_cancel == CANCEL_BEFORE_PROCESSING) {
ServerTryCancel(context);
return Status::CANCELLED;
}
std::thread* server_try_cancel_thd = NULL;
if (server_try_cancel == CANCEL_DURING_PROCESSING) {
server_try_cancel_thd =
new std::thread(&TestServiceImpl::ServerTryCancel, this, context);
}
while (stream->Read(&request)) {
gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
response.set_message(request.message());
stream->Write(response);
}
if (server_try_cancel_thd != NULL) {
server_try_cancel_thd->join();
delete server_try_cancel_thd;
return Status::CANCELLED;
}
if (server_try_cancel == CANCEL_AFTER_PROCESSING) {
ServerTryCancel(context);
return Status::CANCELLED;
}
return Status::OK;
}
int TestServiceImpl::GetIntValueFromMetadata(
const char* key,
const std::multimap<grpc::string_ref, grpc::string_ref>& metadata,
int default_value) {
if (metadata.find(key) != metadata.end()) {
std::istringstream iss(ToString(metadata.find(key)->second));
iss >> default_value;
gpr_log(GPR_INFO, "%s : %d", key, default_value);
}
return default_value;
}
void TestServiceImpl::ServerTryCancel(ServerContext* context) {
EXPECT_FALSE(context->IsCancelled());
context->TryCancel();
gpr_log(GPR_INFO, "Server called TryCancel() to cancel the request");
EXPECT_TRUE(context->IsCancelled());
}
} // namespace testing
} // namespace grpc

@ -44,7 +44,16 @@
namespace grpc {
namespace testing {
const int kNumResponseStreamsMsgs = 3;
const char* const kServerCancelAfterReads = "cancel_after_reads";
const char* const kServerTryCancelRequest = "server_try_cancel";
typedef enum {
DO_NOT_CANCEL = 0,
CANCEL_BEFORE_PROCESSING,
CANCEL_DURING_PROCESSING,
CANCEL_AFTER_PROCESSING
} ServerTryCancelRequestPhase;
class TestServiceImpl : public ::grpc::testing::EchoTestService::Service {
public:
@ -73,6 +82,14 @@ class TestServiceImpl : public ::grpc::testing::EchoTestService::Service {
return signal_client_;
}
private:
int GetIntValueFromMetadata(
const char* key,
const std::multimap<grpc::string_ref, grpc::string_ref>& metadata,
int default_value);
void ServerTryCancel(ServerContext* context);
private:
bool signal_client_;
std::mutex mu_;

@ -45,6 +45,7 @@
#include <grpc/support/time.h>
#include <gtest/gtest.h>
#include "src/core/surface/api_trace.h"
#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/core/util/port.h"
@ -54,6 +55,9 @@ using grpc::testing::EchoRequest;
using grpc::testing::EchoResponse;
using std::chrono::system_clock;
const int kNumThreads = 100; // Number of threads
const int kNumRpcs = 1000; // Number of RPCs per thread
namespace grpc {
namespace testing {
@ -84,7 +88,7 @@ class TestServiceImpl : public ::grpc::testing::EchoTestService::Service {
MaybeEchoDeadline(context, request, response);
if (request->has_param() && request->param().client_cancel_after_us()) {
{
std::unique_lock<std::mutex> lock(mu_);
unique_lock<mutex> lock(mu_);
signal_client_ = true;
}
while (!context->IsCancelled()) {
@ -149,13 +153,13 @@ class TestServiceImpl : public ::grpc::testing::EchoTestService::Service {
}
bool signal_client() {
std::unique_lock<std::mutex> lock(mu_);
unique_lock<mutex> lock(mu_);
return signal_client_;
}
private:
bool signal_client_;
std::mutex mu_;
mutex mu_;
};
class TestServiceImplDupPkg
@ -168,11 +172,10 @@ class TestServiceImplDupPkg
}
};
class End2endTest : public ::testing::Test {
protected:
End2endTest() : kMaxMessageSize_(8192) {}
void SetUp() GRPC_OVERRIDE {
class CommonStressTest {
public:
CommonStressTest() : kMaxMessageSize_(8192) {}
void SetUp() {
int port = grpc_pick_unused_port_or_die();
server_address_ << "localhost:" << port;
// Setup server
@ -185,15 +188,15 @@ class End2endTest : public ::testing::Test {
builder.RegisterService(&dup_pkg_service_);
server_ = builder.BuildAndStart();
}
void TearDown() GRPC_OVERRIDE { server_->Shutdown(); }
void TearDown() { server_->Shutdown(); }
void ResetStub() {
std::shared_ptr<Channel> channel =
CreateChannel(server_address_.str(), InsecureChannelCredentials());
stub_ = grpc::testing::EchoTestService::NewStub(channel);
}
grpc::testing::EchoTestService::Stub* GetStub() { return stub_.get(); }
private:
std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
std::unique_ptr<Server> server_;
std::ostringstream server_address_;
@ -202,6 +205,16 @@ class End2endTest : public ::testing::Test {
TestServiceImplDupPkg dup_pkg_service_;
};
class End2endTest : public ::testing::Test {
protected:
End2endTest() {}
void SetUp() GRPC_OVERRIDE { common_.SetUp(); }
void TearDown() GRPC_OVERRIDE { common_.TearDown(); }
void ResetStub() { common_.ResetStub(); }
CommonStressTest common_;
};
static void SendRpc(grpc::testing::EchoTestService::Stub* stub, int num_rpcs) {
EchoRequest request;
EchoResponse response;
@ -216,17 +229,113 @@ static void SendRpc(grpc::testing::EchoTestService::Stub* stub, int num_rpcs) {
}
TEST_F(End2endTest, ThreadStress) {
ResetStub();
common_.ResetStub();
std::vector<std::thread*> threads;
for (int i = 0; i < 100; ++i) {
threads.push_back(new std::thread(SendRpc, stub_.get(), 1000));
for (int i = 0; i < kNumThreads; ++i) {
threads.push_back(new std::thread(SendRpc, common_.GetStub(), kNumRpcs));
}
for (int i = 0; i < 100; ++i) {
for (int i = 0; i < kNumThreads; ++i) {
threads[i]->join();
delete threads[i];
}
}
class AsyncClientEnd2endTest : public ::testing::Test {
protected:
AsyncClientEnd2endTest() : rpcs_outstanding_(0) {}
void SetUp() GRPC_OVERRIDE { common_.SetUp(); }
void TearDown() GRPC_OVERRIDE {
void* ignored_tag;
bool ignored_ok;
while (cq_.Next(&ignored_tag, &ignored_ok))
;
common_.TearDown();
}
void Wait() {
unique_lock<mutex> l(mu_);
while (rpcs_outstanding_ != 0) {
cv_.wait(l);
}
cq_.Shutdown();
}
struct AsyncClientCall {
EchoResponse response;
ClientContext context;
Status status;
std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader;
};
void AsyncSendRpc(int num_rpcs) {
for (int i = 0; i < num_rpcs; ++i) {
AsyncClientCall* call = new AsyncClientCall;
EchoRequest request;
request.set_message("Hello");
call->response_reader =
common_.GetStub()->AsyncEcho(&call->context, request, &cq_);
call->response_reader->Finish(&call->response, &call->status,
(void*)call);
unique_lock<mutex> l(mu_);
rpcs_outstanding_++;
}
}
void AsyncCompleteRpc() {
while (true) {
void* got_tag;
bool ok = false;
if (!cq_.Next(&got_tag, &ok)) break;
AsyncClientCall* call = static_cast<AsyncClientCall*>(got_tag);
GPR_ASSERT(ok);
delete call;
bool notify;
{
unique_lock<mutex> l(mu_);
rpcs_outstanding_--;
notify = (rpcs_outstanding_ == 0);
}
if (notify) {
cv_.notify_all();
}
}
}
CommonStressTest common_;
CompletionQueue cq_;
mutex mu_;
condition_variable cv_;
int rpcs_outstanding_;
};
TEST_F(AsyncClientEnd2endTest, ThreadStress) {
common_.ResetStub();
std::vector<std::thread*> send_threads, completion_threads;
for (int i = 0; i < kNumThreads / 2; ++i) {
completion_threads.push_back(new std::thread(
&AsyncClientEnd2endTest_ThreadStress_Test::AsyncCompleteRpc, this));
}
for (int i = 0; i < kNumThreads / 2; ++i) {
send_threads.push_back(
new std::thread(&AsyncClientEnd2endTest_ThreadStress_Test::AsyncSendRpc,
this, kNumRpcs));
}
for (int i = 0; i < kNumThreads / 2; ++i) {
send_threads[i]->join();
delete send_threads[i];
}
Wait();
for (int i = 0; i < kNumThreads / 2; ++i) {
completion_threads[i]->join();
delete completion_threads[i];
}
}
} // namespace testing
} // namespace grpc

@ -96,7 +96,8 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext {
std::function<
std::unique_ptr<grpc::ClientAsyncResponseReader<ResponseType>>(
BenchmarkService::Stub*, grpc::ClientContext*, const RequestType&,
CompletionQueue*)> start_req,
CompletionQueue*)>
start_req,
std::function<void(grpc::Status, ResponseType*)> on_done)
: ClientRpcContext(channel_id),
context_(),
@ -142,7 +143,8 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext {
std::function<void(grpc::Status, ResponseType*)> callback_;
std::function<std::unique_ptr<grpc::ClientAsyncResponseReader<ResponseType>>(
BenchmarkService::Stub*, grpc::ClientContext*, const RequestType&,
CompletionQueue*)> start_req_;
CompletionQueue*)>
start_req_;
grpc::Status status_;
double start_;
std::unique_ptr<grpc::ClientAsyncResponseReader<ResponseType>>
@ -162,11 +164,12 @@ class AsyncClient : public ClientImpl<StubType, RequestType> {
using ClientImpl<StubType, RequestType>::cores_;
using ClientImpl<StubType, RequestType>::channels_;
using ClientImpl<StubType, RequestType>::request_;
AsyncClient(const ClientConfig& config,
std::function<ClientRpcContext*(int, StubType*,
const RequestType&)> setup_ctx,
std::function<std::unique_ptr<StubType>(std::shared_ptr<Channel>)>
create_stub)
AsyncClient(
const ClientConfig& config,
std::function<ClientRpcContext*(int, StubType*, const RequestType&)>
setup_ctx,
std::function<std::unique_ptr<StubType>(std::shared_ptr<Channel>)>
create_stub)
: ClientImpl<StubType, RequestType>(config, create_stub),
num_async_threads_(NumThreads(config)),
channel_lock_(new std::mutex[config.client_channels()]),
@ -408,7 +411,8 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext {
std::function<std::unique_ptr<
grpc::ClientAsyncReaderWriter<RequestType, ResponseType>>(
BenchmarkService::Stub*, grpc::ClientContext*, CompletionQueue*,
void*)> start_req,
void*)>
start_req,
std::function<void(grpc::Status, ResponseType*)> on_done)
: ClientRpcContext(channel_id),
context_(),
@ -460,10 +464,10 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext {
ResponseType response_;
bool (ClientRpcContextStreamingImpl::*next_state_)(bool, Histogram*);
std::function<void(grpc::Status, ResponseType*)> callback_;
std::function<
std::unique_ptr<grpc::ClientAsyncReaderWriter<RequestType, ResponseType>>(
BenchmarkService::Stub*, grpc::ClientContext*, CompletionQueue*,
void*)> start_req_;
std::function<std::unique_ptr<
grpc::ClientAsyncReaderWriter<RequestType, ResponseType>>(
BenchmarkService::Stub*, grpc::ClientContext*, CompletionQueue*, void*)>
start_req_;
grpc::Status status_;
double start_;
std::unique_ptr<grpc::ClientAsyncReaderWriter<RequestType, ResponseType>>
@ -507,7 +511,8 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext {
int channel_id, grpc::GenericStub* stub, const ByteBuffer& req,
std::function<std::unique_ptr<grpc::GenericClientAsyncReaderWriter>(
grpc::GenericStub*, grpc::ClientContext*,
const grpc::string& method_name, CompletionQueue*, void*)> start_req,
const grpc::string& method_name, CompletionQueue*, void*)>
start_req,
std::function<void(grpc::Status, ByteBuffer*)> on_done)
: ClientRpcContext(channel_id),
context_(),
@ -564,7 +569,8 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext {
std::function<void(grpc::Status, ByteBuffer*)> callback_;
std::function<std::unique_ptr<grpc::GenericClientAsyncReaderWriter>(
grpc::GenericStub*, grpc::ClientContext*, const grpc::string&,
CompletionQueue*, void*)> start_req_;
CompletionQueue*, void*)>
start_req_;
grpc::Status status_;
double start_;
std::unique_ptr<grpc::GenericClientAsyncReaderWriter> stream_;

@ -384,5 +384,18 @@ std::unique_ptr<ScenarioResult> RunScenario(
delete[] servers;
return result;
}
void RunQuit() {
// Get client, server lists
auto workers = get_workers("QPS_WORKERS");
for (size_t i = 0; i < workers.size(); i++) {
auto stub = WorkerService::NewStub(
CreateChannel(workers[i], InsecureChannelCredentials()));
Void dummy;
grpc::ClientContext ctx;
GPR_ASSERT(stub->QuitWorker(&ctx, dummy, &dummy).ok());
}
}
} // namespace testing
} // namespace grpc

@ -70,6 +70,7 @@ std::unique_ptr<ScenarioResult> RunScenario(
const grpc::testing::ServerConfig& server_config, size_t num_servers,
int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count);
void RunQuit();
} // namespace testing
} // namespace grpc

@ -36,7 +36,6 @@
#include <grpc/support/cpu.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include <vector>
namespace grpc {
namespace testing {
@ -46,11 +45,11 @@ namespace testing {
#define _GNU_SOURCE
#endif
#include <sched.h>
int LimitCores(const int *cores, int cores_size) {
int LimitCores(const int* cores, int cores_size) {
const int num_cores = gpr_cpu_num_cores();
int cores_set = 0;
cpu_set_t *cpup = CPU_ALLOC(num_cores);
cpu_set_t* cpup = CPU_ALLOC(num_cores);
GPR_ASSERT(cpup);
const size_t size = CPU_ALLOC_SIZE(num_cores);
CPU_ZERO_S(size, cpup);
@ -74,7 +73,7 @@ int LimitCores(const int *cores, int cores_size) {
}
#else
// LimitCores is not currently supported for non-Linux platforms
int LimitCores(std::vector<int> core_vec) { return gpr_cpu_num_cores(); }
int LimitCores(const int*, int) { return gpr_cpu_num_cores(); }
#endif
} // namespace testing
} // namespace grpc

@ -34,8 +34,6 @@
#ifndef TEST_QPS_LIMIT_CORES_H
#define TEST_QPS_LIMIT_CORES_H
#include <vector>
namespace grpc {
namespace testing {
/// LimitCores: allow this worker to only run on the cores specified in the

@ -78,6 +78,8 @@ DEFINE_int32(client_core_limit, -1, "Limit on client cores to use");
DEFINE_bool(secure_test, false, "Run a secure test");
DEFINE_bool(quit, false, "Quit the workers");
using grpc::testing::ClientConfig;
using grpc::testing::ServerConfig;
using grpc::testing::ClientType;
@ -90,6 +92,11 @@ namespace grpc {
namespace testing {
static void QpsDriver() {
if (FLAGS_quit) {
RunQuit();
return;
}
RpcType rpc_type;
GPR_ASSERT(RpcType_Parse(FLAGS_rpc_type, &rpc_type));

@ -103,8 +103,8 @@ static std::unique_ptr<Server> CreateServer(const ServerConfig& config) {
class WorkerServiceImpl GRPC_FINAL : public WorkerService::Service {
public:
explicit WorkerServiceImpl(int server_port)
: acquired_(false), server_port_(server_port) {}
WorkerServiceImpl(int server_port, QpsWorker* worker)
: acquired_(false), server_port_(server_port), worker_(worker) {}
Status RunClient(ServerContext* ctx,
ServerReaderWriter<ClientStatus, ClientArgs>* stream)
@ -140,6 +140,16 @@ class WorkerServiceImpl GRPC_FINAL : public WorkerService::Service {
return Status::OK;
}
Status QuitWorker(ServerContext* ctx, const Void*, Void*) GRPC_OVERRIDE {
InstanceGuard g(this);
if (!g.Acquired()) {
return Status(StatusCode::RESOURCE_EXHAUSTED, "");
}
worker_->MarkDone();
return Status::OK;
}
private:
// Protect against multiple clients using this worker at once.
class InstanceGuard {
@ -250,10 +260,12 @@ class WorkerServiceImpl GRPC_FINAL : public WorkerService::Service {
std::mutex mu_;
bool acquired_;
int server_port_;
QpsWorker* worker_;
};
QpsWorker::QpsWorker(int driver_port, int server_port) {
impl_.reset(new WorkerServiceImpl(server_port));
impl_.reset(new WorkerServiceImpl(server_port, this));
gpr_atm_rel_store(&done_, static_cast<gpr_atm>(0));
char* server_address = NULL;
gpr_join_host_port(&server_address, "::", driver_port);
@ -269,5 +281,11 @@ QpsWorker::QpsWorker(int driver_port, int server_port) {
QpsWorker::~QpsWorker() {}
bool QpsWorker::Done() const {
return (gpr_atm_acq_load(&done_) != static_cast<gpr_atm>(0));
}
void QpsWorker::MarkDone() {
gpr_atm_rel_store(&done_, static_cast<gpr_atm>(1));
}
} // namespace testing
} // namespace grpc

@ -36,6 +36,8 @@
#include <memory>
#include <grpc/support/atm.h>
namespace grpc {
class Server;
@ -49,9 +51,14 @@ class QpsWorker {
explicit QpsWorker(int driver_port, int server_port = 0);
~QpsWorker();
bool Done() const;
void MarkDone();
private:
std::unique_ptr<WorkerServiceImpl> impl_;
std::unique_ptr<Server> server_;
gpr_atm done_;
};
} // namespace testing

@ -56,7 +56,7 @@ namespace testing {
static void RunServer() {
QpsWorker worker(FLAGS_driver_port, FLAGS_server_port);
while (!got_sigint) {
while (!got_sigint && !worker.Done()) {
gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
gpr_time_from_seconds(5, GPR_TIMESPAN)));
}

@ -0,0 +1,57 @@
#!/usr/bin/env node
/*
*
* Copyright 2015-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.
*
*/
var grpc = require('grpc');
function identity(x) {
return x;
}
var Client = grpc.makeGenericClientConstructor({
'echo' : {
path: '/buffer/echo',
requestStream: false,
responseStream: false,
requestSerialize: identity,
requestDeserialize: identity,
responseSerialize: identity,
responseDeserialize: identity
}
});
var client = new Client("localhost:1000", grpc.credentials.createInsecure());
client.$channel.close();
console.log("Success!");

@ -0,0 +1,7 @@
{
"name": "grpc-distrib-test",
"version": "0.0.1",
"dependencies": {
"grpc": "*"
}
}

@ -0,0 +1,52 @@
#!/bin/bash
# Copyright 2015-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.
set -ex
cd $(dirname $0)
nvm install $1
npm install -g node-static
STATIC_SERVER=127.0.0.1
STATIC_PORT=8080
# Serves the input_artifacts directory statically at localhost:8080
static "$EXTERNAL_GIT_ROOT/input_artifacts" -a $STATIC_SERVER -p $STATIC_PORT &
STATIC_PID=$!
STATIC_URL="http://$STATIC_SERVER:$STATIC_PORT/"
npm install --unsafe-perm $STATIC_URL/grpc.tgz --grpc_node_binary_host_mirror=$STATIC_URL
kill -9 $STATIC_PID
./distrib_test.js

@ -0,0 +1,7 @@
from grpc.beta import implementations
# This code doesn't do much but makes sure the native extension is loaded
# which is what we are testing here.
channel = implementations.insecure_channel('localhost', 1000)
del channel
print 'Success!'

@ -32,5 +32,27 @@ set -ex
cd $(dirname $0)
pip install "$EXTERNAL_GIT_ROOT/input_artifacts/grpcio-0.12.0b6.tar.gz"
# TODO(jtattermusch): replace the version number
SDIST_ARCHIVE="$EXTERNAL_GIT_ROOT/input_artifacts/grpcio-0.12.0b8.tar.gz"
BDIST_DIR="file://$EXTERNAL_GIT_ROOT/input_artifacts"
if [ ! -f "${SDIST_ARCHIVE}" ]
then
echo "Archive ${SDIST_ARCHIVE} does not exist."
exit 1
fi
# TODO(jtattermusch): this shouldn't be required
pip install --upgrade six
# TODO(jtattermusch): if these don't get preinstalled, pip tries to install them
# with --use-grpc-custom-bdist option, which obviously fails.
pip install --upgrade enum34
pip install --upgrade futures
GRPC_PYTHON_BINARIES_REPOSITORY="${BDIST_DIR}" \
pip install \
"${SDIST_ARCHIVE}" \
--install-option="--use-grpc-custom-bdist"
python distribtest.py

@ -35,7 +35,7 @@ RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compa
RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \
RUN apt-get update && apt-get install -y \
mono-devel \
ca-certificates-mono \
nuget

@ -35,7 +35,7 @@ RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compa
RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \
RUN apt-get update && apt-get install -y \
mono-devel \
ca-certificates-mono \
nuget

@ -0,0 +1,40 @@
# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FROM ubuntu:14.04
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list
RUN apt-get update && apt-get install -y \
mono-devel \
ca-certificates-mono \
nuget
RUN apt-get update && apt-get install -y git unzip

@ -0,0 +1,40 @@
# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FROM ubuntu:15.04
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list
RUN apt-get update && apt-get install -y \
mono-devel \
ca-certificates-mono \
nuget
RUN apt-get update && apt-get install -y git unzip

@ -0,0 +1,40 @@
# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FROM ubuntu:15.10
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list
RUN apt-get update && apt-get install -y \
mono-devel \
ca-certificates-mono \
nuget
RUN apt-get update && apt-get install -y git unzip

@ -0,0 +1,37 @@
# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FROM ubuntu:16.04
RUN apt-get update && apt-get install -y \
mono-devel \
ca-certificates-mono \
nuget
RUN apt-get update && apt-get install -y git unzip

@ -0,0 +1,37 @@
# Copyright 2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FROM centos:7
RUN yum install -y git
RUN yum install -y curl
# Install nvm
RUN touch .profile
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.30.2/install.sh | bash

@ -0,0 +1,36 @@
# Copyright 2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FROM debian:jessie
RUN apt-get update && apt-get install -y curl git
# Install nvm
RUN touch .profile
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.30.2/install.sh | bash

@ -0,0 +1,36 @@
# Copyright 2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FROM 32bit/debian:jessie
RUN apt-get update && apt-get install -y curl git
# Install nvm
RUN touch .profile
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.30.2/install.sh | bash

@ -0,0 +1,36 @@
# Copyright 2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FROM ubuntu:12.04
RUN apt-get update && apt-get install -y curl git
# Install nvm
RUN touch .profile
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.30.2/install.sh | bash

@ -0,0 +1,36 @@
# Copyright 2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y curl git
# Install nvm
RUN touch .profile
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.30.2/install.sh | bash

@ -0,0 +1,36 @@
# Copyright 2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FROM ubuntu:15.04
RUN apt-get update && apt-get install -y curl git
# Install nvm
RUN touch .profile
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.30.2/install.sh | bash

@ -0,0 +1,36 @@
# Copyright 2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FROM ubuntu:15.10
RUN apt-get update && apt-get install -y curl git
# Install nvm
RUN touch .profile
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.30.2/install.sh | bash

@ -0,0 +1,36 @@
# Copyright 2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FROM ubuntu:16.04
RUN apt-get update && apt-get install -y curl git
# Install nvm
RUN touch .profile
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.30.2/install.sh | bash

@ -0,0 +1,36 @@
# Copyright 2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FROM debian:wheezy
RUN apt-get update && apt-get install -y curl
# Install nvm
RUN touch .profile
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.30.2/install.sh | bash

@ -953,7 +953,6 @@ src/core/support/string_win32.h \
src/core/support/thd_internal.h \
src/core/support/time_precise.h \
src/core/census/aggregation.h \
src/core/census/context.h \
src/core/census/rpc_metric_id.h \
src/core/httpcli/httpcli_security_connector.c \
src/core/security/base64.c \
@ -1150,7 +1149,6 @@ src/core/census/context.c \
src/core/census/initialize.c \
src/core/census/operation.c \
src/core/census/placeholders.c \
src/core/census/tag_set.c \
src/core/census/tracing.c
# This tag can be used to specify the character encoding of the source files

@ -43,6 +43,6 @@ fi
cd /var/local/git/grpc
nvm use 4
nvm use 4 || true
$RUN_COMMAND

@ -0,0 +1,49 @@
#!/usr/bin/env bash
# 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.
#
# This script is invoked by Jenkins and triggers run of distribution tests.
#
# To prevent cygwin bash complaining about empty lines ending with \r
# we set the igncr option. The option doesn't exist on Linux, so we fallback
# to just 'set -ex' there.
# NOTE: No empty lines should appear in this file before igncr is set!
set -ex -o igncr || set -ex
curr_platform="$platform"
unset platform # variable named 'platform' breaks the windows build
# Try collecting the artifacts to test from previous Jenkins build step
mkdir -p input_artifacts
cp -r platform=windows/artifacts/* input_artifacts || true
cp -r platform=linux/artifacts/* input_artifacts || true
python tools/run_tests/task_runner.py -j 4 \
-f distribtest $language $curr_platform $architecture \
$@

@ -96,13 +96,19 @@ class PythonArtifact:
if self.platform == 'windows':
raise Exception('Not supported yet.')
else:
environ = {}
if self.platform == 'linux':
if self.arch == 'x86':
environ['SETARCH_CMD'] = 'linux32'
return create_docker_jobspec(self.name,
'tools/dockerfile/grpc_artifact_linux_%s' % self.arch,
'tools/run_tests/build_artifact_python.sh')
'tools/run_tests/build_artifact_python.sh',
environ=environ)
else:
environ['SKIP_PIP_INSTALL'] = 'TRUE'
return create_jobspec(self.name,
['tools/run_tests/build_artifact_python.sh'])
['tools/run_tests/build_artifact_python.sh'],
environ=environ)
def __str__(self):
return self.name
@ -127,7 +133,7 @@ class RubyArtifact:
if self.platform == 'linux':
environ = {}
if self.arch == 'x86':
environ['SETARCH_CMD'] = 'i386'
environ['SETARCH_CMD'] = 'linux32'
return create_docker_jobspec(self.name,
'tools/dockerfile/grpc_artifact_linux_%s' % self.arch,
'tools/run_tests/build_artifact_ruby.sh',
@ -227,5 +233,7 @@ def targets():
for arch in ('x86', 'x64')] +
[PythonArtifact('linux', 'x86'),
PythonArtifact('linux', 'x64'),
PythonArtifact('macos', 'x64'),
RubyArtifact('linux', 'x86'),
RubyArtifact('linux', 'x64')])
RubyArtifact('linux', 'x64'),
RubyArtifact('macos', 'x64')])

@ -32,12 +32,14 @@ set -ex
cd $(dirname $0)/../..
pip install --upgrade six
pip install --upgrade setuptools
if [ "$SKIP_PIP_INSTALL" == "" ]
then
pip install --upgrade six
pip install --upgrade setuptools
pip install -rrequirements.txt
fi
pip install -rrequirements.txt
GRPC_PYTHON_BUILD_WITH_CYTHON=1 python setup.py \
GRPC_PYTHON_BUILD_WITH_CYTHON=1 ${SETARCH_CMD} python setup.py \
bdist_wheel \
sdist \
bdist_egg_grpc_custom

@ -32,7 +32,7 @@ set -ex
cd $(dirname $0)/../..
bundle install
${SETARCH_CMD} bundle install
${SETARCH_CMD} rake native gem

@ -0,0 +1,40 @@
#!/bin/bash
# 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.
set -ex
cd $(dirname $0)/../..
mkdir -p artifacts/
cp -r $EXTERNAL_GIT_ROOT/architecture={x86,x64},language=node,platform={windows,linux,macos}/artifacts/* artifacts/ || true
npm pack
cp grpc-*.tgz artifacts/grpc.tgz

@ -80,6 +80,36 @@ class CSharpDistribTest(object):
def __str__(self):
return self.name
class NodeDistribTest(object):
"""Tests Node package"""
def __init__(self, platform, arch, docker_suffix, node_version):
self.name = 'node_npm_%s_%s_%s_%s' % (platform, arch,
docker_suffix, node_version)
self.platform = platform
self.arch = arch
self.docker_suffix = docker_suffix
self.node_version = node_version
self.labels = ['distribtest', 'node', platform, arch,
docker_suffix, 'node-%s' % node_version]
def pre_build_jobspecs(self):
return []
def build_jobspec(self):
if self.platform not in ('linux',):
raise Exception("Not supported yet.")
return create_docker_jobspec(self.name,
'tools/dockerfile/distribtest/node_%s_%s' % (
self.docker_suffix,
self.arch),
# bash -l needed to make nvm available
'bash -l test/distrib/node/run_distrib_test.sh %s' % (
self.node_version))
def __str__(self):
return self.name
class PythonDistribTest(object):
"""Tests Python package"""
@ -141,6 +171,10 @@ def targets():
CSharpDistribTest('linux', 'x64', 'jessie'),
CSharpDistribTest('linux', 'x86', 'jessie'),
CSharpDistribTest('linux', 'x64', 'centos7'),
CSharpDistribTest('linux', 'x64', 'ubuntu1404'),
CSharpDistribTest('linux', 'x64', 'ubuntu1504'),
CSharpDistribTest('linux', 'x64', 'ubuntu1510'),
CSharpDistribTest('linux', 'x64', 'ubuntu1604'),
PythonDistribTest('linux', 'x64', 'wheezy'),
PythonDistribTest('linux', 'x64', 'jessie'),
PythonDistribTest('linux', 'x86', 'jessie'),
@ -172,5 +206,10 @@ def targets():
RubyDistribTest('linux', 'x64', 'ubuntu1504'),
RubyDistribTest('linux', 'x64', 'ubuntu1510'),
RubyDistribTest('linux', 'x64', 'ubuntu1604'),
NodeDistribTest('linux', 'x86', 'jessie', '4')
] + [
NodeDistribTest('linux', 'x64', os, version)
for os in ('wheezy', 'jessie', 'ubuntu1204', 'ubuntu1404',
'ubuntu1504', 'ubuntu1510', 'ubuntu1604')
for version in ('0.10', '0.12', '3', '4', '5')
]

@ -32,6 +32,26 @@
import jobset
def create_docker_jobspec(name, dockerfile_dir, shell_command, environ={},
flake_retries=0, timeout_retries=0):
"""Creates jobspec for a task running under docker."""
environ = environ.copy()
environ['RUN_COMMAND'] = shell_command
docker_args=[]
for k,v in environ.iteritems():
docker_args += ['-e', '%s=%s' % (k, v)]
docker_env = {'DOCKERFILE_DIR': dockerfile_dir,
'DOCKER_RUN_SCRIPT': 'tools/jenkins/docker_run.sh',
'OUTPUT_DIR': 'artifacts'}
jobspec = jobset.JobSpec(
cmdline=['tools/jenkins/build_and_run_docker.sh'] + docker_args,
environ=docker_env,
shortname='build_package.%s' % (name),
timeout_seconds=30*60,
flake_retries=flake_retries,
timeout_retries=timeout_retries)
return jobspec
def create_jobspec(name, cmdline, environ=None, cwd=None, shell=False,
flake_retries=0, timeout_retries=0):
@ -67,7 +87,22 @@ class CSharpNugetTarget:
def __str__(self):
return self.name
class NodeNpmBinaryTarget:
"""Builds Node NPM package and collects binaries"""
def __init__(self):
self.name = 'node_npm_binary'
self.labels = ['package', 'node', 'linux']
def pre_build_jobspecs(self):
return []
def build_jobspec(self):
return create_docker_jobspec(
self.name,
'tools/dockerfile/grpc_artifact_linux_x64',
'tools/run_tests/build_package_node.sh')
def targets():
"""Gets list of supported targets"""
return [CSharpNugetTarget()]
return [CSharpNugetTarget(), NodeNpmBinaryTarget()]

@ -61,6 +61,18 @@
"test/core/transport/chttp2/bin_encoder_test.c"
]
},
{
"deps": [
"grpc",
"grpc_test_util"
],
"headers": [],
"language": "c",
"name": "census_context_test",
"src": [
"test/core/census/context_test.c"
]
},
{
"deps": [
"grpc",
@ -981,18 +993,6 @@
"test/core/iomgr/socket_utils_test.c"
]
},
{
"deps": [
"grpc",
"grpc_test_util"
],
"headers": [],
"language": "c",
"name": "tag_set_test",
"src": [
"test/core/census/tag_set_test.c"
]
},
{
"deps": [
"grpc",
@ -2506,7 +2506,6 @@
"include/grpc/support/tls_pthread.h",
"include/grpc/support/useful.h",
"src/core/census/aggregation.h",
"src/core/census/context.h",
"src/core/census/grpc_filter.h",
"src/core/census/rpc_metric_id.h",
"src/core/channel/channel_args.h",
@ -2706,7 +2705,6 @@
"include/grpc/support/useful.h",
"src/core/census/aggregation.h",
"src/core/census/context.c",
"src/core/census/context.h",
"src/core/census/grpc_context.c",
"src/core/census/grpc_filter.c",
"src/core/census/grpc_filter.h",
@ -2714,7 +2712,6 @@
"src/core/census/operation.c",
"src/core/census/placeholders.c",
"src/core/census/rpc_metric_id.h",
"src/core/census/tag_set.c",
"src/core/census/tracing.c",
"src/core/channel/channel_args.c",
"src/core/channel/channel_args.h",
@ -3181,7 +3178,6 @@
"include/grpc/support/tls_pthread.h",
"include/grpc/support/useful.h",
"src/core/census/aggregation.h",
"src/core/census/context.h",
"src/core/census/grpc_filter.h",
"src/core/census/rpc_metric_id.h",
"src/core/channel/channel_args.h",
@ -3366,7 +3362,6 @@
"include/grpc/support/useful.h",
"src/core/census/aggregation.h",
"src/core/census/context.c",
"src/core/census/context.h",
"src/core/census/grpc_context.c",
"src/core/census/grpc_filter.c",
"src/core/census/grpc_filter.h",
@ -3374,7 +3369,6 @@
"src/core/census/operation.c",
"src/core/census/placeholders.c",
"src/core/census/rpc_metric_id.h",
"src/core/census/tag_set.c",
"src/core/census/tracing.c",
"src/core/channel/channel_args.c",
"src/core/channel/channel_args.h",

@ -101,6 +101,26 @@
"windows"
]
},
{
"args": [],
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "census_context_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
]
},
{
"args": [],
"ci_platforms": [
@ -1419,26 +1439,6 @@
"posix"
]
},
{
"args": [],
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "tag_set_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
]
},
{
"args": [],
"ci_platforms": [

@ -126,6 +126,15 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bin_encoder_test", "vcxproj
{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "census_context_test", "vcxproj\test\census_context_test\census_context_test.vcxproj", "{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}"
ProjectSection(myProperties) = preProject
lib = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "channel_create_test", "vcxproj\test\channel_create_test\channel_create_test.vcxproj", "{AFC88484-3A2E-32BC-25B2-23DF741D4F3D}"
ProjectSection(myProperties) = preProject
lib = "False"
@ -724,15 +733,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sockaddr_utils_test", "vcxp
{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tag_set_test", "vcxproj\test\tag_set_test\tag_set_test.vcxproj", "{430F8F07-6AAD-0150-B35B-DB9E2E21941A}"
ProjectSection(myProperties) = preProject
lib = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "time_averaged_stats_test", "vcxproj\test\time_averaged_stats_test\time_averaged_stats_test.vcxproj", "{D1EB2A9B-8508-62D7-8FC4-11A11B1CBFD3}"
ProjectSection(myProperties) = preProject
lib = "False"
@ -1349,6 +1349,22 @@ Global
{D5C70922-D68E-0E9D-9988-995E0F9A79AE}.Release-DLL|Win32.Build.0 = Release|Win32
{D5C70922-D68E-0E9D-9988-995E0F9A79AE}.Release-DLL|x64.ActiveCfg = Release|x64
{D5C70922-D68E-0E9D-9988-995E0F9A79AE}.Release-DLL|x64.Build.0 = Release|x64
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Debug|Win32.ActiveCfg = Debug|Win32
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Debug|x64.ActiveCfg = Debug|x64
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release|Win32.ActiveCfg = Release|Win32
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release|x64.ActiveCfg = Release|x64
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Debug|Win32.Build.0 = Debug|Win32
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Debug|x64.Build.0 = Debug|x64
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release|Win32.Build.0 = Release|Win32
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release|x64.Build.0 = Release|x64
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Debug-DLL|Win32.Build.0 = Debug|Win32
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Debug-DLL|x64.ActiveCfg = Debug|x64
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Debug-DLL|x64.Build.0 = Debug|x64
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release-DLL|Win32.ActiveCfg = Release|Win32
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release-DLL|Win32.Build.0 = Release|Win32
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release-DLL|x64.ActiveCfg = Release|x64
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release-DLL|x64.Build.0 = Release|x64
{AFC88484-3A2E-32BC-25B2-23DF741D4F3D}.Debug|Win32.ActiveCfg = Debug|Win32
{AFC88484-3A2E-32BC-25B2-23DF741D4F3D}.Debug|x64.ActiveCfg = Debug|x64
{AFC88484-3A2E-32BC-25B2-23DF741D4F3D}.Release|Win32.ActiveCfg = Release|Win32
@ -2421,22 +2437,6 @@ Global
{529771F0-10B0-9B1A-1E7E-8A8E01870348}.Release-DLL|Win32.Build.0 = Release|Win32
{529771F0-10B0-9B1A-1E7E-8A8E01870348}.Release-DLL|x64.ActiveCfg = Release|x64
{529771F0-10B0-9B1A-1E7E-8A8E01870348}.Release-DLL|x64.Build.0 = Release|x64
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Debug|Win32.ActiveCfg = Debug|Win32
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Debug|x64.ActiveCfg = Debug|x64
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Release|Win32.ActiveCfg = Release|Win32
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Release|x64.ActiveCfg = Release|x64
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Debug|Win32.Build.0 = Debug|Win32
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Debug|x64.Build.0 = Debug|x64
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Release|Win32.Build.0 = Release|Win32
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Release|x64.Build.0 = Release|x64
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Debug-DLL|Win32.Build.0 = Debug|Win32
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Debug-DLL|x64.ActiveCfg = Debug|x64
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Debug-DLL|x64.Build.0 = Debug|x64
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Release-DLL|Win32.ActiveCfg = Release|Win32
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Release-DLL|Win32.Build.0 = Release|Win32
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Release-DLL|x64.ActiveCfg = Release|x64
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Release-DLL|x64.Build.0 = Release|x64
{D1EB2A9B-8508-62D7-8FC4-11A11B1CBFD3}.Debug|Win32.ActiveCfg = Debug|Win32
{D1EB2A9B-8508-62D7-8FC4-11A11B1CBFD3}.Debug|x64.ActiveCfg = Debug|x64
{D1EB2A9B-8508-62D7-8FC4-11A11B1CBFD3}.Release|Win32.ActiveCfg = Release|Win32

@ -462,7 +462,6 @@
<ClInclude Include="$(SolutionDir)\..\src\core\support\thd_internal.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\support\time_precise.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\census\aggregation.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\census\context.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\census\rpc_metric_id.h" />
</ItemGroup>
<ItemGroup>
@ -856,8 +855,6 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\census\placeholders.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\census\tag_set.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\census\tracing.c">
</ClCompile>
</ItemGroup>

@ -586,9 +586,6 @@
<ClCompile Include="$(SolutionDir)\..\src\core\census\placeholders.c">
<Filter>src\core\census</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\census\tag_set.c">
<Filter>src\core\census</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\census\tracing.c">
<Filter>src\core\census</Filter>
</ClCompile>
@ -1175,9 +1172,6 @@
<ClInclude Include="$(SolutionDir)\..\src\core\census\aggregation.h">
<Filter>src\core\census</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\census\context.h">
<Filter>src\core\census</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\census\rpc_metric_id.h">
<Filter>src\core\census</Filter>
</ClInclude>

@ -438,7 +438,6 @@
<ClInclude Include="$(SolutionDir)\..\src\core\transport\transport.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\transport\transport_impl.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\census\aggregation.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\census\context.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\census\rpc_metric_id.h" />
</ItemGroup>
<ItemGroup>
@ -792,8 +791,6 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\census\placeholders.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\census\tag_set.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\census\tracing.c">
</ClCompile>
</ItemGroup>

@ -526,9 +526,6 @@
<ClCompile Include="$(SolutionDir)\..\src\core\census\placeholders.c">
<Filter>src\core\census</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\census\tag_set.c">
<Filter>src\core\census</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\census\tracing.c">
<Filter>src\core\census</Filter>
</ClCompile>
@ -1070,9 +1067,6 @@
<ClInclude Include="$(SolutionDir)\..\src\core\census\aggregation.h">
<Filter>src\core\census</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\census\context.h">
<Filter>src\core\census</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\census\rpc_metric_id.h">
<Filter>src\core\census</Filter>
</ClInclude>

@ -20,7 +20,7 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{430F8F07-6AAD-0150-B35B-DB9E2E21941A}</ProjectGuid>
<ProjectGuid>{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}</ProjectGuid>
<IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
<IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
</PropertyGroup>
@ -60,14 +60,14 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<TargetName>tag_set_test</TargetName>
<TargetName>census_context_test</TargetName>
<Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
<Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
<Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
<Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<TargetName>tag_set_test</TargetName>
<TargetName>census_context_test</TargetName>
<Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
<Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
<Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
@ -158,7 +158,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="$(SolutionDir)\..\test\core\census\tag_set_test.c">
<ClCompile Include="$(SolutionDir)\..\test\core\census\context_test.c">
</ClCompile>
</ItemGroup>
<ItemGroup>

@ -1,20 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="$(SolutionDir)\..\test\core\census\tag_set_test.c">
<ClCompile Include="$(SolutionDir)\..\test\core\census\context_test.c">
<Filter>test\core\census</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="test">
<UniqueIdentifier>{500aa440-5924-8047-996a-4c5096d1ef96}</UniqueIdentifier>
<UniqueIdentifier>{bc15bb31-7dbe-17f2-fb1c-4bc140ce1707}</UniqueIdentifier>
</Filter>
<Filter Include="test\core">
<UniqueIdentifier>{a3bf80f0-5b13-f623-277b-05f0231dd933}</UniqueIdentifier>
<UniqueIdentifier>{806f9b58-6a48-ae09-3cc6-bb36e3126f27}</UniqueIdentifier>
</Filter>
<Filter Include="test\core\census">
<UniqueIdentifier>{b6ed1b86-7795-4da9-a169-9eccf836852c}</UniqueIdentifier>
<UniqueIdentifier>{85e37a47-e797-dcd1-b1e0-df553a454d8f}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>
Loading…
Cancel
Save