Merge branch 'master' of github.com:grpc/grpc into the-ultimate-showdown

pull/2612/head
Nicolas "Pixel" Noble 9 years ago
commit f123443aa5
  1. 5
      BUILD
  2. 36
      Makefile
  3. 14
      build.json
  4. 2
      gRPC.podspec
  5. 56
      include/grpc/support/cancellable_platform.h
  6. 33
      include/grpc/support/sync.h
  7. 157
      src/core/support/cancellable.c
  8. 15
      src/core/support/sync.c
  9. 59
      src/php/ext/grpc/channel.c
  10. 12
      src/php/ext/grpc/php_grpc.c
  11. 45
      src/php/lib/Grpc/BaseStub.php
  12. 46
      src/php/tests/unit_tests/EndToEndTest.php
  13. 43
      src/python/grpcio/grpc/_links/service.py
  14. 2
      src/python/grpcio_health_checking/MANIFEST.in
  15. 9
      src/python/grpcio_health_checking/README.rst
  16. 80
      src/python/grpcio_health_checking/commands.py
  17. 30
      src/python/grpcio_health_checking/grpc/__init__.py
  18. 30
      src/python/grpcio_health_checking/grpc/health/__init__.py
  19. 30
      src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py
  20. 49
      src/python/grpcio_health_checking/grpc/health/v1alpha/health.proto
  21. 129
      src/python/grpcio_health_checking/grpc/health/v1alpha/health.py
  22. 72
      src/python/grpcio_health_checking/setup.py
  23. 9
      src/python/grpcio_test/grpc_test/framework/interfaces/links/test_cases.py
  24. 2
      templates/BUILD.template
  25. 172
      test/core/support/cancellable_test.c
  26. 3
      test/cpp/interop/interop_client.cc
  27. 4
      test/cpp/interop/server.cc
  28. 2
      test/cpp/util/echo.proto
  29. 2
      test/cpp/util/echo_duplicate.proto
  30. 30
      test/cpp/util/messages.proto
  31. 2
      test/proto/empty.proto
  32. 50
      test/proto/messages.proto
  33. 2
      test/proto/test.proto
  34. 1
      tools/doxygen/Doxyfile.core
  35. 2
      tools/doxygen/Doxyfile.core.internal
  36. 7
      tools/run_tests/build_python.sh
  37. 15
      tools/run_tests/sources_and_headers.json
  38. 17
      tools/run_tests/tests.json
  39. 10
      vsprojects/Grpc.mak
  40. 3
      vsprojects/gpr/gpr.vcxproj
  41. 6
      vsprojects/gpr/gpr.vcxproj.filters

@ -52,7 +52,6 @@ cc_library(
"src/core/support/string_win32.h", "src/core/support/string_win32.h",
"src/core/support/thd_internal.h", "src/core/support/thd_internal.h",
"src/core/support/alloc.c", "src/core/support/alloc.c",
"src/core/support/cancellable.c",
"src/core/support/cmdline.c", "src/core/support/cmdline.c",
"src/core/support/cpu_iphone.c", "src/core/support/cpu_iphone.c",
"src/core/support/cpu_linux.c", "src/core/support/cpu_linux.c",
@ -96,7 +95,6 @@ cc_library(
"include/grpc/support/atm_gcc_atomic.h", "include/grpc/support/atm_gcc_atomic.h",
"include/grpc/support/atm_gcc_sync.h", "include/grpc/support/atm_gcc_sync.h",
"include/grpc/support/atm_win32.h", "include/grpc/support/atm_win32.h",
"include/grpc/support/cancellable_platform.h",
"include/grpc/support/cmdline.h", "include/grpc/support/cmdline.h",
"include/grpc/support/cpu.h", "include/grpc/support/cpu.h",
"include/grpc/support/histogram.h", "include/grpc/support/histogram.h",
@ -400,6 +398,7 @@ cc_library(
], ],
deps = [ deps = [
"//external:libssl", "//external:libssl",
"//external:zlib",
":gpr", ":gpr",
], ],
) )
@ -887,7 +886,6 @@ objc_library(
name = "gpr_objc", name = "gpr_objc",
srcs = [ srcs = [
"src/core/support/alloc.c", "src/core/support/alloc.c",
"src/core/support/cancellable.c",
"src/core/support/cmdline.c", "src/core/support/cmdline.c",
"src/core/support/cpu_iphone.c", "src/core/support/cpu_iphone.c",
"src/core/support/cpu_linux.c", "src/core/support/cpu_linux.c",
@ -931,7 +929,6 @@ objc_library(
"include/grpc/support/atm_gcc_atomic.h", "include/grpc/support/atm_gcc_atomic.h",
"include/grpc/support/atm_gcc_sync.h", "include/grpc/support/atm_gcc_sync.h",
"include/grpc/support/atm_win32.h", "include/grpc/support/atm_win32.h",
"include/grpc/support/cancellable_platform.h",
"include/grpc/support/cmdline.h", "include/grpc/support/cmdline.h",
"include/grpc/support/cpu.h", "include/grpc/support/cpu.h",
"include/grpc/support/histogram.h", "include/grpc/support/histogram.h",

File diff suppressed because one or more lines are too long

@ -367,7 +367,6 @@
"include/grpc/support/atm_gcc_atomic.h", "include/grpc/support/atm_gcc_atomic.h",
"include/grpc/support/atm_gcc_sync.h", "include/grpc/support/atm_gcc_sync.h",
"include/grpc/support/atm_win32.h", "include/grpc/support/atm_win32.h",
"include/grpc/support/cancellable_platform.h",
"include/grpc/support/cmdline.h", "include/grpc/support/cmdline.h",
"include/grpc/support/cpu.h", "include/grpc/support/cpu.h",
"include/grpc/support/histogram.h", "include/grpc/support/histogram.h",
@ -402,7 +401,6 @@
], ],
"src": [ "src": [
"src/core/support/alloc.c", "src/core/support/alloc.c",
"src/core/support/cancellable.c",
"src/core/support/cmdline.c", "src/core/support/cmdline.c",
"src/core/support/cpu_iphone.c", "src/core/support/cpu_iphone.c",
"src/core/support/cpu_linux.c", "src/core/support/cpu_linux.c",
@ -1106,18 +1104,6 @@
"grpc" "grpc"
] ]
}, },
{
"name": "gpr_cancellable_test",
"build": "test",
"language": "c",
"src": [
"test/core/support/cancellable_test.c"
],
"deps": [
"gpr_test_util",
"gpr"
]
},
{ {
"name": "gpr_cmdline_test", "name": "gpr_cmdline_test",
"build": "test", "build": "test",

@ -73,7 +73,6 @@ Pod::Spec.new do |s|
'grpc/support/atm_gcc_atomic.h', 'grpc/support/atm_gcc_atomic.h',
'grpc/support/atm_gcc_sync.h', 'grpc/support/atm_gcc_sync.h',
'grpc/support/atm_win32.h', 'grpc/support/atm_win32.h',
'grpc/support/cancellable_platform.h',
'grpc/support/cmdline.h', 'grpc/support/cmdline.h',
'grpc/support/cpu.h', 'grpc/support/cpu.h',
'grpc/support/histogram.h', 'grpc/support/histogram.h',
@ -97,7 +96,6 @@ Pod::Spec.new do |s|
'grpc/support/tls_pthread.h', 'grpc/support/tls_pthread.h',
'grpc/support/useful.h', 'grpc/support/useful.h',
'src/core/support/alloc.c', 'src/core/support/alloc.c',
'src/core/support/cancellable.c',
'src/core/support/cmdline.c', 'src/core/support/cmdline.c',
'src/core/support/cpu_iphone.c', 'src/core/support/cpu_iphone.c',
'src/core/support/cpu_linux.c', 'src/core/support/cpu_linux.c',

@ -1,56 +0,0 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_SUPPORT_CANCELLABLE_PLATFORM_H
#define GRPC_SUPPORT_CANCELLABLE_PLATFORM_H
#include <grpc/support/atm.h>
#include <grpc/support/sync.h>
struct gpr_cancellable_list_ {
/* a doubly-linked list on cancellable's waiters queue */
struct gpr_cancellable_list_ *next;
struct gpr_cancellable_list_ *prev;
/* The following two fields are arguments to gpr_cv_cancellable_wait() */
gpr_mu *mu;
gpr_cv *cv;
};
/* Internal definition of gpr_cancellable. */
typedef struct {
gpr_mu mu; /* protects waiters and modifications to cancelled */
gpr_atm cancelled;
struct gpr_cancellable_list_ waiters;
} gpr_cancellable;
#endif /* GRPC_SUPPORT_CANCELLABLE_PLATFORM_H */

@ -65,7 +65,6 @@
#endif #endif
#include <grpc/support/time.h> /* for gpr_timespec */ #include <grpc/support/time.h> /* for gpr_timespec */
#include <grpc/support/cancellable_platform.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -121,11 +120,6 @@ void gpr_cv_destroy(gpr_cv *cv);
holds an exclusive lock on *mu. */ holds an exclusive lock on *mu. */
int gpr_cv_wait(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline); int gpr_cv_wait(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline);
/* Behave like gpr_cv_wait(cv, mu, abs_deadline), except behave as though
the deadline has expired if *c is cancelled. */
int gpr_cv_cancellable_wait(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline,
gpr_cancellable *c);
/* If any threads are waiting on *cv, wake at least one. /* If any threads are waiting on *cv, wake at least one.
Clients may treat this as an optimization of gpr_cv_broadcast() Clients may treat this as an optimization of gpr_cv_broadcast()
for use in the case where waking more than one waiter is not useful. for use in the case where waking more than one waiter is not useful.
@ -135,28 +129,6 @@ void gpr_cv_signal(gpr_cv *cv);
/* Wake all threads waiting on *cv. Requires: *cv initialized. */ /* Wake all threads waiting on *cv. Requires: *cv initialized. */
void gpr_cv_broadcast(gpr_cv *cv); void gpr_cv_broadcast(gpr_cv *cv);
/* --- Cancellation ---
A gpr_cancellable can be used with gpr_cv_cancellable_wait()
or gpr_event_cancellable_wait() cancel pending waits. */
/* Initialize *c. */
void gpr_cancellable_init(gpr_cancellable *c);
/* Cause *c no longer to be initialized, freeing any memory in use. Requires:
*c initialized; no other concurrent operation on *c. */
void gpr_cancellable_destroy(gpr_cancellable *c);
/* Return non-zero iff *c has been cancelled. Requires *c initialized.
This call is faster than acquiring a mutex on most platforms. */
int gpr_cancellable_is_cancelled(gpr_cancellable *c);
/* Cancel *c. If *c was not previously cancelled, cause
gpr_cancellable_init() to return non-zero, and outstanding and future
calls to gpr_cv_cancellable_wait() and gpr_event_cancellable_wait() to
return immediately indicating a timeout has occurred; otherwise do nothing.
Requires *c initialized.*/
void gpr_cancellable_cancel(gpr_cancellable *c);
/* --- One-time initialization --- /* --- One-time initialization ---
gpr_once must be declared with static storage class, and initialized with gpr_once must be declared with static storage class, and initialized with
@ -199,11 +171,6 @@ void *gpr_event_get(gpr_event *ev);
on most platforms. */ on most platforms. */
void *gpr_event_wait(gpr_event *ev, gpr_timespec abs_deadline); void *gpr_event_wait(gpr_event *ev, gpr_timespec abs_deadline);
/* Behave like gpr_event_wait(ev, abs_deadline), except behave as though
the deadline has expired if *c is cancelled. */
void *gpr_event_cancellable_wait(gpr_event *ev, gpr_timespec abs_deadline,
gpr_cancellable *c);
/* --- Reference counting --- /* --- Reference counting ---
These calls act on the type gpr_refcount. It requires no destruction. */ These calls act on the type gpr_refcount. It requires no destruction. */

@ -1,157 +0,0 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* Implementation for gpr_cancellable */
#include <grpc/support/atm.h>
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
void gpr_cancellable_init(gpr_cancellable *c) {
gpr_mu_init(&c->mu);
c->cancelled = 0;
c->waiters.next = &c->waiters;
c->waiters.prev = &c->waiters;
c->waiters.mu = NULL;
c->waiters.cv = NULL;
}
void gpr_cancellable_destroy(gpr_cancellable *c) { gpr_mu_destroy(&c->mu); }
int gpr_cancellable_is_cancelled(gpr_cancellable *c) {
return gpr_atm_acq_load(&c->cancelled) != 0;
}
/* Threads in gpr_cv_cancellable_wait(cv, mu, ..., c) place themselves on a
linked list c->waiters of gpr_cancellable_list_ before waiting on their
condition variables. They check for cancellation while holding *mu. Thus,
to wake a thread from gpr_cv_cancellable_wait(), it suffices to:
- set c->cancelled
- acquire and release *mu
- gpr_cv_broadcast(cv)
However, gpr_cancellable_cancel() may not use gpr_mu_lock(mu), since the
caller may already hold *mu---a possible deadlock. (If we knew the caller
did not hold *mu, care would still be needed, because c->mu follows *mu in
the locking order, so *mu could not be acquired while holding c->mu---which
is needed to iterate over c->waiters.)
Therefore, gpr_cancellable_cancel() uses gpr_mu_trylock() rather than
gpr_mu_lock(), and retries until either gpr_mu_trylock() succeeds or the
thread leaves gpr_cv_cancellable_wait() for other reasons. In the first
case, gpr_cancellable_cancel() removes the entry from the waiters list; in
the second, the waiting thread removes itself from the list.
A one-entry cache of mutexes and condition variables processed is kept to
avoid doing the same work again and again if many threads are blocked in the
same place. However, it's important to broadcast on a condition variable if
the corresponding mutex has been locked successfully, even if the condition
variable has been signalled before. */
void gpr_cancellable_cancel(gpr_cancellable *c) {
if (!gpr_cancellable_is_cancelled(c)) {
int failures;
int backoff = 1;
do {
struct gpr_cancellable_list_ *l;
struct gpr_cancellable_list_ *nl;
gpr_mu *omu = 0; /* one-element cache of a processed gpr_mu */
gpr_cv *ocv = 0; /* one-element cache of a processd gpr_cv */
gpr_mu_lock(&c->mu);
gpr_atm_rel_store(&c->cancelled, 1);
failures = 0;
for (l = c->waiters.next; l != &c->waiters; l = nl) {
nl = l->next;
if (omu != l->mu) {
omu = l->mu;
if (gpr_mu_trylock(l->mu)) {
gpr_mu_unlock(l->mu);
l->next->prev = l->prev; /* remove *l from list */
l->prev->next = l->next;
/* allow unconditional dequeue in gpr_cv_cancellable_wait() */
l->next = l;
l->prev = l;
ocv = 0; /* force broadcast */
} else {
failures++;
}
}
if (ocv != l->cv) {
ocv = l->cv;
gpr_cv_broadcast(l->cv);
}
}
gpr_mu_unlock(&c->mu);
if (failures != 0) {
if (backoff < 10) {
volatile int i;
for (i = 0; i != (1 << backoff); i++) {
}
backoff++;
} else {
gpr_event ev;
gpr_event_init(&ev);
gpr_event_wait(
&ev, gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
gpr_time_from_micros(1000, GPR_TIMESPAN)));
}
}
} while (failures != 0);
}
}
int gpr_cv_cancellable_wait(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline,
gpr_cancellable *c) {
gpr_int32 timeout;
gpr_mu_lock(&c->mu);
timeout = gpr_cancellable_is_cancelled(c);
if (!timeout) {
struct gpr_cancellable_list_ le;
le.mu = mu;
le.cv = cv;
le.next = c->waiters.next;
le.prev = &c->waiters;
le.next->prev = &le;
le.prev->next = &le;
gpr_mu_unlock(&c->mu);
timeout = gpr_cv_wait(cv, mu, abs_deadline);
gpr_mu_lock(&c->mu);
le.next->prev = le.prev;
le.prev->next = le.next;
if (!timeout) {
timeout = gpr_cancellable_is_cancelled(c);
}
}
gpr_mu_unlock(&c->mu);
return timeout;
}

@ -94,21 +94,6 @@ void *gpr_event_wait(gpr_event *ev, gpr_timespec abs_deadline) {
return result; return result;
} }
void *gpr_event_cancellable_wait(gpr_event *ev, gpr_timespec abs_deadline,
gpr_cancellable *c) {
void *result = (void *)gpr_atm_acq_load(&ev->state);
if (result == NULL) {
struct sync_array_s *s = hash(ev);
gpr_mu_lock(&s->mu);
do {
result = (void *)gpr_atm_acq_load(&ev->state);
} while (result == NULL &&
!gpr_cv_cancellable_wait(&s->cv, &s->mu, abs_deadline, c));
gpr_mu_unlock(&s->mu);
}
return result;
}
void gpr_ref_init(gpr_refcount *r, int n) { gpr_atm_rel_store(&r->count, n); } void gpr_ref_init(gpr_refcount *r, int n) { gpr_atm_rel_store(&r->count, n); }
void gpr_ref(gpr_refcount *r) { gpr_atm_no_barrier_fetch_add(&r->count, 1); } void gpr_ref(gpr_refcount *r) { gpr_atm_no_barrier_fetch_add(&r->count, 1); }

@ -51,8 +51,10 @@
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include <grpc/grpc_security.h> #include <grpc/grpc_security.h>
#include "server.h" #include "completion_queue.h"
#include "credentials.h" #include "credentials.h"
#include "server.h"
#include "timeval.h"
zend_class_entry *grpc_ce_channel; zend_class_entry *grpc_ce_channel;
@ -204,6 +206,59 @@ PHP_METHOD(Channel, getTarget) {
RETURN_STRING(grpc_channel_get_target(channel->wrapped), 1); RETURN_STRING(grpc_channel_get_target(channel->wrapped), 1);
} }
/**
* Get the connectivity state of the channel
* @param bool (optional) try to connect on the channel
* @return long The grpc connectivity state
*/
PHP_METHOD(Channel, getConnectivityState) {
wrapped_grpc_channel *channel =
(wrapped_grpc_channel *)zend_object_store_get_object(getThis() TSRMLS_CC);
bool try_to_connect;
/* "|b" == 1 optional bool */
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &try_to_connect) ==
FAILURE) {
zend_throw_exception(spl_ce_InvalidArgumentException,
"getConnectivityState expects a bool", 1 TSRMLS_CC);
return;
}
RETURN_LONG(grpc_channel_check_connectivity_state(channel->wrapped,
(int)try_to_connect));
}
/**
* Watch the connectivity state of the channel until it changed
* @param long The previous connectivity state of the channel
* @param Timeval The deadline this function should wait until
* @return bool If the connectivity state changes from last_state
* before deadline
*/
PHP_METHOD(Channel, watchConnectivityState) {
wrapped_grpc_channel *channel =
(wrapped_grpc_channel *)zend_object_store_get_object(getThis() TSRMLS_CC);
long last_state;
zval *deadline_obj;
/* "lO" == 1 long 1 object */
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lO",
&last_state, &deadline_obj, grpc_ce_timeval) == FAILURE) {
zend_throw_exception(spl_ce_InvalidArgumentException,
"watchConnectivityState expects 1 long 1 timeval",
1 TSRMLS_CC);
return;
}
wrapped_grpc_timeval *deadline =
(wrapped_grpc_timeval *)zend_object_store_get_object(
deadline_obj TSRMLS_CC);
grpc_channel_watch_connectivity_state(
channel->wrapped, (grpc_connectivity_state)last_state,
deadline->wrapped, completion_queue, NULL);
grpc_event event = grpc_completion_queue_pluck(
completion_queue, NULL,
gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
RETURN_BOOL(event.success);
}
/** /**
* Close the channel * Close the channel
*/ */
@ -219,6 +274,8 @@ PHP_METHOD(Channel, close) {
static zend_function_entry channel_methods[] = { static zend_function_entry channel_methods[] = {
PHP_ME(Channel, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) PHP_ME(Channel, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
PHP_ME(Channel, getTarget, NULL, ZEND_ACC_PUBLIC) PHP_ME(Channel, getTarget, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Channel, getConnectivityState, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Channel, watchConnectivityState, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Channel, close, NULL, ZEND_ACC_PUBLIC) PHP_ME(Channel, close, NULL, ZEND_ACC_PUBLIC)
PHP_FE_END}; PHP_FE_END};

@ -183,6 +183,18 @@ PHP_MINIT_FUNCTION(grpc) {
REGISTER_LONG_CONSTANT("Grpc\\OP_RECV_CLOSE_ON_SERVER", REGISTER_LONG_CONSTANT("Grpc\\OP_RECV_CLOSE_ON_SERVER",
GRPC_OP_RECV_CLOSE_ON_SERVER, CONST_CS); GRPC_OP_RECV_CLOSE_ON_SERVER, CONST_CS);
/* Register connectivity state constants */
REGISTER_LONG_CONSTANT("Grpc\\CHANNEL_IDLE",
GRPC_CHANNEL_IDLE, CONST_CS);
REGISTER_LONG_CONSTANT("Grpc\\CHANNEL_CONNECTING",
GRPC_CHANNEL_CONNECTING, CONST_CS);
REGISTER_LONG_CONSTANT("Grpc\\CHANNEL_READY",
GRPC_CHANNEL_READY, CONST_CS);
REGISTER_LONG_CONSTANT("Grpc\\CHANNEL_TRANSIENT_FAILURE",
GRPC_CHANNEL_TRANSIENT_FAILURE, CONST_CS);
REGISTER_LONG_CONSTANT("Grpc\\CHANNEL_FATAL_FAILURE",
GRPC_CHANNEL_FATAL_FAILURE, CONST_CS);
grpc_init_call(TSRMLS_C); grpc_init_call(TSRMLS_C);
grpc_init_channel(TSRMLS_C); grpc_init_channel(TSRMLS_C);
grpc_init_server(TSRMLS_C); grpc_init_server(TSRMLS_C);

@ -74,6 +74,51 @@ class BaseStub {
return $this->channel->getTarget(); return $this->channel->getTarget();
} }
/**
* @param $try_to_connect bool
* @return int The grpc connectivity state
*/
public function getConnectivityState($try_to_connect = false) {
return $this->channel->getConnectivityState($try_to_connect);
}
/**
* @param $timeout in microseconds
* @return bool true if channel is ready
* @throw Exception if channel is in FATAL_ERROR state
*/
public function waitForReady($timeout) {
$new_state = $this->getConnectivityState(true);
if ($this->_checkConnectivityState($new_state)) {
return true;
}
$now = Timeval::now();
$delta = new Timeval($timeout);
$deadline = $now->add($delta);
while ($this->channel->watchConnectivityState($new_state, $deadline)) {
// state has changed before deadline
$new_state = $this->getConnectivityState();
if ($this->_checkConnectivityState($new_state)) {
return true;
}
}
// deadline has passed
$new_state = $this->getConnectivityState();
return $this->_checkConnectivityState($new_state);
}
private function _checkConnectivityState($new_state) {
if ($new_state == Grpc\CHANNEL_READY) {
return true;
}
if ($new_state == Grpc\CHANNEL_FATAL_ERROR) {
throw new Exception('Failed to connect to server');
}
return false;
}
/** /**
* Close the communication channel associated with this stub * Close the communication channel associated with this stub
*/ */

@ -153,4 +153,50 @@ class EndToEndTest extends PHPUnit_Framework_TestCase{
public function testGetTarget() { public function testGetTarget() {
$this->assertTrue(is_string($this->channel->getTarget())); $this->assertTrue(is_string($this->channel->getTarget()));
} }
public function testGetConnectivityState() {
$this->assertTrue($this->channel->getConnectivityState() == Grpc\CHANNEL_IDLE);
}
public function testWatchConnectivityStateFailed() {
$idle_state = $this->channel->getConnectivityState(true);
$this->assertTrue($idle_state == Grpc\CHANNEL_IDLE);
$now = Grpc\Timeval::now();
$delta = new Grpc\Timeval(1);
$deadline = $now->add($delta);
$this->assertFalse($this->channel->watchConnectivityState(
$idle_state, $deadline));
}
public function testWatchConnectivityStateSuccess() {
$idle_state = $this->channel->getConnectivityState(true);
$this->assertTrue($idle_state == Grpc\CHANNEL_IDLE);
$now = Grpc\Timeval::now();
$delta = new Grpc\Timeval(3000000); // should finish well before
$deadline = $now->add($delta);
$this->assertTrue($this->channel->watchConnectivityState(
$idle_state, $deadline));
$new_state = $this->channel->getConnectivityState();
$this->assertTrue($idle_state != $new_state);
}
public function testWatchConnectivityStateDoNothing() {
$idle_state = $this->channel->getConnectivityState();
$this->assertTrue($idle_state == Grpc\CHANNEL_IDLE);
$now = Grpc\Timeval::now();
$delta = new Grpc\Timeval(100000);
$deadline = $now->add($delta);
$this->assertFalse($this->channel->watchConnectivityState(
$idle_state, $deadline));
$new_state = $this->channel->getConnectivityState();
$this->assertTrue($new_state == Grpc\CHANNEL_IDLE);
}
} }

@ -44,7 +44,10 @@ from grpc.framework.interfaces.links import links
@enum.unique @enum.unique
class _Read(enum.Enum): class _Read(enum.Enum):
READING = 'reading' READING = 'reading'
AWAITING_ALLOWANCE = 'awaiting allowance' # TODO(issue 2916): This state will again be necessary after eliminating the
# "early_read" field of _RPCState and going back to only reading when granted
# allowance to read.
# AWAITING_ALLOWANCE = 'awaiting allowance'
CLOSED = 'closed' CLOSED = 'closed'
@ -67,12 +70,15 @@ class _RPCState(object):
def __init__( def __init__(
self, request_deserializer, response_serializer, sequence_number, read, self, request_deserializer, response_serializer, sequence_number, read,
allowance, high_write, low_write, premetadataed, terminal_metadata, code, early_read, allowance, high_write, low_write, premetadataed,
message): terminal_metadata, code, message):
self.request_deserializer = request_deserializer self.request_deserializer = request_deserializer
self.response_serializer = response_serializer self.response_serializer = response_serializer
self.sequence_number = sequence_number self.sequence_number = sequence_number
self.read = read self.read = read
# TODO(issue 2916): Eliminate this by eliminating the necessity of calling
# call.read just to advance the RPC.
self.early_read = early_read # A raw (not deserialized) read.
self.allowance = allowance self.allowance = allowance
self.high_write = high_write self.high_write = high_write
self.low_write = low_write self.low_write = low_write
@ -120,7 +126,7 @@ class _Kernel(object):
call.read(call) call.read(call)
self._rpc_states[call] = _RPCState( self._rpc_states[call] = _RPCState(
request_deserializer, response_serializer, 1, _Read.READING, 0, request_deserializer, response_serializer, 1, _Read.READING, None, 1,
_HighWrite.OPEN, _LowWrite.OPEN, False, None, None, None) _HighWrite.OPEN, _LowWrite.OPEN, False, None, None, None)
ticket = links.Ticket( ticket = links.Ticket(
call, 0, group, method, links.Ticket.Subscription.FULL, call, 0, group, method, links.Ticket.Subscription.FULL,
@ -140,12 +146,15 @@ class _Kernel(object):
termination = links.Ticket.Termination.COMPLETION termination = links.Ticket.Termination.COMPLETION
else: else:
if 0 < rpc_state.allowance: if 0 < rpc_state.allowance:
payload = rpc_state.request_deserializer(event.bytes)
termination = None
rpc_state.allowance -= 1 rpc_state.allowance -= 1
call.read(call) call.read(call)
else: else:
rpc_state.read = _Read.AWAITING_ALLOWANCE rpc_state.early_read = event.bytes
payload = rpc_state.request_deserializer(event.bytes) return
termination = None # TODO(issue 2916): Instead of returning:
# rpc_state.read = _Read.AWAITING_ALLOWANCE
ticket = links.Ticket( ticket = links.Ticket(
call, rpc_state.sequence_number, None, None, None, None, None, None, call, rpc_state.sequence_number, None, None, None, None, None, None,
payload, None, None, None, termination) payload, None, None, None, termination)
@ -237,12 +246,22 @@ class _Kernel(object):
rpc_state.premetadataed = True rpc_state.premetadataed = True
if ticket.allowance is not None: if ticket.allowance is not None:
if rpc_state.read is _Read.AWAITING_ALLOWANCE: if rpc_state.early_read is None:
rpc_state.allowance += ticket.allowance - 1
call.read(call)
rpc_state.read = _Read.READING
else:
rpc_state.allowance += ticket.allowance rpc_state.allowance += ticket.allowance
else:
payload = rpc_state.request_deserializer(rpc_state.early_read)
rpc_state.allowance += ticket.allowance - 1
rpc_state.early_read = None
if rpc_state.read is _Read.READING:
call.read(call)
termination = None
else:
termination = links.Ticket.Termination.COMPLETION
ticket = links.Ticket(
call, rpc_state.sequence_number, None, None, None, None, None,
None, payload, None, None, None, termination)
rpc_state.sequence_number += 1
self._relay.add_value(ticket)
if ticket.payload is not None: if ticket.payload is not None:
call.write(rpc_state.response_serializer(ticket.payload), call) call.write(rpc_state.response_serializer(ticket.payload), call)

@ -0,0 +1,2 @@
graft grpc
include commands.py

@ -0,0 +1,9 @@
gRPC Python Health Checking
===========================
Reference package for GRPC Python health checking.
Dependencies
------------
Depends on the `grpcio` package, available from PyPI via `pip install grpcio`.

@ -0,0 +1,80 @@
# Copyright 2015, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Provides distutils command classes for the GRPC Python setup process."""
import distutils
import glob
import os
import os.path
import subprocess
import sys
import setuptools
from setuptools.command import build_py
class BuildProtoModules(setuptools.Command):
"""Command to generate project *_pb2.py modules from proto files."""
description = ''
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
self.protoc_command = 'protoc'
self.grpc_python_plugin_command = distutils.spawn.find_executable(
'grpc_python_plugin')
def run(self):
paths = []
root_directory = os.getcwd()
for walk_root, directories, filenames in os.walk(root_directory):
for filename in filenames:
if filename.endswith('.proto'):
paths.append(os.path.join(walk_root, filename))
command = [
self.protoc_command,
'--plugin=protoc-gen-python-grpc={}'.format(
self.grpc_python_plugin_command),
'-I {}'.format(root_directory),
'--python_out={}'.format(root_directory),
'--python-grpc_out={}'.format(root_directory),
] + paths
subprocess.check_call(' '.join(command), cwd=root_directory, shell=True)
class BuildPy(build_py.build_py):
"""Custom project build command."""
def run(self):
self.run_command('build_proto_modules')
build_py.build_py.run(self)

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

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

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

@ -0,0 +1,49 @@
// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package grpc.health.v1alpha;
message HealthCheckRequest {
string service = 1;
}
message HealthCheckResponse {
enum ServingStatus {
UNKNOWN = 0;
SERVING = 1;
NOT_SERVING = 2;
}
ServingStatus status = 1;
}
service Health {
rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
}

@ -0,0 +1,129 @@
# Copyright 2015, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Reference implementation for health checking in gRPC Python."""
import abc
import enum
import threading
from grpc.health.v1alpha import health_pb2
@enum.unique
class HealthStatus(enum.Enum):
"""Statuses for a service mirroring the reference health.proto's values."""
UNKNOWN = health_pb2.HealthCheckResponse.UNKNOWN
SERVING = health_pb2.HealthCheckResponse.SERVING
NOT_SERVING = health_pb2.HealthCheckResponse.NOT_SERVING
class _HealthServicer(health_pb2.EarlyAdopterHealthServicer):
"""Servicer handling RPCs for service statuses."""
def __init__(self):
self._server_status_lock = threading.Lock()
self._server_status = {}
def Check(self, request, context):
with self._server_status_lock:
if request.service not in self._server_status:
# TODO(atash): once the Python API has a way of setting the server
# status, bring us into conformance with the health check spec by
# returning the NOT_FOUND status here.
raise NotImplementedError()
else:
return health_pb2.HealthCheckResponse(
status=self._server_status[request.service].value)
def set(service, status):
if not isinstance(status, HealthStatus):
raise TypeError('expected grpc.health.v1alpha.health.HealthStatus '
'for argument `status` but got {}'.format(status))
with self._server_status_lock:
self._server_status[service] = status
class HealthServer(health_pb2.EarlyAdopterHealthServer):
"""Interface for the reference gRPC Python health server."""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def start(self):
raise NotImplementedError()
@abc.abstractmethod
def stop(self):
raise NotImplementedError()
@abc.abstractmethod
def set(self, service, status):
"""Set the status of the given service.
Args:
service (str): service name of the service to set the reported status of
status (HealthStatus): status to set for the specified service
"""
raise NotImplementedError()
class _HealthServerImplementation(HealthServer):
"""Implementation for the reference gRPC Python health server."""
def __init__(self, server, servicer):
self._server = server
self._servicer = servicer
def start(self):
self._server.start()
def stop(self):
self._server.stop()
def set(self, service, status):
self._servicer.set(service, status)
def create_Health_server(port, private_key=None, certificate_chain=None):
"""Get a HealthServer instance.
Args:
port (int): port number passed through to health_pb2 server creation
routine.
private_key (str): to-be-created server's desired private key
certificate_chain (str): to-be-created server's desired certificate chain
Returns:
An instance of HealthServer (conforming thus to
EarlyAdopterHealthServer and providing a method to set server status)."""
servicer = _HealthServicer()
server = health_pb2.early_adopter_create_Health_server(
servicer, port=port, private_key=private_key,
certificate_chain=certificate_chain)
return _HealthServerImplementation(server, servicer)

@ -0,0 +1,72 @@
# Copyright 2015, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Setup module for the GRPC Python package's optional health checking."""
import os
import os.path
import sys
from distutils import core as _core
import setuptools
# Ensure we're in the proper directory whether or not we're being used by pip.
os.chdir(os.path.dirname(os.path.abspath(__file__)))
# Break import-style to ensure we can actually find our commands module.
import commands
_PACKAGES = (
setuptools.find_packages('.')
)
_PACKAGE_DIRECTORIES = {
'': '.',
}
_INSTALL_REQUIRES = (
'grpcio>=0.10.0a0',
)
_SETUP_REQUIRES = _INSTALL_REQUIRES
_COMMAND_CLASS = {
'build_proto_modules': commands.BuildProtoModules,
'build_py': commands.BuildPy,
}
setuptools.setup(
name='grpcio_health_checking',
version='0.10.0a0',
packages=list(_PACKAGES),
package_dir=_PACKAGE_DIRECTORIES,
install_requires=_INSTALL_REQUIRES,
setup_requires=_SETUP_REQUIRES,
cmdclass=_COMMAND_CLASS
)

@ -303,16 +303,9 @@ class TransmissionTest(object):
invocation_message, links.Ticket.Termination.COMPLETION) invocation_message, links.Ticket.Termination.COMPLETION)
self._invocation_link.accept_ticket(original_invocation_ticket) self._invocation_link.accept_ticket(original_invocation_ticket)
# TODO(nathaniel): This shouldn't be necessary. Detecting the end of the
# invocation-side ticket sequence shouldn't require granting allowance for
# another payload.
self._service_mate.block_until_tickets_satisfy( self._service_mate.block_until_tickets_satisfy(
at_least_n_payloads_received_predicate(1)) at_least_n_payloads_received_predicate(1))
service_operation_id = self._service_mate.tickets()[0].operation_id service_operation_id = self._service_mate.tickets()[0].operation_id
self._service_link.accept_ticket(
links.Ticket(
service_operation_id, 0, None, None, links.Ticket.Subscription.FULL,
None, 1, None, None, None, None, None, None))
self._service_mate.block_until_tickets_satisfy(terminated) self._service_mate.block_until_tickets_satisfy(terminated)
self._assert_is_valid_invocation_sequence( self._assert_is_valid_invocation_sequence(
@ -321,7 +314,7 @@ class TransmissionTest(object):
invocation_terminal_metadata, links.Ticket.Termination.COMPLETION) invocation_terminal_metadata, links.Ticket.Termination.COMPLETION)
original_service_ticket = links.Ticket( original_service_ticket = links.Ticket(
service_operation_id, 1, None, None, links.Ticket.Subscription.FULL, service_operation_id, 0, None, None, links.Ticket.Subscription.FULL,
timeout, 0, service_initial_metadata, service_payload, timeout, 0, service_initial_metadata, service_payload,
service_terminal_metadata, service_code, service_message, service_terminal_metadata, service_code, service_message,
links.Ticket.Termination.COMPLETION) links.Ticket.Termination.COMPLETION)

@ -49,6 +49,8 @@ def get_deps(target_dict):
deps.append("//external:protobuf_compiler") deps.append("//external:protobuf_compiler")
if target_dict['name'] == 'grpc++_unsecure' or target_dict['name'] == 'grpc++': if target_dict['name'] == 'grpc++_unsecure' or target_dict['name'] == 'grpc++':
deps.append("//external:protobuf_clib") deps.append("//external:protobuf_clib")
elif target_dict['name'] == 'grpc':
deps.append("//external:zlib")
for d in target_dict.get('deps', []): for d in target_dict.get('deps', []):
if d.find('//') == 0 or d[0] == ':': if d.find('//') == 0 or d[0] == ':':
deps.append(d) deps.append(d)

@ -1,172 +0,0 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* Test of gpr_cancellable. */
#include <stdio.h>
#include <stdlib.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include "test/core/util/test_config.h"
struct test {
gpr_mu mu;
gpr_cv cv;
gpr_event ev;
gpr_event done;
gpr_cancellable cancel;
int n;
};
/* A thread body. Wait until t->cancel is cancelledm then
decrement t->n. If t->n becomes 0, set t->done. */
static void thd_body(void *v) {
struct test *t = v;
gpr_mu_lock(&t->mu);
while (!gpr_cv_cancellable_wait(
&t->cv, &t->mu, gpr_inf_future(GPR_CLOCK_REALTIME), &t->cancel)) {
}
t->n--;
if (t->n == 0) {
gpr_event_set(&t->done, (void *)1);
}
gpr_mu_unlock(&t->mu);
}
static void test(void) {
int i;
gpr_thd_id thd;
struct test t;
int n = 1;
gpr_timespec interval;
gpr_mu_init(&t.mu);
gpr_cv_init(&t.cv);
gpr_event_init(&t.ev);
gpr_event_init(&t.done);
gpr_cancellable_init(&t.cancel);
/* A gpr_cancellable starts not cancelled. */
GPR_ASSERT(!gpr_cancellable_is_cancelled(&t.cancel));
/* Test timeout on event wait for uncancelled gpr_cancellable */
interval = gpr_now(GPR_CLOCK_REALTIME);
gpr_event_cancellable_wait(
&t.ev, gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
gpr_time_from_micros(1000000, GPR_TIMESPAN)),
&t.cancel);
interval = gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), interval);
GPR_ASSERT(
gpr_time_cmp(interval, gpr_time_from_micros(500000, GPR_TIMESPAN)) >= 0);
GPR_ASSERT(
gpr_time_cmp(gpr_time_from_micros(2000000, GPR_TIMESPAN), interval) >= 0);
/* Test timeout on cv wait for uncancelled gpr_cancellable */
gpr_mu_lock(&t.mu);
interval = gpr_now(GPR_CLOCK_REALTIME);
while (!gpr_cv_cancellable_wait(
&t.cv, &t.mu, gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
gpr_time_from_micros(1000000, GPR_TIMESPAN)),
&t.cancel)) {
}
interval = gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), interval);
GPR_ASSERT(
gpr_time_cmp(interval, gpr_time_from_micros(500000, GPR_TIMESPAN)) >= 0);
GPR_ASSERT(
gpr_time_cmp(gpr_time_from_micros(2000000, GPR_TIMESPAN), interval) >= 0);
gpr_mu_unlock(&t.mu);
/* Create some threads. They all wait until cancelled; the last to finish
sets t.done. */
t.n = n;
for (i = 0; i != n; i++) {
GPR_ASSERT(gpr_thd_new(&thd, &thd_body, &t, NULL));
}
/* Check that t.cancel still is not cancelled. */
GPR_ASSERT(!gpr_cancellable_is_cancelled(&t.cancel));
/* Wait a second, and check that no threads have finished waiting. */
gpr_mu_lock(&t.mu);
gpr_cv_wait(&t.cv, &t.mu,
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
gpr_time_from_micros(1000000, GPR_TIMESPAN)));
GPR_ASSERT(t.n == n);
gpr_mu_unlock(&t.mu);
/* Check that t.cancel still is not cancelled, but when
cancelled it retports that it is cacncelled. */
GPR_ASSERT(!gpr_cancellable_is_cancelled(&t.cancel));
gpr_cancellable_cancel(&t.cancel);
GPR_ASSERT(gpr_cancellable_is_cancelled(&t.cancel));
/* Wait for threads to finish. */
gpr_event_wait(&t.done, gpr_inf_future(GPR_CLOCK_REALTIME));
GPR_ASSERT(t.n == 0);
/* Test timeout on cv wait for cancelled gpr_cancellable */
gpr_mu_lock(&t.mu);
interval = gpr_now(GPR_CLOCK_REALTIME);
while (!gpr_cv_cancellable_wait(
&t.cv, &t.mu, gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
gpr_time_from_micros(1000000, GPR_TIMESPAN)),
&t.cancel)) {
}
interval = gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), interval);
GPR_ASSERT(
gpr_time_cmp(gpr_time_from_micros(100000, GPR_TIMESPAN), interval) >= 0);
gpr_mu_unlock(&t.mu);
/* Test timeout on event wait for cancelled gpr_cancellable */
interval = gpr_now(GPR_CLOCK_REALTIME);
gpr_event_cancellable_wait(
&t.ev, gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
gpr_time_from_micros(1000000, GPR_TIMESPAN)),
&t.cancel);
interval = gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), interval);
GPR_ASSERT(
gpr_time_cmp(gpr_time_from_micros(100000, GPR_TIMESPAN), interval) >= 0);
gpr_mu_destroy(&t.mu);
gpr_cv_destroy(&t.cv);
gpr_cancellable_destroy(&t.cancel);
}
/* ------------------------------------------------- */
int main(int argc, char *argv[]) {
grpc_test_init(argc, argv);
test();
return 0;
}

@ -316,7 +316,6 @@ void InteropClient::DoHalfDuplex() {
unsigned int i = 0; unsigned int i = 0;
StreamingOutputCallResponse response; StreamingOutputCallResponse response;
while (stream->Read(&response)) { while (stream->Read(&response)) {
GPR_ASSERT(response.payload().has_body());
GPR_ASSERT(response.payload().body() == GPR_ASSERT(response.payload().body() ==
grpc::string(response_stream_sizes[i], '\0')); grpc::string(response_stream_sizes[i], '\0'));
++i; ++i;
@ -346,7 +345,6 @@ void InteropClient::DoPingPong() {
payload->set_body(grpc::string(request_stream_sizes[i], '\0')); payload->set_body(grpc::string(request_stream_sizes[i], '\0'));
GPR_ASSERT(stream->Write(request)); GPR_ASSERT(stream->Write(request));
GPR_ASSERT(stream->Read(&response)); GPR_ASSERT(stream->Read(&response));
GPR_ASSERT(response.payload().has_body());
GPR_ASSERT(response.payload().body() == GPR_ASSERT(response.payload().body() ==
grpc::string(response_stream_sizes[i], '\0')); grpc::string(response_stream_sizes[i], '\0'));
} }
@ -393,7 +391,6 @@ void InteropClient::DoCancelAfterFirstResponse() {
StreamingOutputCallResponse response; StreamingOutputCallResponse response;
GPR_ASSERT(stream->Write(request)); GPR_ASSERT(stream->Write(request));
GPR_ASSERT(stream->Read(&response)); GPR_ASSERT(stream->Read(&response));
GPR_ASSERT(response.payload().has_body());
GPR_ASSERT(response.payload().body() == grpc::string(31415, '\0')); GPR_ASSERT(response.payload().body() == grpc::string(31415, '\0'));
gpr_log(GPR_INFO, "Trying to cancel..."); gpr_log(GPR_INFO, "Trying to cancel...");
context.TryCancel(); context.TryCancel();

@ -99,7 +99,7 @@ class TestServiceImpl : public TestService::Service {
Status UnaryCall(ServerContext* context, const SimpleRequest* request, Status UnaryCall(ServerContext* context, const SimpleRequest* request,
SimpleResponse* response) { SimpleResponse* response) {
if (request->has_response_size() && request->response_size() > 0) { if (request->response_size() > 0) {
if (!SetPayload(request->response_type(), request->response_size(), if (!SetPayload(request->response_type(), request->response_size(),
response->mutable_payload())) { response->mutable_payload())) {
return Status(grpc::StatusCode::INTERNAL, "Error creating payload."); return Status(grpc::StatusCode::INTERNAL, "Error creating payload.");
@ -140,7 +140,7 @@ class TestServiceImpl : public TestService::Service {
StreamingInputCallRequest request; StreamingInputCallRequest request;
int aggregated_payload_size = 0; int aggregated_payload_size = 0;
while (reader->Read(&request)) { while (reader->Read(&request)) {
if (request.has_payload() && request.payload().has_body()) { if (request.has_payload()) {
aggregated_payload_size += request.payload().body().size(); aggregated_payload_size += request.payload().body().size();
} }
} }

@ -28,7 +28,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2"; syntax = "proto3";
import "test/cpp/util/messages.proto"; import "test/cpp/util/messages.proto";

@ -30,7 +30,7 @@
// This is a partial copy of echo.proto with a different package name. // This is a partial copy of echo.proto with a different package name.
syntax = "proto2"; syntax = "proto3";
import "test/cpp/util/messages.proto"; import "test/cpp/util/messages.proto";

@ -28,32 +28,32 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2"; syntax = "proto3";
package grpc.cpp.test.util; package grpc.cpp.test.util;
message RequestParams { message RequestParams {
optional bool echo_deadline = 1; bool echo_deadline = 1;
optional int32 client_cancel_after_us = 2; int32 client_cancel_after_us = 2;
optional int32 server_cancel_after_us = 3; int32 server_cancel_after_us = 3;
optional bool echo_metadata = 4; bool echo_metadata = 4;
optional bool check_auth_context = 5; bool check_auth_context = 5;
optional int32 response_message_length = 6; int32 response_message_length = 6;
optional bool echo_peer = 7; bool echo_peer = 7;
} }
message EchoRequest { message EchoRequest {
optional string message = 1; string message = 1;
optional RequestParams param = 2; RequestParams param = 2;
} }
message ResponseParams { message ResponseParams {
optional int64 request_deadline = 1; int64 request_deadline = 1;
optional string host = 2; string host = 2;
optional string peer = 3; string peer = 3;
} }
message EchoResponse { message EchoResponse {
optional string message = 1; string message = 1;
optional ResponseParams param = 2; ResponseParams param = 2;
} }

@ -28,7 +28,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2"; syntax = "proto3";
package grpc.testing; package grpc.testing;

@ -30,7 +30,7 @@
// Message definitions to be used by integration test service definitions. // Message definitions to be used by integration test service definitions.
syntax = "proto2"; syntax = "proto3";
package grpc.testing; package grpc.testing;
@ -57,59 +57,59 @@ enum CompressionType {
// A block of data, to simply increase gRPC message size. // A block of data, to simply increase gRPC message size.
message Payload { message Payload {
// The type of data in body. // The type of data in body.
optional PayloadType type = 1; PayloadType type = 1;
// Primary contents of payload. // Primary contents of payload.
optional bytes body = 2; bytes body = 2;
} }
// A protobuf representation for grpc status. This is used by test // A protobuf representation for grpc status. This is used by test
// clients to specify a status that the server should attempt to return. // clients to specify a status that the server should attempt to return.
message EchoStatus { message EchoStatus {
optional int32 code = 1; int32 code = 1;
optional string message = 2; string message = 2;
} }
// Unary request. // Unary request.
message SimpleRequest { message SimpleRequest {
// Desired payload type in the response from the server. // Desired payload type in the response from the server.
// If response_type is RANDOM, server randomly chooses one from other formats. // If response_type is RANDOM, server randomly chooses one from other formats.
optional PayloadType response_type = 1; PayloadType response_type = 1;
// Desired payload size in the response from the server. // Desired payload size in the response from the server.
// If response_type is COMPRESSABLE, this denotes the size before compression. // If response_type is COMPRESSABLE, this denotes the size before compression.
optional int32 response_size = 2; int32 response_size = 2;
// Optional input payload sent along with the request. // Optional input payload sent along with the request.
optional Payload payload = 3; Payload payload = 3;
// Whether SimpleResponse should include username. // Whether SimpleResponse should include username.
optional bool fill_username = 4; bool fill_username = 4;
// Whether SimpleResponse should include OAuth scope. // Whether SimpleResponse should include OAuth scope.
optional bool fill_oauth_scope = 5; bool fill_oauth_scope = 5;
// Compression algorithm to be used by the server for the response (stream) // Compression algorithm to be used by the server for the response (stream)
optional CompressionType response_compression = 6; CompressionType response_compression = 6;
// Whether server should return a given status // Whether server should return a given status
optional EchoStatus response_status = 7; EchoStatus response_status = 7;
} }
// Unary response, as configured by the request. // Unary response, as configured by the request.
message SimpleResponse { message SimpleResponse {
// Payload to increase message size. // Payload to increase message size.
optional Payload payload = 1; Payload payload = 1;
// The user the request came from, for verifying authentication was // The user the request came from, for verifying authentication was
// successful when the client expected it. // successful when the client expected it.
optional string username = 2; string username = 2;
// OAuth scope. // OAuth scope.
optional string oauth_scope = 3; string oauth_scope = 3;
} }
// Client-streaming request. // Client-streaming request.
message StreamingInputCallRequest { message StreamingInputCallRequest {
// Optional input payload sent along with the request. // Optional input payload sent along with the request.
optional Payload payload = 1; Payload payload = 1;
// Not expecting any payload from the response. // Not expecting any payload from the response.
} }
@ -117,18 +117,18 @@ message StreamingInputCallRequest {
// Client-streaming response. // Client-streaming response.
message StreamingInputCallResponse { message StreamingInputCallResponse {
// Aggregated size of payloads received from the client. // Aggregated size of payloads received from the client.
optional int32 aggregated_payload_size = 1; int32 aggregated_payload_size = 1;
} }
// Configuration for a particular response. // Configuration for a particular response.
message ResponseParameters { message ResponseParameters {
// Desired payload sizes in responses from the server. // Desired payload sizes in responses from the server.
// If response_type is COMPRESSABLE, this denotes the size before compression. // If response_type is COMPRESSABLE, this denotes the size before compression.
optional int32 size = 1; int32 size = 1;
// Desired interval between consecutive responses in the response stream in // Desired interval between consecutive responses in the response stream in
// microseconds. // microseconds.
optional int32 interval_us = 2; int32 interval_us = 2;
} }
// Server-streaming request. // Server-streaming request.
@ -137,31 +137,31 @@ message StreamingOutputCallRequest {
// If response_type is RANDOM, the payload from each response in the stream // If response_type is RANDOM, the payload from each response in the stream
// might be of different types. This is to simulate a mixed type of payload // might be of different types. This is to simulate a mixed type of payload
// stream. // stream.
optional PayloadType response_type = 1; PayloadType response_type = 1;
// Configuration for each expected response message. // Configuration for each expected response message.
repeated ResponseParameters response_parameters = 2; repeated ResponseParameters response_parameters = 2;
// Optional input payload sent along with the request. // Optional input payload sent along with the request.
optional Payload payload = 3; Payload payload = 3;
// Compression algorithm to be used by the server for the response (stream) // Compression algorithm to be used by the server for the response (stream)
optional CompressionType response_compression = 6; CompressionType response_compression = 6;
// Whether server should return a given status // Whether server should return a given status
optional EchoStatus response_status = 7; EchoStatus response_status = 7;
} }
// Server-streaming response, as configured by the request and parameters. // Server-streaming response, as configured by the request and parameters.
message StreamingOutputCallResponse { message StreamingOutputCallResponse {
// Payload to increase response size. // Payload to increase response size.
optional Payload payload = 1; Payload payload = 1;
} }
// For reconnect interop test only. // For reconnect interop test only.
// Server tells client whether its reconnects are following the spec and the // Server tells client whether its reconnects are following the spec and the
// reconnect backoffs it saw. // reconnect backoffs it saw.
message ReconnectInfo { message ReconnectInfo {
optional bool passed = 1; bool passed = 1;
repeated int32 backoff_ms = 2; repeated int32 backoff_ms = 2;
} }

@ -31,7 +31,7 @@
// An integration test service that covers all the method signature permutations // An integration test service that covers all the method signature permutations
// of unary/streaming requests/responses. // of unary/streaming requests/responses.
syntax = "proto2"; syntax = "proto3";
import "test/proto/empty.proto"; import "test/proto/empty.proto";
import "test/proto/messages.proto"; import "test/proto/messages.proto";

@ -772,7 +772,6 @@ include/grpc/support/atm.h \
include/grpc/support/atm_gcc_atomic.h \ include/grpc/support/atm_gcc_atomic.h \
include/grpc/support/atm_gcc_sync.h \ include/grpc/support/atm_gcc_sync.h \
include/grpc/support/atm_win32.h \ include/grpc/support/atm_win32.h \
include/grpc/support/cancellable_platform.h \
include/grpc/support/cmdline.h \ include/grpc/support/cmdline.h \
include/grpc/support/cpu.h \ include/grpc/support/cpu.h \
include/grpc/support/histogram.h \ include/grpc/support/histogram.h \

@ -1024,7 +1024,6 @@ include/grpc/support/atm.h \
include/grpc/support/atm_gcc_atomic.h \ include/grpc/support/atm_gcc_atomic.h \
include/grpc/support/atm_gcc_sync.h \ include/grpc/support/atm_gcc_sync.h \
include/grpc/support/atm_win32.h \ include/grpc/support/atm_win32.h \
include/grpc/support/cancellable_platform.h \
include/grpc/support/cmdline.h \ include/grpc/support/cmdline.h \
include/grpc/support/cpu.h \ include/grpc/support/cpu.h \
include/grpc/support/histogram.h \ include/grpc/support/histogram.h \
@ -1055,7 +1054,6 @@ src/core/support/string.h \
src/core/support/string_win32.h \ src/core/support/string_win32.h \
src/core/support/thd_internal.h \ src/core/support/thd_internal.h \
src/core/support/alloc.c \ src/core/support/alloc.c \
src/core/support/cancellable.c \
src/core/support/cmdline.c \ src/core/support/cmdline.c \
src/core/support/cpu_iphone.c \ src/core/support/cpu_iphone.c \
src/core/support/cpu_linux.c \ src/core/support/cpu_linux.c \

@ -34,8 +34,10 @@ set -ex
cd $(dirname $0)/../.. cd $(dirname $0)/../..
ROOT=`pwd` ROOT=`pwd`
PATH=$ROOT/bins/$CONFIG:$ROOT/bins/$CONFIG/protobuf:$PATH
GRPCIO=$ROOT/src/python/grpcio GRPCIO=$ROOT/src/python/grpcio
GRPCIO_TEST=$ROOT/src/python/grpcio_test GRPCIO_TEST=$ROOT/src/python/grpcio_test
GRPCIO_HEALTH_CHECKING=$ROOT/src/python/grpcio_health_checking
make_virtualenv() { make_virtualenv() {
virtualenv_name="python"$1"_virtual_environment" virtualenv_name="python"$1"_virtual_environment"
@ -54,6 +56,9 @@ make_virtualenv() {
cd $GRPCIO_TEST cd $GRPCIO_TEST
pip install -r requirements.txt pip install -r requirements.txt
pip install $GRPCIO_TEST pip install $GRPCIO_TEST
# Install grpcio_health_checking
pip install $GRPCIO_HEALTH_CHECKING
else else
source $virtualenv_name/bin/activate source $virtualenv_name/bin/activate
# Uninstall and re-install the packages we care about. Don't use # Uninstall and re-install the packages we care about. Don't use
@ -62,12 +67,14 @@ make_virtualenv() {
# dependency upgrades. # dependency upgrades.
(yes | pip uninstall grpcio) || true (yes | pip uninstall grpcio) || true
(yes | pip uninstall grpcio_test) || true (yes | pip uninstall grpcio_test) || true
(yes | pip uninstall grpcio_health_checking) || true
(CFLAGS="-I$ROOT/include -std=c89" LDFLAGS=-L$ROOT/libs/$CONFIG GRPC_PYTHON_BUILD_WITH_CYTHON=1 pip install $GRPCIO) || ( (CFLAGS="-I$ROOT/include -std=c89" LDFLAGS=-L$ROOT/libs/$CONFIG GRPC_PYTHON_BUILD_WITH_CYTHON=1 pip install $GRPCIO) || (
# Fall back to rebuilding the entire environment # Fall back to rebuilding the entire environment
rm -rf $virtualenv_name rm -rf $virtualenv_name
make_virtualenv $1 make_virtualenv $1
) )
pip install $GRPCIO_TEST pip install $GRPCIO_TEST
pip install $GRPCIO_HEALTH_CHECKING
fi fi
} }

@ -223,18 +223,6 @@
"tools/codegen/core/gen_hpack_tables.c" "tools/codegen/core/gen_hpack_tables.c"
] ]
}, },
{
"deps": [
"gpr",
"gpr_test_util"
],
"headers": [],
"language": "c",
"name": "gpr_cancellable_test",
"src": [
"test/core/support/cancellable_test.c"
]
},
{ {
"deps": [ "deps": [
"gpr", "gpr",
@ -12087,7 +12075,6 @@
"include/grpc/support/atm_gcc_atomic.h", "include/grpc/support/atm_gcc_atomic.h",
"include/grpc/support/atm_gcc_sync.h", "include/grpc/support/atm_gcc_sync.h",
"include/grpc/support/atm_win32.h", "include/grpc/support/atm_win32.h",
"include/grpc/support/cancellable_platform.h",
"include/grpc/support/cmdline.h", "include/grpc/support/cmdline.h",
"include/grpc/support/cpu.h", "include/grpc/support/cpu.h",
"include/grpc/support/histogram.h", "include/grpc/support/histogram.h",
@ -12126,7 +12113,6 @@
"include/grpc/support/atm_gcc_atomic.h", "include/grpc/support/atm_gcc_atomic.h",
"include/grpc/support/atm_gcc_sync.h", "include/grpc/support/atm_gcc_sync.h",
"include/grpc/support/atm_win32.h", "include/grpc/support/atm_win32.h",
"include/grpc/support/cancellable_platform.h",
"include/grpc/support/cmdline.h", "include/grpc/support/cmdline.h",
"include/grpc/support/cpu.h", "include/grpc/support/cpu.h",
"include/grpc/support/histogram.h", "include/grpc/support/histogram.h",
@ -12150,7 +12136,6 @@
"include/grpc/support/tls_pthread.h", "include/grpc/support/tls_pthread.h",
"include/grpc/support/useful.h", "include/grpc/support/useful.h",
"src/core/support/alloc.c", "src/core/support/alloc.c",
"src/core/support/cancellable.c",
"src/core/support/cmdline.c", "src/core/support/cmdline.c",
"src/core/support/cpu_iphone.c", "src/core/support/cpu_iphone.c",
"src/core/support/cpu_linux.c", "src/core/support/cpu_linux.c",

@ -212,23 +212,6 @@
"posix" "posix"
] ]
}, },
{
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"flaky": false,
"language": "c",
"name": "gpr_cancellable_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
]
},
{ {
"ci_platforms": [ "ci_platforms": [
"linux", "linux",

File diff suppressed because one or more lines are too long

@ -127,7 +127,6 @@
<ClInclude Include="..\..\include\grpc\support\atm_gcc_atomic.h" /> <ClInclude Include="..\..\include\grpc\support\atm_gcc_atomic.h" />
<ClInclude Include="..\..\include\grpc\support\atm_gcc_sync.h" /> <ClInclude Include="..\..\include\grpc\support\atm_gcc_sync.h" />
<ClInclude Include="..\..\include\grpc\support\atm_win32.h" /> <ClInclude Include="..\..\include\grpc\support\atm_win32.h" />
<ClInclude Include="..\..\include\grpc\support\cancellable_platform.h" />
<ClInclude Include="..\..\include\grpc\support\cmdline.h" /> <ClInclude Include="..\..\include\grpc\support\cmdline.h" />
<ClInclude Include="..\..\include\grpc\support\cpu.h" /> <ClInclude Include="..\..\include\grpc\support\cpu.h" />
<ClInclude Include="..\..\include\grpc\support\histogram.h" /> <ClInclude Include="..\..\include\grpc\support\histogram.h" />
@ -163,8 +162,6 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\core\support\alloc.c"> <ClCompile Include="..\..\src\core\support\alloc.c">
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\core\support\cancellable.c">
</ClCompile>
<ClCompile Include="..\..\src\core\support\cmdline.c"> <ClCompile Include="..\..\src\core\support\cmdline.c">
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\core\support\cpu_iphone.c"> <ClCompile Include="..\..\src\core\support\cpu_iphone.c">

@ -4,9 +4,6 @@
<ClCompile Include="..\..\src\core\support\alloc.c"> <ClCompile Include="..\..\src\core\support\alloc.c">
<Filter>src\core\support</Filter> <Filter>src\core\support</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\core\support\cancellable.c">
<Filter>src\core\support</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\support\cmdline.c"> <ClCompile Include="..\..\src\core\support\cmdline.c">
<Filter>src\core\support</Filter> <Filter>src\core\support</Filter>
</ClCompile> </ClCompile>
@ -132,9 +129,6 @@
<ClInclude Include="..\..\include\grpc\support\atm_win32.h"> <ClInclude Include="..\..\include\grpc\support\atm_win32.h">
<Filter>include\grpc\support</Filter> <Filter>include\grpc\support</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\include\grpc\support\cancellable_platform.h">
<Filter>include\grpc\support</Filter>
</ClInclude>
<ClInclude Include="..\..\include\grpc\support\cmdline.h"> <ClInclude Include="..\..\include\grpc\support\cmdline.h">
<Filter>include\grpc\support</Filter> <Filter>include\grpc\support</Filter>
</ClInclude> </ClInclude>

Loading…
Cancel
Save