Merge remote-tracking branch 'upstream/master' into revert-9063-revert-8951-revert-8949-revert-8922-slice_cleanup

pull/9064/head
Mark D. Roth 8 years ago
commit 1311e3448c
  1. 29
      doc/cpp/perf_notes.md
  2. 4
      doc/interop-test-descriptions.md
  3. 4
      include/grpc++/grpc++.h
  4. 6
      include/grpc++/impl/codegen/completion_queue.h
  5. 5
      src/core/ext/README.md
  6. 5
      src/core/ext/client_channel/channel_connectivity.c
  7. 6
      src/core/ext/client_channel/subchannel.c
  8. 7
      src/core/ext/lb_policy/grpclb/grpclb.c
  9. 4
      src/core/ext/resolver/README.md
  10. 6
      src/core/ext/resolver/dns/native/dns_resolver.c
  11. 1
      src/core/ext/transport/README.md
  12. 1
      src/core/ext/transport/chttp2/README.md
  13. 6
      src/core/lib/README.md
  14. 4
      src/core/lib/channel/README.md
  15. 7
      src/core/lib/channel/deadline_filter.c
  16. 1
      src/core/lib/channel/deadline_filter.h
  17. 5
      src/core/lib/channel/handshaker.c
  18. 6
      src/core/lib/iomgr/README.md
  19. 4
      src/core/lib/iomgr/tcp_client_posix.c
  20. 5
      src/core/lib/iomgr/tcp_client_uv.c
  21. 4
      src/core/lib/iomgr/tcp_client_windows.c
  22. 16
      src/core/lib/iomgr/timer.h
  23. 15
      src/core/lib/iomgr/timer_generic.c
  24. 2
      src/core/lib/iomgr/timer_generic.h
  25. 13
      src/core/lib/iomgr/timer_uv.c
  26. 2
      src/core/lib/iomgr/timer_uv.h
  27. 4
      src/core/lib/surface/README.md
  28. 5
      src/core/lib/surface/alarm.c
  29. 7
      src/core/lib/transport/README.md
  30. 2
      src/core/lib/tsi/README.md
  31. 3
      src/node/interop/interop_client.js
  32. 11
      src/php/tests/interop/interop_client.php
  33. 12
      src/python/grpcio/grpc/_channel.py
  34. 16
      src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py
  35. 1
      src/python/grpcio_tests/tests/tests.json
  36. 2
      src/python/grpcio_tests/tests/unit/_compression_test.py
  37. 4
      src/python/grpcio_tests/tests/unit/_empty_message_test.py
  38. 2
      src/python/grpcio_tests/tests/unit/_exit_scenarios.py
  39. 247
      src/python/grpcio_tests/tests/unit/_invocation_defects_test.py
  40. 4
      src/python/grpcio_tests/tests/unit/_metadata_test.py
  41. 29
      templates/tools/doxygen/Doxyfile.include
  42. 18
      test/core/end2end/fuzzers/api_fuzzer.c
  43. 43
      test/core/iomgr/timer_list_test.c
  44. 30
      tools/doxygen/Doxyfile.c++
  45. 31
      tools/doxygen/Doxyfile.c++.internal
  46. 29
      tools/doxygen/Doxyfile.core
  47. 50
      tools/doxygen/Doxyfile.core.internal
  48. 4
      tools/run_tests/README.md
  49. 4
      tools/run_tests/run_interop_tests.py
  50. 2
      vsprojects/README.md
  51. 39
      vsprojects/build_vs2010.bat
  52. 4
      vsprojects/coapp/zlib/README.md

@ -0,0 +1,29 @@
# C++ Performance Notes
## Streaming write buffering
Generally, each write operation (Write(), WritesDone()) implies a syscall.
gRPC will try to batch together separate write operations from different
threads, but currently cannot automatically infer batching in a single stream.
If message k+1 in a stream does not rely on responses from message k, it's
possible to enable write batching by passing a WriteOptions argument to Write
with the buffer_hint set:
~~~{.cpp}
stream_writer->Write(message, WriteOptions().set_buffer_hint());
~~~
The write will be buffered until one of the following is true:
- the per-stream buffer is filled (controllable with the channel argument
GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE) - this prevents infinite buffering leading
to OOM
- a subsequent Write without buffer_hint set is posted
- the call is finished for writing (WritesDone() called on the client,
or Finish() called on an async server stream, or the service handler returns
for a sync server stream)
## Completion Queues and Threading in the Async API
Right now, the best performance trade-off is having numcpu's threads and one
completion queue per thread.

@ -716,7 +716,9 @@ Procedure:
```
{
response_size: 314159
response_parameters:{
size: 314159
}
payload:{
body: 271828 bytes of zeros
}

@ -44,6 +44,10 @@
/// peer, compression settings, authentication, etc.
/// - grpc::Server, representing a gRPC server, created by grpc::ServerBuilder.
///
/// Streaming calls are handled with the streaming classes in
/// \ref sync_stream.h and
/// \ref async_stream.h.
///
/// Refer to the
/// [examples](https://github.com/grpc/grpc/blob/master/examples/cpp)
/// for code putting these pieces into play.

@ -94,8 +94,10 @@ class ServerContext;
extern CoreCodegenInterface* g_core_codegen_interface;
/// A thin wrapper around \a grpc_completion_queue (see / \a
/// src/core/surface/completion_queue.h).
/// A thin wrapper around \ref grpc_completion_queue (see \ref
/// src/core/lib/surface/completion_queue.h).
/// See \ref doc/cpp/perf_notes.md for notes on best practices for high
/// performance servers.
class CompletionQueue : private GrpcLibraryCodegen {
public:
/// Default constructor. Implicitly creates a \a grpc_completion_queue

@ -0,0 +1,5 @@
Optional plugins for gRPC Core: Modules in this directory extend gRPC Core in
useful ways. All optional code belongs here.
NOTE: The movement of code between lib and ext is an ongoing effort, so this
directory currently contains too much of the core library.

@ -76,6 +76,7 @@ typedef struct {
gpr_mu mu;
callback_phase phase;
grpc_closure on_complete;
grpc_closure on_timeout;
grpc_timer alarm;
grpc_connectivity_state state;
grpc_completion_queue *cq;
@ -200,6 +201,8 @@ void grpc_channel_watch_connectivity_state(
gpr_mu_init(&w->mu);
grpc_closure_init(&w->on_complete, watch_complete, w,
grpc_schedule_on_exec_ctx);
grpc_closure_init(&w->on_timeout, timeout_complete, w,
grpc_schedule_on_exec_ctx);
w->phase = WAITING;
w->state = last_observed_state;
w->cq = cq;
@ -208,7 +211,7 @@ void grpc_channel_watch_connectivity_state(
grpc_timer_init(&exec_ctx, &w->alarm,
gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
timeout_complete, w, gpr_now(GPR_CLOCK_MONOTONIC));
&w->on_timeout, gpr_now(GPR_CLOCK_MONOTONIC));
if (client_channel_elem->filter == &grpc_client_channel_filter) {
GRPC_CHANNEL_INTERNAL_REF(channel, "watch_channel_connectivity");

@ -109,6 +109,9 @@ struct grpc_subchannel {
/** callback for connection finishing */
grpc_closure connected;
/** callback for our alarm */
grpc_closure on_alarm;
/** pollset_set tracking who's interested in a connection
being setup */
grpc_pollset_set *pollset_set;
@ -483,7 +486,8 @@ static void maybe_start_connecting_locked(grpc_exec_ctx *exec_ctx,
gpr_log(GPR_INFO, "Retry in %" PRId64 ".%09d seconds",
time_til_next.tv_sec, time_til_next.tv_nsec);
}
grpc_timer_init(exec_ctx, &c->alarm, c->next_attempt, on_alarm, c, now);
grpc_closure_init(&c->on_alarm, on_alarm, c, grpc_schedule_on_exec_ctx);
grpc_timer_init(exec_ctx, &c->alarm, c->next_attempt, &c->on_alarm, now);
}
}

@ -327,6 +327,9 @@ typedef struct glb_lb_policy {
/* A response from the LB server has been received. Process it */
grpc_closure lb_on_response_received;
/* LB call retry timer callback. */
grpc_closure lb_on_call_retry;
grpc_call *lb_call; /* streaming call to the LB server, */
grpc_metadata_array lb_initial_metadata_recv; /* initial MD from LB server */
@ -1364,8 +1367,10 @@ static void lb_on_server_status_received(grpc_exec_ctx *exec_ctx, void *arg,
}
}
GRPC_LB_POLICY_WEAK_REF(&glb_policy->base, "grpclb_retry_timer");
grpc_closure_init(&glb_policy->lb_on_call_retry, lb_call_on_retry_timer,
glb_policy, grpc_schedule_on_exec_ctx);
grpc_timer_init(exec_ctx, &glb_policy->lb_call_retry_timer, next_try,
lb_call_on_retry_timer, glb_policy, now);
&glb_policy->lb_on_call_retry, now);
}
gpr_mu_unlock(&glb_policy->mu);
GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &glb_policy->base,

@ -0,0 +1,4 @@
# Resolver
Implementations of various name resolution schemes.
See the [naming spec](/doc/naming.md).

@ -81,6 +81,7 @@ typedef struct {
/** retry timer */
bool have_retry_timer;
grpc_timer retry_timer;
grpc_closure on_retry;
/** retry backoff state */
gpr_backoff backoff_state;
@ -199,8 +200,9 @@ static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg,
} else {
gpr_log(GPR_DEBUG, "retrying immediately");
}
grpc_timer_init(exec_ctx, &r->retry_timer, next_try, dns_on_retry_timer, r,
now);
grpc_closure_init(&r->on_retry, dns_on_retry_timer, r,
grpc_schedule_on_exec_ctx);
grpc_timer_init(exec_ctx, &r->retry_timer, next_try, &r->on_retry, now);
}
if (r->resolved_result != NULL) {
grpc_channel_args_destroy(exec_ctx, r->resolved_result);

@ -0,0 +1 @@
Transports for gRPC

@ -0,0 +1 @@
CHTTP2 - gRPC's implementation of a HTTP2 based transport

@ -0,0 +1,6 @@
Required elements of gRPC Core: Each module in this directory is required to
build gRPC. If it's possible to envisage a configuration where code is not
required, then that code belongs in ext/ instead.
NOTE: The movement of code between lib and ext is an ongoing effort, so this
directory currently contains too much of the core library.

@ -0,0 +1,4 @@
# Channel
Provides channel/call stack implementation, and implementation of common filters
for that implementation.

@ -83,8 +83,11 @@ static void start_timer_if_needed_locked(grpc_exec_ctx* exec_ctx,
// Take a reference to the call stack, to be owned by the timer.
GRPC_CALL_STACK_REF(deadline_state->call_stack, "deadline_timer");
deadline_state->timer_pending = true;
grpc_timer_init(exec_ctx, &deadline_state->timer, deadline, timer_callback,
elem, gpr_now(GPR_CLOCK_MONOTONIC));
grpc_closure_init(&deadline_state->timer_callback, timer_callback, elem,
grpc_schedule_on_exec_ctx);
grpc_timer_init(exec_ctx, &deadline_state->timer, deadline,
&deadline_state->timer_callback,
gpr_now(GPR_CLOCK_MONOTONIC));
}
}
static void start_timer_if_needed(grpc_exec_ctx* exec_ctx,

@ -46,6 +46,7 @@ typedef struct grpc_deadline_state {
bool timer_pending;
// The deadline timer.
grpc_timer timer;
grpc_closure timer_callback;
// Closure to invoke when the call is complete.
// We use this to cancel the timer.
grpc_closure on_complete;

@ -86,6 +86,7 @@ struct grpc_handshake_manager {
grpc_tcp_server_acceptor* acceptor;
// Deadline timer across all handshakers.
grpc_timer deadline_timer;
grpc_closure on_timeout;
// The final callback and user_data to invoke after the last handshaker.
grpc_closure on_handshake_done;
void* user_data;
@ -224,9 +225,11 @@ void grpc_handshake_manager_do_handshake(
grpc_schedule_on_exec_ctx);
// Start deadline timer, which owns a ref.
gpr_ref(&mgr->refs);
grpc_closure_init(&mgr->on_timeout, on_timeout, mgr,
grpc_schedule_on_exec_ctx);
grpc_timer_init(exec_ctx, &mgr->deadline_timer,
gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
on_timeout, mgr, gpr_now(GPR_CLOCK_MONOTONIC));
&mgr->on_timeout, gpr_now(GPR_CLOCK_MONOTONIC));
// Start first handshaker, which also owns a ref.
gpr_ref(&mgr->refs);
bool done = call_next_handshaker_locked(exec_ctx, mgr, GRPC_ERROR_NONE);

@ -0,0 +1,6 @@
# iomgr
Platform abstractions for I/O (mostly network).
Provides abstractions over TCP/UDP I/O, file loading, polling, and concurrency
management for various operating systems.

@ -65,6 +65,7 @@ typedef struct {
grpc_fd *fd;
gpr_timespec deadline;
grpc_timer alarm;
grpc_closure on_alarm;
int refs;
grpc_closure write_closure;
grpc_pollset_set *interested_parties;
@ -352,9 +353,10 @@ static void tcp_client_connect_impl(grpc_exec_ctx *exec_ctx,
}
gpr_mu_lock(&ac->mu);
grpc_closure_init(&ac->on_alarm, tc_on_alarm, ac, grpc_schedule_on_exec_ctx);
grpc_timer_init(exec_ctx, &ac->alarm,
gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
tc_on_alarm, ac, gpr_now(GPR_CLOCK_MONOTONIC));
&ac->on_alarm, gpr_now(GPR_CLOCK_MONOTONIC));
grpc_fd_notify_on_write(exec_ctx, ac->fd, &ac->write_closure);
gpr_mu_unlock(&ac->mu);

@ -49,6 +49,7 @@
typedef struct grpc_uv_tcp_connect {
uv_connect_t connect_req;
grpc_timer alarm;
grpc_closure on_alarm;
uv_tcp_t *tcp_handle;
grpc_closure *closure;
grpc_endpoint **endpoint;
@ -148,9 +149,11 @@ static void tcp_client_connect_impl(grpc_exec_ctx *exec_ctx,
uv_tcp_connect(&connect->connect_req, connect->tcp_handle,
(const struct sockaddr *)resolved_addr->addr,
uv_tc_on_connect);
grpc_closure_init(&connect->on_alarm, uv_tc_on_alarm, connect,
grpc_schedule_on_exec_ctx);
grpc_timer_init(exec_ctx, &connect->alarm,
gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
uv_tc_on_alarm, connect, gpr_now(GPR_CLOCK_MONOTONIC));
&connect->on_alarm, gpr_now(GPR_CLOCK_MONOTONIC));
}
// overridden by api_fuzzer.c

@ -58,6 +58,7 @@ typedef struct {
grpc_winsocket *socket;
gpr_timespec deadline;
grpc_timer alarm;
grpc_closure on_alarm;
char *addr_name;
int refs;
grpc_closure on_connect;
@ -229,7 +230,8 @@ void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *on_done,
ac->resource_quota = resource_quota;
grpc_closure_init(&ac->on_connect, on_connect, ac, grpc_schedule_on_exec_ctx);
grpc_timer_init(exec_ctx, &ac->alarm, deadline, on_alarm, ac,
grpc_closure_init(&ac->on_alarm, on_alarm, ac, grpc_schedule_on_exec_ctx);
grpc_timer_init(exec_ctx, &ac->alarm, deadline, &ac->on_alarm,
gpr_now(GPR_CLOCK_MONOTONIC));
grpc_socket_notify_on_write(exec_ctx, socket, &ac->on_connect);
return;

@ -49,15 +49,15 @@
typedef struct grpc_timer grpc_timer;
/* Initialize *timer. When expired or canceled, timer_cb will be called with
*timer_cb_arg and error set to indicate if it expired (GRPC_ERROR_NONE) or
was canceled (GRPC_ERROR_CANCELLED). timer_cb is guaranteed to be called
exactly once, and application code should check the error to determine
how it was invoked. The application callback is also responsible for
maintaining information about when to free up any user-level state. */
/* Initialize *timer. When expired or canceled, closure will be called with
error set to indicate if it expired (GRPC_ERROR_NONE) or was canceled
(GRPC_ERROR_CANCELLED). timer_cb is guaranteed to be called exactly once, and
application code should check the error to determine how it was invoked. The
application callback is also responsible for maintaining information about
when to free up any user-level state. */
void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer,
gpr_timespec deadline, grpc_iomgr_cb_func timer_cb,
void *timer_cb_arg, gpr_timespec now);
gpr_timespec deadline, grpc_closure *closure,
gpr_timespec now);
/* Note that there is no timer destroy function. This is because the
timer is a one-time occurrence with a guarantee that the callback will

@ -178,28 +178,27 @@ static void note_deadline_change(shard_type *shard) {
}
void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer,
gpr_timespec deadline, grpc_iomgr_cb_func timer_cb,
void *timer_cb_arg, gpr_timespec now) {
gpr_timespec deadline, grpc_closure *closure,
gpr_timespec now) {
int is_first_timer = 0;
shard_type *shard = &g_shards[shard_idx(timer)];
GPR_ASSERT(deadline.clock_type == g_clock_type);
GPR_ASSERT(now.clock_type == g_clock_type);
grpc_closure_init(&timer->closure, timer_cb, timer_cb_arg,
grpc_schedule_on_exec_ctx);
timer->closure = closure;
timer->deadline = deadline;
timer->triggered = 0;
if (!g_initialized) {
timer->triggered = 1;
grpc_closure_sched(
exec_ctx, &timer->closure,
exec_ctx, timer->closure,
GRPC_ERROR_CREATE("Attempt to create timer before initialization"));
return;
}
if (gpr_time_cmp(deadline, now) <= 0) {
timer->triggered = 1;
grpc_closure_sched(exec_ctx, &timer->closure, GRPC_ERROR_NONE);
grpc_closure_sched(exec_ctx, timer->closure, GRPC_ERROR_NONE);
return;
}
@ -251,7 +250,7 @@ void grpc_timer_cancel(grpc_exec_ctx *exec_ctx, grpc_timer *timer) {
shard_type *shard = &g_shards[shard_idx(timer)];
gpr_mu_lock(&shard->mu);
if (!timer->triggered) {
grpc_closure_sched(exec_ctx, &timer->closure, GRPC_ERROR_CANCELLED);
grpc_closure_sched(exec_ctx, timer->closure, GRPC_ERROR_CANCELLED);
timer->triggered = 1;
if (timer->heap_index == INVALID_HEAP_INDEX) {
list_remove(timer);
@ -317,7 +316,7 @@ static size_t pop_timers(grpc_exec_ctx *exec_ctx, shard_type *shard,
grpc_timer *timer;
gpr_mu_lock(&shard->mu);
while ((timer = pop_one(shard, now))) {
grpc_closure_sched(exec_ctx, &timer->closure, GRPC_ERROR_REF(error));
grpc_closure_sched(exec_ctx, timer->closure, GRPC_ERROR_REF(error));
n++;
}
*new_min_deadline = compute_min_deadline(shard);

@ -43,7 +43,7 @@ struct grpc_timer {
int triggered;
struct grpc_timer *next;
struct grpc_timer *prev;
grpc_closure closure;
grpc_closure *closure;
};
#endif /* GRPC_CORE_LIB_IOMGR_TIMER_GENERIC_H */

@ -55,21 +55,20 @@ void run_expired_timer(uv_timer_t *handle) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
GPR_ASSERT(!timer->triggered);
timer->triggered = 1;
grpc_closure_sched(&exec_ctx, &timer->closure, GRPC_ERROR_NONE);
grpc_closure_sched(&exec_ctx, timer->closure, GRPC_ERROR_NONE);
stop_uv_timer(handle);
grpc_exec_ctx_finish(&exec_ctx);
}
void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer,
gpr_timespec deadline, grpc_iomgr_cb_func timer_cb,
void *timer_cb_arg, gpr_timespec now) {
gpr_timespec deadline, grpc_closure *closure,
gpr_timespec now) {
uint64_t timeout;
uv_timer_t *uv_timer;
grpc_closure_init(&timer->closure, timer_cb, timer_cb_arg,
grpc_schedule_on_exec_ctx);
timer->closure = closure;
if (gpr_time_cmp(deadline, now) <= 0) {
timer->triggered = 1;
grpc_closure_sched(exec_ctx, &timer->closure, GRPC_ERROR_NONE);
grpc_closure_sched(exec_ctx, timer->closure, GRPC_ERROR_NONE);
return;
}
timer->triggered = 0;
@ -84,7 +83,7 @@ void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer,
void grpc_timer_cancel(grpc_exec_ctx *exec_ctx, grpc_timer *timer) {
if (!timer->triggered) {
timer->triggered = 1;
grpc_closure_sched(exec_ctx, &timer->closure, GRPC_ERROR_CANCELLED);
grpc_closure_sched(exec_ctx, timer->closure, GRPC_ERROR_CANCELLED);
stop_uv_timer((uv_timer_t *)timer->uv_timer);
}
}

@ -37,7 +37,7 @@
#include "src/core/lib/iomgr/exec_ctx.h"
struct grpc_timer {
grpc_closure closure;
grpc_closure *closure;
/* This is actually a uv_timer_t*, but we want to keep platform-specific
types out of headers */
void *uv_timer;

@ -0,0 +1,4 @@
# Surface
Surface provides the bulk of the gRPC Core public API, and translates it into
calls against core components.

@ -38,6 +38,7 @@
struct grpc_alarm {
grpc_timer alarm;
grpc_closure on_alarm;
grpc_cq_completion completion;
/** completion queue where events about this alarm will be posted */
grpc_completion_queue *cq;
@ -64,9 +65,11 @@ grpc_alarm *grpc_alarm_create(grpc_completion_queue *cq, gpr_timespec deadline,
alarm->tag = tag;
grpc_cq_begin_op(cq, tag);
grpc_closure_init(&alarm->on_alarm, alarm_cb, alarm,
grpc_schedule_on_exec_ctx);
grpc_timer_init(&exec_ctx, &alarm->alarm,
gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
alarm_cb, alarm, gpr_now(GPR_CLOCK_MONOTONIC));
&alarm->on_alarm, gpr_now(GPR_CLOCK_MONOTONIC));
grpc_exec_ctx_finish(&exec_ctx);
return alarm;
}

@ -0,0 +1,7 @@
# Transport
Common implementation details for gRPC Transports.
Transports multiplex messages across some single connection. In ext/ there are
implementations atop [a custom http2 implementation](/src/core/ext/transport/chttp2/README.md)
and atop [cronet](/src/core/ext/transport/cronet/README.md).

@ -0,0 +1,2 @@
# Transport Security Interface
An abstraction library over crypto and auth modules (typically OpenSSL)

@ -312,6 +312,9 @@ function customMetadata(client, done) {
}
};
var streaming_arg = {
response_parameters: [
{size: 314159}
],
payload: {
body: zeroBuffer(271828)
}

@ -451,11 +451,22 @@ function customMetadata($stub)
$streaming_request = new grpc\testing\StreamingOutputCallRequest();
$streaming_request->setPayload($payload);
$response_parameters = new grpc\testing\ResponseParameters();
$response_parameters->setSize($response_len);
$streaming_request->getResponseParameters()[] = $response_parameters;
$streaming_call->write($streaming_request);
$streaming_call->writesDone();
$result = $streaming_call->read();
hardAssertIfStatusOk($streaming_call->getStatus());
$streaming_initial_metadata = $streaming_call->getMetadata();
hardAssert(array_key_exists($ECHO_INITIAL_KEY, $streaming_initial_metadata),
'Initial metadata does not contain expected key');
hardAssert(
$streaming_initial_metadata[$ECHO_INITIAL_KEY][0] === $ECHO_INITIAL_VALUE,
'Incorrect initial metadata value');
$streaming_trailing_metadata = $streaming_call->getTrailingMetadata();
hardAssert(array_key_exists($ECHO_TRAILING_KEY,
$streaming_trailing_metadata),

@ -32,6 +32,7 @@
import sys
import threading
import time
import logging
import grpc
from grpc import _common
@ -197,7 +198,16 @@ def _consume_request_iterator(
event_handler = _event_handler(state, call, None)
def consume_request_iterator():
for request in request_iterator:
while True:
try:
request = next(request_iterator)
except StopIteration:
break
except Exception as e:
logging.exception("Exception iterating requests!")
call.cancel()
_abort(state, grpc.StatusCode.UNKNOWN, "Exception iterating requests!")
return
serialized_request = _common.serialize(request, request_serializer)
with state.condition:
if state.code is None and not state.cancelled:

@ -75,7 +75,7 @@ class ReflectionServicerTest(unittest.TestCase):
file_by_filename='i-donut-exist'
),
)
responses = tuple(self._stub.ServerReflectionInfo(requests))
responses = tuple(self._stub.ServerReflectionInfo(iter(requests)))
expected_responses = (
reflection_pb2.ServerReflectionResponse(
valid_host='',
@ -93,7 +93,7 @@ class ReflectionServicerTest(unittest.TestCase):
)
),
)
self.assertEqual(expected_responses, responses)
self.assertSequenceEqual(expected_responses, responses)
def testFileBySymbol(self):
requests = (
@ -104,7 +104,7 @@ class ReflectionServicerTest(unittest.TestCase):
file_containing_symbol='i.donut.exist.co.uk.org.net.me.name.foo'
),
)
responses = tuple(self._stub.ServerReflectionInfo(requests))
responses = tuple(self._stub.ServerReflectionInfo(iter(requests)))
expected_responses = (
reflection_pb2.ServerReflectionResponse(
valid_host='',
@ -122,7 +122,7 @@ class ReflectionServicerTest(unittest.TestCase):
)
),
)
self.assertEqual(expected_responses, responses)
self.assertSequenceEqual(expected_responses, responses)
@unittest.skip('TODO(atash): implement file-containing-extension reflection '
'(see https://github.com/google/protobuf/issues/2248)')
@ -141,7 +141,7 @@ class ReflectionServicerTest(unittest.TestCase):
),
),
)
responses = tuple(self._stub.ServerReflectionInfo(requests))
responses = tuple(self._stub.ServerReflectionInfo(iter(requests)))
expected_responses = (
reflection_pb2.ServerReflectionResponse(
valid_host='',
@ -159,7 +159,7 @@ class ReflectionServicerTest(unittest.TestCase):
)
),
)
self.assertEqual(expected_responses, responses)
self.assertSequenceEqual(expected_responses, responses)
def testListServices(self):
requests = (
@ -167,7 +167,7 @@ class ReflectionServicerTest(unittest.TestCase):
list_services='',
),
)
responses = tuple(self._stub.ServerReflectionInfo(requests))
responses = tuple(self._stub.ServerReflectionInfo(iter(requests)))
expected_responses = (
reflection_pb2.ServerReflectionResponse(
valid_host='',
@ -179,7 +179,7 @@ class ReflectionServicerTest(unittest.TestCase):
)
),
)
self.assertEqual(expected_responses, responses)
self.assertSequenceEqual(expected_responses, responses)
if __name__ == '__main__':
unittest.main(verbosity=2)

@ -28,6 +28,7 @@
"unit._empty_message_test.EmptyMessageTest",
"unit._exit_test.ExitTest",
"unit._invalid_metadata_test.InvalidMetadataTest",
"unit._invocation_defects_test.InvocationDefectsTest",
"unit._metadata_code_details_test.MetadataCodeDetailsTest",
"unit._metadata_test.MetadataTest",
"unit._rpc_test.RPCTest",

@ -125,7 +125,7 @@ class CompressionTest(unittest.TestCase):
compressed_channel = grpc.insecure_channel('localhost:%d' % self._port,
options=[('grpc.default_compression_algorithm', 1)])
multi_callable = compressed_channel.stream_stream(_STREAM_STREAM)
call = multi_callable([request] * test_constants.STREAM_LENGTH)
call = multi_callable(iter([request] * test_constants.STREAM_LENGTH))
for response in call:
self.assertEqual(request, response)

@ -123,12 +123,12 @@ class EmptyMessageTest(unittest.TestCase):
def testStreamUnary(self):
response = self._channel.stream_unary(_STREAM_UNARY)(
[_REQUEST] * test_constants.STREAM_LENGTH)
iter([_REQUEST] * test_constants.STREAM_LENGTH))
self.assertEqual(_RESPONSE, response)
def testStreamStream(self):
response_iterator = self._channel.stream_stream(_STREAM_STREAM)(
[_REQUEST] * test_constants.STREAM_LENGTH)
iter([_REQUEST] * test_constants.STREAM_LENGTH))
self.assertSequenceEqual(
[_RESPONSE] * test_constants.STREAM_LENGTH, list(response_iterator))

@ -240,7 +240,7 @@ if __name__ == '__main__':
multi_callable = channel.stream_unary(method)
future = multi_callable.future(infinite_request_iterator())
result, call = multi_callable.with_call(
[REQUEST] * test_constants.STREAM_LENGTH)
iter([REQUEST] * test_constants.STREAM_LENGTH))
elif (args.scenario == IN_FLIGHT_STREAM_STREAM_CALL or
args.scenario == IN_FLIGHT_PARTIAL_STREAM_STREAM_CALL):
multi_callable = channel.stream_stream(method)

@ -0,0 +1,247 @@
# Copyright 2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import itertools
import threading
import unittest
from concurrent import futures
import grpc
from grpc.framework.foundation import logging_pool
from tests.unit.framework.common import test_constants
from tests.unit.framework.common import test_control
_SERIALIZE_REQUEST = lambda bytestring: bytestring * 2
_DESERIALIZE_REQUEST = lambda bytestring: bytestring[len(bytestring) // 2:]
_SERIALIZE_RESPONSE = lambda bytestring: bytestring * 3
_DESERIALIZE_RESPONSE = lambda bytestring: bytestring[:len(bytestring) // 3]
_UNARY_UNARY = '/test/UnaryUnary'
_UNARY_STREAM = '/test/UnaryStream'
_STREAM_UNARY = '/test/StreamUnary'
_STREAM_STREAM = '/test/StreamStream'
class _Callback(object):
def __init__(self):
self._condition = threading.Condition()
self._value = None
self._called = False
def __call__(self, value):
with self._condition:
self._value = value
self._called = True
self._condition.notify_all()
def value(self):
with self._condition:
while not self._called:
self._condition.wait()
return self._value
class _Handler(object):
def __init__(self, control):
self._control = control
def handle_unary_unary(self, request, servicer_context):
self._control.control()
if servicer_context is not None:
servicer_context.set_trailing_metadata((('testkey', 'testvalue',),))
return request
def handle_unary_stream(self, request, servicer_context):
for _ in range(test_constants.STREAM_LENGTH):
self._control.control()
yield request
self._control.control()
if servicer_context is not None:
servicer_context.set_trailing_metadata((('testkey', 'testvalue',),))
def handle_stream_unary(self, request_iterator, servicer_context):
if servicer_context is not None:
servicer_context.invocation_metadata()
self._control.control()
response_elements = []
for request in request_iterator:
self._control.control()
response_elements.append(request)
self._control.control()
if servicer_context is not None:
servicer_context.set_trailing_metadata((('testkey', 'testvalue',),))
return b''.join(response_elements)
def handle_stream_stream(self, request_iterator, servicer_context):
self._control.control()
if servicer_context is not None:
servicer_context.set_trailing_metadata((('testkey', 'testvalue',),))
for request in request_iterator:
self._control.control()
yield request
self._control.control()
class _MethodHandler(grpc.RpcMethodHandler):
def __init__(
self, request_streaming, response_streaming, request_deserializer,
response_serializer, unary_unary, unary_stream, stream_unary,
stream_stream):
self.request_streaming = request_streaming
self.response_streaming = response_streaming
self.request_deserializer = request_deserializer
self.response_serializer = response_serializer
self.unary_unary = unary_unary
self.unary_stream = unary_stream
self.stream_unary = stream_unary
self.stream_stream = stream_stream
class _GenericHandler(grpc.GenericRpcHandler):
def __init__(self, handler):
self._handler = handler
def service(self, handler_call_details):
if handler_call_details.method == _UNARY_UNARY:
return _MethodHandler(
False, False, None, None, self._handler.handle_unary_unary, None,
None, None)
elif handler_call_details.method == _UNARY_STREAM:
return _MethodHandler(
False, True, _DESERIALIZE_REQUEST, _SERIALIZE_RESPONSE, None,
self._handler.handle_unary_stream, None, None)
elif handler_call_details.method == _STREAM_UNARY:
return _MethodHandler(
True, False, _DESERIALIZE_REQUEST, _SERIALIZE_RESPONSE, None, None,
self._handler.handle_stream_unary, None)
elif handler_call_details.method == _STREAM_STREAM:
return _MethodHandler(
True, True, None, None, None, None, None,
self._handler.handle_stream_stream)
else:
return None
class FailAfterFewIterationsCounter(object):
def __init__(self, high, bytestring):
self._current = 0
self._high = high
self._bytestring = bytestring
def __iter__(self):
return self
def __next__(self):
if self._current >= self._high:
raise Exception("This is a deliberate failure in a unit test.")
else:
self._current += 1
return self._bytestring
def _unary_unary_multi_callable(channel):
return channel.unary_unary(_UNARY_UNARY)
def _unary_stream_multi_callable(channel):
return channel.unary_stream(
_UNARY_STREAM,
request_serializer=_SERIALIZE_REQUEST,
response_deserializer=_DESERIALIZE_RESPONSE)
def _stream_unary_multi_callable(channel):
return channel.stream_unary(
_STREAM_UNARY,
request_serializer=_SERIALIZE_REQUEST,
response_deserializer=_DESERIALIZE_RESPONSE)
def _stream_stream_multi_callable(channel):
return channel.stream_stream(_STREAM_STREAM)
class InvocationDefectsTest(unittest.TestCase):
def setUp(self):
self._control = test_control.PauseFailControl()
self._handler = _Handler(self._control)
self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
self._server = grpc.server(self._server_pool)
port = self._server.add_insecure_port('[::]:0')
self._server.add_generic_rpc_handlers((_GenericHandler(self._handler),))
self._server.start()
self._channel = grpc.insecure_channel('localhost:%d' % port)
def tearDown(self):
self._server.stop(0)
def testIterableStreamRequestBlockingUnaryResponse(self):
requests = [b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH)]
multi_callable = _stream_unary_multi_callable(self._channel)
with self.assertRaises(grpc.RpcError):
response = multi_callable(
requests,
metadata=(('test', 'IterableStreamRequestBlockingUnaryResponse'),))
def testIterableStreamRequestFutureUnaryResponse(self):
requests = [b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH)]
multi_callable = _stream_unary_multi_callable(self._channel)
response_future = multi_callable.future(
requests,
metadata=(
('test', 'IterableStreamRequestFutureUnaryResponse'),))
with self.assertRaises(grpc.RpcError):
response = response_future.result()
def testIterableStreamRequestStreamResponse(self):
requests = [b'\x77\x58' for _ in range(test_constants.STREAM_LENGTH)]
multi_callable = _stream_stream_multi_callable(self._channel)
response_iterator = multi_callable(
requests,
metadata=(('test', 'IterableStreamRequestStreamResponse'),))
with self.assertRaises(grpc.RpcError):
next(response_iterator)
def testIteratorStreamRequestStreamResponse(self):
requests_iterator = FailAfterFewIterationsCounter(
test_constants.STREAM_LENGTH // 2, b'\x07\x08')
multi_callable = _stream_stream_multi_callable(self._channel)
response_iterator = multi_callable(
requests_iterator,
metadata=(('test', 'IteratorStreamRequestStreamResponse'),))
with self.assertRaises(grpc.RpcError):
for _ in range(test_constants.STREAM_LENGTH // 2 + 1):
next(response_iterator)

@ -193,7 +193,7 @@ class MetadataTest(unittest.TestCase):
def testStreamUnary(self):
multi_callable = self._channel.stream_unary(_STREAM_UNARY)
unused_response, call = multi_callable.with_call(
[_REQUEST] * test_constants.STREAM_LENGTH,
iter([_REQUEST] * test_constants.STREAM_LENGTH),
metadata=_CLIENT_METADATA)
self.assertTrue(test_common.metadata_transmitted(
_SERVER_INITIAL_METADATA, call.initial_metadata()))
@ -202,7 +202,7 @@ class MetadataTest(unittest.TestCase):
def testStreamStream(self):
multi_callable = self._channel.stream_stream(_STREAM_STREAM)
call = multi_callable([_REQUEST] * test_constants.STREAM_LENGTH,
call = multi_callable(iter([_REQUEST] * test_constants.STREAM_LENGTH),
metadata=_CLIENT_METADATA)
self.assertTrue(test_common.metadata_transmitted(
_SERVER_INITIAL_METADATA, call.initial_metadata()))

@ -8,7 +8,10 @@
<%def name="gen_doxyfile(libnames, packagename, collection, internal)">
<%
import itertools
import glob
import os
targets = []
docpackage = packagename.replace('+', 'p').lower()
for libname in libnames:
target = None
for p in collection:
@ -16,6 +19,11 @@
target = p
assert(target)
targets.append(target)
srcdoc = []
for dirpath, dirnames, filenames in os.walk('src/%s' % docpackage):
for filename in filenames:
if os.path.splitext(filename)[1] == '.md':
srcdoc.append(os.path.join(dirpath, filename))
%>
# Doxyfile 1.8.9.1
@ -778,13 +786,20 @@ WARN_LOGFILE =
# spaces.
# Note: If this tag is empty the current directory is searched.
INPUT = ${' \\\n'.join(
itertools.chain.from_iterable(
target.public_headers +
([]
if not internal
else target.headers + target.src)
for target in targets))}
INPUT = ${
' \\\n'.join(
itertools.chain(
itertools.chain.from_iterable(
target.public_headers +
([]
if not internal
else target.headers + target.src)
for target in targets),
glob.glob('doc/*.md'),
glob.glob('doc/%s/*.md' % docpackage),
[] if not internal else srcdoc)
)
}
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses

@ -369,10 +369,11 @@ void my_resolve_address(grpc_exec_ctx *exec_ctx, const char *addr,
r->addr = gpr_strdup(addr);
r->on_done = on_done;
r->addrs = addresses;
grpc_timer_init(exec_ctx, &r->timer,
gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
gpr_time_from_seconds(1, GPR_TIMESPAN)),
finish_resolve, r, gpr_now(GPR_CLOCK_MONOTONIC));
grpc_timer_init(
exec_ctx, &r->timer, gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
gpr_time_from_seconds(1, GPR_TIMESPAN)),
grpc_closure_create(finish_resolve, r, grpc_schedule_on_exec_ctx),
gpr_now(GPR_CLOCK_MONOTONIC));
}
////////////////////////////////////////////////////////////////////////////////
@ -430,10 +431,11 @@ static void sched_connect(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
fc->closure = closure;
fc->ep = ep;
fc->deadline = deadline;
grpc_timer_init(exec_ctx, &fc->timer,
gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
gpr_time_from_millis(1, GPR_TIMESPAN)),
do_connect, fc, gpr_now(GPR_CLOCK_MONOTONIC));
grpc_timer_init(
exec_ctx, &fc->timer, gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
gpr_time_from_millis(1, GPR_TIMESPAN)),
grpc_closure_create(do_connect, fc, grpc_schedule_on_exec_ctx),
gpr_now(GPR_CLOCK_MONOTONIC));
}
static void my_tcp_client_connect(grpc_exec_ctx *exec_ctx,

@ -57,17 +57,20 @@ static void add_test(void) {
/* 10 ms timers. will expire in the current epoch */
for (i = 0; i < 10; i++) {
grpc_timer_init(&exec_ctx, &timers[i],
gpr_time_add(start, gpr_time_from_millis(10, GPR_TIMESPAN)),
cb, (void *)(intptr_t)i, start);
grpc_timer_init(
&exec_ctx, &timers[i],
gpr_time_add(start, gpr_time_from_millis(10, GPR_TIMESPAN)),
grpc_closure_create(cb, (void *)(intptr_t)i, grpc_schedule_on_exec_ctx),
start);
}
/* 1010 ms timers. will expire in the next epoch */
for (i = 10; i < 20; i++) {
grpc_timer_init(
&exec_ctx, &timers[i],
gpr_time_add(start, gpr_time_from_millis(1010, GPR_TIMESPAN)), cb,
(void *)(intptr_t)i, start);
gpr_time_add(start, gpr_time_from_millis(1010, GPR_TIMESPAN)),
grpc_closure_create(cb, (void *)(intptr_t)i, grpc_schedule_on_exec_ctx),
start);
}
/* collect timers. Only the first batch should be ready. */
@ -125,16 +128,26 @@ void destruction_test(void) {
grpc_timer_list_init(gpr_time_0(GPR_CLOCK_REALTIME));
memset(cb_called, 0, sizeof(cb_called));
grpc_timer_init(&exec_ctx, &timers[0], tfm(100), cb, (void *)(intptr_t)0,
gpr_time_0(GPR_CLOCK_REALTIME));
grpc_timer_init(&exec_ctx, &timers[1], tfm(3), cb, (void *)(intptr_t)1,
gpr_time_0(GPR_CLOCK_REALTIME));
grpc_timer_init(&exec_ctx, &timers[2], tfm(100), cb, (void *)(intptr_t)2,
gpr_time_0(GPR_CLOCK_REALTIME));
grpc_timer_init(&exec_ctx, &timers[3], tfm(3), cb, (void *)(intptr_t)3,
gpr_time_0(GPR_CLOCK_REALTIME));
grpc_timer_init(&exec_ctx, &timers[4], tfm(1), cb, (void *)(intptr_t)4,
gpr_time_0(GPR_CLOCK_REALTIME));
grpc_timer_init(
&exec_ctx, &timers[0], tfm(100),
grpc_closure_create(cb, (void *)(intptr_t)0, grpc_schedule_on_exec_ctx),
gpr_time_0(GPR_CLOCK_REALTIME));
grpc_timer_init(
&exec_ctx, &timers[1], tfm(3),
grpc_closure_create(cb, (void *)(intptr_t)1, grpc_schedule_on_exec_ctx),
gpr_time_0(GPR_CLOCK_REALTIME));
grpc_timer_init(
&exec_ctx, &timers[2], tfm(100),
grpc_closure_create(cb, (void *)(intptr_t)2, grpc_schedule_on_exec_ctx),
gpr_time_0(GPR_CLOCK_REALTIME));
grpc_timer_init(
&exec_ctx, &timers[3], tfm(3),
grpc_closure_create(cb, (void *)(intptr_t)3, grpc_schedule_on_exec_ctx),
gpr_time_0(GPR_CLOCK_REALTIME));
grpc_timer_init(
&exec_ctx, &timers[4], tfm(1),
grpc_closure_create(cb, (void *)(intptr_t)4, grpc_schedule_on_exec_ctx),
gpr_time_0(GPR_CLOCK_REALTIME));
GPR_ASSERT(1 == grpc_timer_check(&exec_ctx, tfm(2), NULL));
grpc_exec_ctx_finish(&exec_ctx);
GPR_ASSERT(1 == cb_called[4][1]);

@ -848,7 +848,35 @@ include/grpc/impl/codegen/slice.h \
include/grpc/impl/codegen/sync.h \
include/grpc/impl/codegen/sync_generic.h \
include/grpc/impl/codegen/sync_posix.h \
include/grpc/impl/codegen/sync_windows.h
include/grpc/impl/codegen/sync_windows.h \
doc/fail_fast.md \
doc/compression.md \
doc/environment_variables.md \
doc/stress_test_framework.md \
doc/PROTOCOL-WEB.md \
doc/cpp-style-guide.md \
doc/http-grpc-status-mapping.md \
doc/wait-for-ready.md \
doc/command_line_tool.md \
doc/c-style-guide.md \
doc/server_reflection_tutorial.md \
doc/health-checking.md \
doc/connection-backoff-interop-test-description.md \
doc/epoll-polling-engine.md \
doc/naming.md \
doc/binary-logging.md \
doc/connectivity-semantics-and-api.md \
doc/connection-backoff.md \
doc/compression_cookbook.md \
doc/PROTOCOL-HTTP2.md \
doc/load-balancing.md \
doc/negative-http2-interop-test-descriptions.md \
doc/server-reflection.md \
doc/interop-test-descriptions.md \
doc/statuscodes.md \
doc/g_stands_for.md \
doc/cpp/perf_notes.md \
doc/cpp/pending_api_cleanups.md
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses

@ -894,7 +894,36 @@ src/cpp/util/slice_cc.cc \
src/cpp/util/status.cc \
src/cpp/util/string_ref.cc \
src/cpp/util/time_cc.cc \
src/cpp/codegen/codegen_init.cc
src/cpp/codegen/codegen_init.cc \
doc/fail_fast.md \
doc/compression.md \
doc/environment_variables.md \
doc/stress_test_framework.md \
doc/PROTOCOL-WEB.md \
doc/cpp-style-guide.md \
doc/http-grpc-status-mapping.md \
doc/wait-for-ready.md \
doc/command_line_tool.md \
doc/c-style-guide.md \
doc/server_reflection_tutorial.md \
doc/health-checking.md \
doc/connection-backoff-interop-test-description.md \
doc/epoll-polling-engine.md \
doc/naming.md \
doc/binary-logging.md \
doc/connectivity-semantics-and-api.md \
doc/connection-backoff.md \
doc/compression_cookbook.md \
doc/PROTOCOL-HTTP2.md \
doc/load-balancing.md \
doc/negative-http2-interop-test-descriptions.md \
doc/server-reflection.md \
doc/interop-test-descriptions.md \
doc/statuscodes.md \
doc/g_stands_for.md \
doc/cpp/perf_notes.md \
doc/cpp/pending_api_cleanups.md \
src/cpp/README.md
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses

@ -827,7 +827,34 @@ include/grpc/impl/codegen/slice.h \
include/grpc/impl/codegen/sync.h \
include/grpc/impl/codegen/sync_generic.h \
include/grpc/impl/codegen/sync_posix.h \
include/grpc/impl/codegen/sync_windows.h
include/grpc/impl/codegen/sync_windows.h \
doc/fail_fast.md \
doc/compression.md \
doc/environment_variables.md \
doc/stress_test_framework.md \
doc/PROTOCOL-WEB.md \
doc/cpp-style-guide.md \
doc/http-grpc-status-mapping.md \
doc/wait-for-ready.md \
doc/command_line_tool.md \
doc/c-style-guide.md \
doc/server_reflection_tutorial.md \
doc/health-checking.md \
doc/connection-backoff-interop-test-description.md \
doc/epoll-polling-engine.md \
doc/naming.md \
doc/binary-logging.md \
doc/connectivity-semantics-and-api.md \
doc/connection-backoff.md \
doc/compression_cookbook.md \
doc/PROTOCOL-HTTP2.md \
doc/load-balancing.md \
doc/negative-http2-interop-test-descriptions.md \
doc/server-reflection.md \
doc/interop-test-descriptions.md \
doc/statuscodes.md \
doc/g_stands_for.md \
doc/core/pending_api_cleanups.md
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses

@ -1278,7 +1278,55 @@ src/core/lib/support/tls_pthread.c \
src/core/lib/support/tmpfile_msys.c \
src/core/lib/support/tmpfile_posix.c \
src/core/lib/support/tmpfile_windows.c \
src/core/lib/support/wrap_memcpy.c
src/core/lib/support/wrap_memcpy.c \
doc/fail_fast.md \
doc/compression.md \
doc/environment_variables.md \
doc/stress_test_framework.md \
doc/PROTOCOL-WEB.md \
doc/cpp-style-guide.md \
doc/http-grpc-status-mapping.md \
doc/wait-for-ready.md \
doc/command_line_tool.md \
doc/c-style-guide.md \
doc/server_reflection_tutorial.md \
doc/health-checking.md \
doc/connection-backoff-interop-test-description.md \
doc/epoll-polling-engine.md \
doc/naming.md \
doc/binary-logging.md \
doc/connectivity-semantics-and-api.md \
doc/connection-backoff.md \
doc/compression_cookbook.md \
doc/PROTOCOL-HTTP2.md \
doc/load-balancing.md \
doc/negative-http2-interop-test-descriptions.md \
doc/server-reflection.md \
doc/interop-test-descriptions.md \
doc/statuscodes.md \
doc/g_stands_for.md \
doc/core/pending_api_cleanups.md \
src/core/README.md \
src/core/ext/README.md \
src/core/ext/transport/README.md \
src/core/ext/transport/chttp2/README.md \
src/core/ext/transport/chttp2/client/secure/README.md \
src/core/ext/transport/chttp2/client/insecure/README.md \
src/core/ext/transport/chttp2/transport/README.md \
src/core/ext/transport/chttp2/server/secure/README.md \
src/core/ext/transport/chttp2/server/insecure/README.md \
src/core/ext/client_channel/README.md \
src/core/ext/resolver/README.md \
src/core/ext/resolver/sockaddr/README.md \
src/core/ext/resolver/dns/native/README.md \
src/core/ext/census/README.md \
src/core/ext/census/gen/README.md \
src/core/lib/README.md \
src/core/lib/tsi/README.md \
src/core/lib/channel/README.md \
src/core/lib/transport/README.md \
src/core/lib/iomgr/README.md \
src/core/lib/surface/README.md
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses

@ -22,6 +22,10 @@ The script is also capable of running interop tests for grpc-java and grpc-go, u
######Example
`tools/run_tests/run_interop_tests.py -l csharp -s c++ --use_docker` (run interop tests with C# client and C++ server)
Note: if you see an error like `no space left on device` when running the
interop tests using Docker, make sure that Docker is building the image files in
a location with sufficient disk space.
#Performance benchmarks (run_performance_tests.py)
Runs predefined benchmark scenarios for given languages. Besides the simple configuration of running all the scenarios locally,

@ -179,10 +179,10 @@ class JavaLanguage:
return {}
def unimplemented_test_cases(self):
return _SKIP_ADVANCED + _SKIP_COMPRESSION
return _SKIP_COMPRESSION
def unimplemented_test_cases_server(self):
return _SKIP_ADVANCED + _SKIP_COMPRESSION
return _SKIP_COMPRESSION
def __str__(self):
return 'java'

@ -2,7 +2,7 @@ This directory contains MS Visual Studio project & solution files.
#Supported Visual Studio versions
Currently supported versions are Visual Studio 2013 (our primary focus) and 2010.
Currently supported versions are Visual Studio 2013 (our primary focus).
#Building
We are using [NuGet](http://www.nuget.org) to pull zlib and openssl dependencies.

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

@ -10,7 +10,7 @@ Multiple versions of VS installed to be able to build all the targets:
* Visual Studio 2013
* Visual Studio 2010 (you might need SP1 to prevent LNK1123 error)
CoApp toolkit: http://downloads.coapp.org/files/CoApp.Tools.Powershell.msi
CoApp toolkit: http://coapp.org/files/CoApp.Tools.Powershell.msi
More details on installation: http://coapp.org/tutorials/installation.html
@ -33,4 +33,4 @@ This will create three NuGet packages:
* the symbols package (debug symbols)
Later, you can push the package to NuGet.org repo.
Attention: before pusing the resulting nuget package to public nuget repo, you have to be 100% sure it works correctly - there’s no way how to delete or update an already existing package.
Attention: before pusing the resulting nuget package to public nuget repo, you have to be 100% sure it works correctly - there’s no way how to delete or update an already existing package.

Loading…
Cancel
Save