diff options
author | 2017-12-13 14:04:45 -0800 | |
---|---|---|
committer | 2017-12-13 14:04:45 -0800 | |
commit | 032e9b32dc5978a042bdda5c3031ae6cbd928973 (patch) | |
tree | 9a9102f17700c05003cb2c85801913e48637ddf5 /src | |
parent | 86ece2c8f6740bf046cddbe66e6cec12d50fb29b (diff) | |
parent | 91a851c6e1f6bc7c1dbf84ea12558d535c911252 (diff) |
Merge remote-tracking branch 'upstream/master' into fix-stream-compression-config-interface
Diffstat (limited to 'src')
96 files changed, 3751 insertions, 1578 deletions
diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc index 40fe0b054a..7c97056402 100644 --- a/src/compiler/csharp_generator.cc +++ b/src/compiler/csharp_generator.cc @@ -659,8 +659,11 @@ grpc::string GetServices(const FileDescriptor* file, bool generate_client, } // Write out a file header. - out.Print("// Generated by the protocol buffer compiler. DO NOT EDIT!\n"); - out.Print("// source: $filename$\n", "filename", file->name()); + out.Print("// <auto-generated>\n"); + out.Print( + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"); + out.Print("// source: $filename$\n", "filename", file->name()); + out.Print("// </auto-generated>\n"); // use C++ style as there are no file-level XML comments in .NET grpc::string leading_comments = GetCsharpComments(file, true); diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc index d9e8a30f5e..ae9d47ece5 100644 --- a/src/core/lib/iomgr/ev_epoll1_linux.cc +++ b/src/core/lib/iomgr/ev_epoll1_linux.cc @@ -738,7 +738,7 @@ static bool begin_worker(grpc_pollset* pollset, grpc_pollset_worker* worker, } if (gpr_cv_wait(&worker->cv, &pollset->mu, - grpc_millis_to_timespec(deadline, GPR_CLOCK_REALTIME)) && + grpc_millis_to_timespec(deadline, GPR_CLOCK_MONOTONIC)) && worker->state == UNKICKED) { /* If gpr_cv_wait returns true (i.e a timeout), pretend that the worker received a kick */ diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc index 006e3ddd2f..53de94fb6e 100644 --- a/src/core/lib/iomgr/ev_poll_posix.cc +++ b/src/core/lib/iomgr/ev_poll_posix.cc @@ -1471,7 +1471,7 @@ static void run_poll(void* args) { decref_poll_result(result); // Leave this polling thread alive for a grace period to do another poll() // op - gpr_timespec deadline = gpr_now(GPR_CLOCK_REALTIME); + gpr_timespec deadline = gpr_now(GPR_CLOCK_MONOTONIC); deadline = gpr_time_add(deadline, thread_grace); pargs->trigger_set = 0; gpr_cv_wait(&pargs->trigger, &g_cvfds.mu, deadline); @@ -1526,9 +1526,9 @@ static int cvfd_poll(struct pollfd* fds, nfds_t nfds, int timeout) { } } - gpr_timespec deadline = gpr_now(GPR_CLOCK_REALTIME); + gpr_timespec deadline = gpr_now(GPR_CLOCK_MONOTONIC); if (timeout < 0) { - deadline = gpr_inf_future(GPR_CLOCK_REALTIME); + deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); } else { deadline = gpr_time_add(deadline, gpr_time_from_millis(timeout, GPR_TIMESPAN)); @@ -1631,7 +1631,7 @@ static void global_cv_fd_table_shutdown() { // Not doing so will result in reported memory leaks if (!gpr_unref(&g_cvfds.pollcount)) { int res = gpr_cv_wait(&g_cvfds.shutdown_cv, &g_cvfds.mu, - gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(3, GPR_TIMESPAN))); GPR_ASSERT(res == 0); } diff --git a/src/core/lib/iomgr/executor.cc b/src/core/lib/iomgr/executor.cc index b45223ce16..b7288d5bf3 100644 --- a/src/core/lib/iomgr/executor.cc +++ b/src/core/lib/iomgr/executor.cc @@ -155,7 +155,7 @@ static void executor_thread(void* arg) { ts->depth -= subtract_depth; while (grpc_closure_list_empty(ts->elems) && !ts->shutdown) { ts->queued_long_job = false; - gpr_cv_wait(&ts->cv, &ts->mu, gpr_inf_future(GPR_CLOCK_REALTIME)); + gpr_cv_wait(&ts->cv, &ts->mu, gpr_inf_future(GPR_CLOCK_MONOTONIC)); } if (ts->shutdown) { if (executor_trace.enabled()) { diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc index dacf08ea9e..70807c479d 100644 --- a/src/core/lib/iomgr/iomgr.cc +++ b/src/core/lib/iomgr/iomgr.cc @@ -118,7 +118,7 @@ void grpc_iomgr_shutdown() { abort(); } gpr_timespec short_deadline = - gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_millis(100, GPR_TIMESPAN)); if (gpr_cv_wait(&g_rcv, &g_mu, short_deadline)) { if (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), shutdown_deadline) > diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc index 15062a52cd..24ccab14b2 100644 --- a/src/core/lib/iomgr/tcp_client_posix.cc +++ b/src/core/lib/iomgr/tcp_client_posix.cc @@ -236,65 +236,68 @@ finish: GRPC_CLOSURE_SCHED(closure, error); } -static void tcp_client_connect_impl(grpc_closure* closure, grpc_endpoint** ep, - grpc_pollset_set* interested_parties, - const grpc_channel_args* channel_args, - const grpc_resolved_address* addr, - grpc_millis deadline) { - int fd; +grpc_error* grpc_tcp_client_prepare_fd(const grpc_channel_args* channel_args, + const grpc_resolved_address* addr, + grpc_resolved_address* mapped_addr, + grpc_fd** fdobj) { grpc_dualstack_mode dsmode; - int err; - async_connect* ac; - grpc_resolved_address addr6_v4mapped; - grpc_resolved_address addr4_copy; - grpc_fd* fdobj; + int fd; + grpc_error* error; char* name; char* addr_str; - grpc_error* error; - - *ep = nullptr; - - /* Use dualstack sockets where available. */ - if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) { - addr = &addr6_v4mapped; + *fdobj = nullptr; + /* Use dualstack sockets where available. Set mapped to v6 or v4 mapped to + v6. */ + if (!grpc_sockaddr_to_v4mapped(addr, mapped_addr)) { + /* addr is v4 mapped to v6 or v6. */ + memcpy(mapped_addr, addr, sizeof(*mapped_addr)); } - - error = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode, &fd); + error = + grpc_create_dualstack_socket(mapped_addr, SOCK_STREAM, 0, &dsmode, &fd); if (error != GRPC_ERROR_NONE) { - GRPC_CLOSURE_SCHED(closure, error); - return; + return error; } if (dsmode == GRPC_DSMODE_IPV4) { - /* If we got an AF_INET socket, map the address back to IPv4. */ - GPR_ASSERT(grpc_sockaddr_is_v4mapped(addr, &addr4_copy)); - addr = &addr4_copy; + /* Original addr is either v4 or v4 mapped to v6. Set mapped_addr to v4. */ + if (!grpc_sockaddr_is_v4mapped(addr, mapped_addr)) { + memcpy(mapped_addr, addr, sizeof(*mapped_addr)); + } } - if ((error = prepare_socket(addr, fd, channel_args)) != GRPC_ERROR_NONE) { - GRPC_CLOSURE_SCHED(closure, error); - return; + if ((error = prepare_socket(mapped_addr, fd, channel_args)) != + GRPC_ERROR_NONE) { + return error; } + addr_str = grpc_sockaddr_to_uri(mapped_addr); + gpr_asprintf(&name, "tcp-client:%s", addr_str); + *fdobj = grpc_fd_create(fd, name); + gpr_free(name); + gpr_free(addr_str); + return GRPC_ERROR_NONE; +} +void grpc_tcp_client_create_from_prepared_fd( + grpc_pollset_set* interested_parties, grpc_closure* closure, grpc_fd* fdobj, + const grpc_channel_args* channel_args, const grpc_resolved_address* addr, + grpc_millis deadline, grpc_endpoint** ep) { + const int fd = grpc_fd_wrapped_fd(fdobj); + int err; + async_connect* ac; do { GPR_ASSERT(addr->len < ~(socklen_t)0); err = connect(fd, (const struct sockaddr*)addr->addr, (socklen_t)addr->len); } while (err < 0 && errno == EINTR); - - addr_str = grpc_sockaddr_to_uri(addr); - gpr_asprintf(&name, "tcp-client:%s", addr_str); - - fdobj = grpc_fd_create(fd, name); - if (err >= 0) { + char* addr_str = grpc_sockaddr_to_uri(addr); *ep = grpc_tcp_client_create_from_fd(fdobj, channel_args, addr_str); + gpr_free(addr_str); GRPC_CLOSURE_SCHED(closure, GRPC_ERROR_NONE); - goto done; + return; } - if (errno != EWOULDBLOCK && errno != EINPROGRESS) { grpc_fd_orphan(fdobj, nullptr, nullptr, false /* already_closed */, "tcp_client_connect_error"); GRPC_CLOSURE_SCHED(closure, GRPC_OS_ERROR(errno, "connect")); - goto done; + return; } grpc_pollset_set_add_fd(interested_parties, fdobj); @@ -304,8 +307,7 @@ static void tcp_client_connect_impl(grpc_closure* closure, grpc_endpoint** ep, ac->ep = ep; ac->fd = fdobj; ac->interested_parties = interested_parties; - ac->addr_str = addr_str; - addr_str = nullptr; + ac->addr_str = grpc_sockaddr_to_uri(addr); gpr_mu_init(&ac->mu); ac->refs = 2; GRPC_CLOSURE_INIT(&ac->write_closure, on_writable, ac, @@ -322,10 +324,25 @@ static void tcp_client_connect_impl(grpc_closure* closure, grpc_endpoint** ep, grpc_timer_init(&ac->alarm, deadline, &ac->on_alarm); grpc_fd_notify_on_write(ac->fd, &ac->write_closure); gpr_mu_unlock(&ac->mu); +} -done: - gpr_free(name); - gpr_free(addr_str); +static void tcp_client_connect_impl(grpc_closure* closure, grpc_endpoint** ep, + grpc_pollset_set* interested_parties, + const grpc_channel_args* channel_args, + const grpc_resolved_address* addr, + grpc_millis deadline) { + grpc_resolved_address mapped_addr; + grpc_fd* fdobj = nullptr; + grpc_error* error; + *ep = nullptr; + if ((error = grpc_tcp_client_prepare_fd(channel_args, addr, &mapped_addr, + &fdobj)) != GRPC_ERROR_NONE) { + GRPC_CLOSURE_SCHED(closure, error); + return; + } + grpc_tcp_client_create_from_prepared_fd(interested_parties, closure, fdobj, + channel_args, &mapped_addr, deadline, + ep); } // overridden by api_fuzzer.c diff --git a/src/core/lib/iomgr/tcp_client_posix.h b/src/core/lib/iomgr/tcp_client_posix.h index 7d0f133a6b..57e50a67d2 100644 --- a/src/core/lib/iomgr/tcp_client_posix.h +++ b/src/core/lib/iomgr/tcp_client_posix.h @@ -23,7 +23,44 @@ #include "src/core/lib/iomgr/ev_posix.h" #include "src/core/lib/iomgr/tcp_client.h" +/* Create an endpoint from a connected grpc_fd. + + fd: a connected FD. Ownership is taken. + channel_args: may contain custom settings for the endpoint + addr_str: destination address in printable format + Returns: a new endpoint +*/ grpc_endpoint* grpc_tcp_client_create_from_fd( grpc_fd* fd, const grpc_channel_args* channel_args, const char* addr_str); +/* Return a configured, unbound, unconnected TCP client grpc_fd. + + channel_args: may contain custom settings for the fd + addr: the destination address + mapped_addr: out parameter. addr mapped to an address appropriate to the + type of socket FD created. For example, if addr is IPv4 and dual stack + sockets are available, mapped_addr will be an IPv4-mapped IPv6 address + fdobj: out parameter. The new FD + Returns: error, if any. Out parameters are not set on error +*/ +grpc_error* grpc_tcp_client_prepare_fd(const grpc_channel_args* channel_args, + const grpc_resolved_address* addr, + grpc_resolved_address* mapped_addr, + grpc_fd** fdobj); + +/* Connect a configured TCP client grpc_fd. + + interested_parties: a set of pollsets that would be interested in this + connection being established (in order to continue their work + closure: called when complete. On success, *ep will be set. + fdobj: an FD returned from grpc_tcp_client_prepare_fd(). Ownership is taken + channel_args: may contain custom settings for the endpoint + deadline: connection deadline + ep: out parameter. Set before closure is called if successful +*/ +void grpc_tcp_client_create_from_prepared_fd( + grpc_pollset_set* interested_parties, grpc_closure* closure, grpc_fd* fdobj, + const grpc_channel_args* channel_args, const grpc_resolved_address* addr, + grpc_millis deadline, grpc_endpoint** ep); + #endif /* GRPC_CORE_LIB_IOMGR_TCP_CLIENT_POSIX_H */ diff --git a/src/core/lib/iomgr/tcp_client_windows.cc b/src/core/lib/iomgr/tcp_client_windows.cc index 5521a0a9ae..97aa9237dc 100644 --- a/src/core/lib/iomgr/tcp_client_windows.cc +++ b/src/core/lib/iomgr/tcp_client_windows.cc @@ -103,6 +103,7 @@ static void on_connect(void* acp, grpc_error* error) { GPR_ASSERT(transfered_bytes == 0); if (!wsa_success) { error = GRPC_WSA_ERROR(WSAGetLastError(), "ConnectEx"); + closesocket(socket->socket); } else { *ep = grpc_tcp_create(socket, ac->channel_args, ac->addr_name); socket = NULL; diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index 8ca6a3c23e..7fb068f10f 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -192,7 +192,7 @@ static bool wait_until(grpc_millis next) { } gpr_cv_wait(&g_cv_wait, &g_mu, - grpc_millis_to_timespec(next, GPR_CLOCK_REALTIME)); + grpc_millis_to_timespec(next, GPR_CLOCK_MONOTONIC)); if (grpc_timer_check_trace.enabled()) { gpr_log(GPR_DEBUG, "wait ended: was_timed:%d kicked:%d", @@ -317,7 +317,7 @@ static void stop_threads(void) { gpr_log(GPR_DEBUG, "num timer threads: %d", g_thread_count); } while (g_thread_count > 0) { - gpr_cv_wait(&g_cv_shutdown, &g_mu, gpr_inf_future(GPR_CLOCK_REALTIME)); + gpr_cv_wait(&g_cv_shutdown, &g_mu, gpr_inf_future(GPR_CLOCK_MONOTONIC)); if (grpc_timer_check_trace.enabled()) { gpr_log(GPR_DEBUG, "num timer threads: %d", g_thread_count); } diff --git a/src/core/lib/security/credentials/google_default/credentials_generic.cc b/src/core/lib/security/credentials/google_default/credentials_generic.cc index 58ee080cf3..af103f5dc5 100644 --- a/src/core/lib/security/credentials/google_default/credentials_generic.cc +++ b/src/core/lib/security/credentials/google_default/credentials_generic.cc @@ -29,7 +29,7 @@ char* grpc_get_well_known_google_credentials_file_path_impl(void) { char* result = nullptr; char* base = gpr_getenv(GRPC_GOOGLE_CREDENTIALS_PATH_ENV_VAR); if (base == nullptr) { - gpr_log(GPR_ERROR, "Could not get " GRPC_GOOGLE_CREDENTIALS_ENV_VAR + gpr_log(GPR_ERROR, "Could not get " GRPC_GOOGLE_CREDENTIALS_PATH_ENV_VAR " environment variable."); return nullptr; } diff --git a/src/core/lib/support/sync_posix.cc b/src/core/lib/support/sync_posix.cc index dfdd233bf4..c3f6b10463 100644 --- a/src/core/lib/support/sync_posix.cc +++ b/src/core/lib/support/sync_posix.cc @@ -66,7 +66,12 @@ int gpr_mu_trylock(gpr_mu* mu) { /*----------------------------------------*/ void gpr_cv_init(gpr_cv* cv) { - GPR_ASSERT(pthread_cond_init(cv, nullptr) == 0); + pthread_condattr_t attr; + GPR_ASSERT(pthread_condattr_init(&attr) == 0); +#if GPR_LINUX + GPR_ASSERT(pthread_condattr_setclock(&attr, CLOCK_MONOTONIC) == 0); +#endif // GPR_LINUX + GPR_ASSERT(pthread_cond_init(cv, &attr) == 0); } void gpr_cv_destroy(gpr_cv* cv) { GPR_ASSERT(pthread_cond_destroy(cv) == 0); } @@ -78,7 +83,11 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { err = pthread_cond_wait(cv, mu); } else { struct timespec abs_deadline_ts; +#if GPR_LINUX + abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_MONOTONIC); +#else abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_REALTIME); +#endif // GPR_LINUX abs_deadline_ts.tv_sec = (time_t)abs_deadline.tv_sec; abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec; err = pthread_cond_timedwait(cv, mu, &abs_deadline_ts); diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 12385b7130..aa5808da4c 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -115,7 +115,7 @@ static grpc_error* non_polling_poller_work(grpc_pollset* pollset, } w.kicked = false; gpr_timespec deadline_ts = - grpc_millis_to_timespec(deadline, GPR_CLOCK_REALTIME); + grpc_millis_to_timespec(deadline, GPR_CLOCK_MONOTONIC); while (!npp->shutdown && !w.kicked && !gpr_cv_wait(&w.cv, &npp->mu, deadline_ts)) ; diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 4f07183180..f1d428f0a1 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -1170,7 +1170,7 @@ void grpc_server_shutdown_and_notify(grpc_server* server, gpr_mu_lock(&server->mu_global); while (server->starting) { gpr_cv_wait(&server->starting_cv, &server->mu_global, - gpr_inf_future(GPR_CLOCK_REALTIME)); + gpr_inf_future(GPR_CLOCK_MONOTONIC)); } /* stay locked, and gather up some stuff to do */ diff --git a/src/csharp/Grpc.Core.Tests/ChannelConnectivityTest.cs b/src/csharp/Grpc.Core.Tests/ChannelConnectivityTest.cs new file mode 100644 index 0000000000..a43040f01a --- /dev/null +++ b/src/csharp/Grpc.Core.Tests/ChannelConnectivityTest.cs @@ -0,0 +1,86 @@ +#region Copyright notice and license + +// Copyright 2017 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Grpc.Core; +using Grpc.Core.Internal; +using Grpc.Core.Profiling; +using Grpc.Core.Utils; +using NUnit.Framework; + +namespace Grpc.Core.Tests +{ + public class ChannelConnectivityTest + { + const string Host = "127.0.0.1"; + + MockServiceHelper helper; + Server server; + Channel channel; + + [SetUp] + public void Init() + { + helper = new MockServiceHelper(Host); + server = helper.GetServer(); + server.Start(); + channel = helper.GetChannel(); + } + + [TearDown] + public void Cleanup() + { + channel.ShutdownAsync().Wait(); + server.ShutdownAsync().Wait(); + } + + [Test] + public async Task Channel_WaitForStateChangedAsync() + { + helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) => + { + return Task.FromResult(request); + }); + + Assert.ThrowsAsync(typeof(TaskCanceledException), + async () => await channel.WaitForStateChangedAsync(channel.State, DateTime.UtcNow.AddMilliseconds(10))); + + var stateChangedTask = channel.WaitForStateChangedAsync(channel.State); + + await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "abc"); + + await stateChangedTask; + Assert.AreEqual(ChannelState.Ready, channel.State); + } + + [Test] + public async Task Channel_ConnectAsync() + { + await channel.ConnectAsync(); + Assert.AreEqual(ChannelState.Ready, channel.State); + + await channel.ConnectAsync(DateTime.UtcNow.AddMilliseconds(1000)); + Assert.AreEqual(ChannelState.Ready, channel.State); + } + } +} diff --git a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs index 90dd365b07..331c3321e1 100644 --- a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs +++ b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs @@ -373,34 +373,5 @@ namespace Grpc.Core.Tests }); Assert.AreEqual("PASS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc")); } - - [Test] - public async Task Channel_WaitForStateChangedAsync() - { - helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) => - { - return Task.FromResult(request); - }); - - Assert.ThrowsAsync(typeof(TaskCanceledException), - async () => await channel.WaitForStateChangedAsync(channel.State, DateTime.UtcNow.AddMilliseconds(10))); - - var stateChangedTask = channel.WaitForStateChangedAsync(channel.State); - - await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "abc"); - - await stateChangedTask; - Assert.AreEqual(ChannelState.Ready, channel.State); - } - - [Test] - public async Task Channel_ConnectAsync() - { - await channel.ConnectAsync(); - Assert.AreEqual(ChannelState.Ready, channel.State); - - await channel.ConnectAsync(DateTime.UtcNow.AddMilliseconds(1000)); - Assert.AreEqual(ChannelState.Ready, channel.State); - } } } diff --git a/src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs b/src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs index 775c950c8c..7e4e2975c1 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs @@ -40,7 +40,7 @@ namespace Grpc.Core.Internal.Tests public void CreateAsyncAndShutdown() { var env = GrpcEnvironment.AddRef(); - var cq = CompletionQueueSafeHandle.CreateAsync(new CompletionRegistry(env, () => BatchContextSafeHandle.Create())); + var cq = CompletionQueueSafeHandle.CreateAsync(new CompletionRegistry(env, () => BatchContextSafeHandle.Create(), () => RequestCallContextSafeHandle.Create())); cq.Shutdown(); var ev = cq.Next(); cq.Dispose(); diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs index f9925a8a76..e39da9c1c2 100644 --- a/src/csharp/Grpc.Core/Channel.cs +++ b/src/csharp/Grpc.Core/Channel.cs @@ -152,8 +152,11 @@ namespace Grpc.Core "Shutdown is a terminal state. No further state changes can occur."); var tcs = new TaskCompletionSource<object>(); var deadlineTimespec = deadline.HasValue ? Timespec.FromDateTime(deadline.Value) : Timespec.InfFuture; - // pass "tcs" as "state" for WatchConnectivityStateHandler. - handle.WatchConnectivityState(lastObservedState, deadlineTimespec, completionQueue, WatchConnectivityStateHandler, tcs); + lock (myLock) + { + // pass "tcs" as "state" for WatchConnectivityStateHandler. + handle.WatchConnectivityState(lastObservedState, deadlineTimespec, completionQueue, WatchConnectivityStateHandler, tcs); + } return tcs.Task; } @@ -236,7 +239,10 @@ namespace Grpc.Core Logger.Warning("Channel shutdown was called but there are still {0} active calls for that channel.", activeCallCount); } - handle.Dispose(); + lock (myLock) + { + handle.Dispose(); + } await Task.WhenAll(GrpcEnvironment.ReleaseAsync(), connectivityWatcherTask).ConfigureAwait(false); } @@ -285,7 +291,10 @@ namespace Grpc.Core { try { - return handle.CheckConnectivityState(tryToConnect); + lock (myLock) + { + return handle.CheckConnectivityState(tryToConnect); + } } catch (ObjectDisposedException) { diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs index 2b1b5e32d7..7b4342b74b 100644 --- a/src/csharp/Grpc.Core/GrpcEnvironment.cs +++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs @@ -35,6 +35,8 @@ namespace Grpc.Core const int MinDefaultThreadPoolSize = 4; const int DefaultBatchContextPoolSharedCapacity = 10000; const int DefaultBatchContextPoolThreadLocalCapacity = 64; + const int DefaultRequestCallContextPoolSharedCapacity = 10000; + const int DefaultRequestCallContextPoolThreadLocalCapacity = 64; static object staticLock = new object(); static GrpcEnvironment instance; @@ -44,12 +46,15 @@ namespace Grpc.Core static bool inlineHandlers; static int batchContextPoolSharedCapacity = DefaultBatchContextPoolSharedCapacity; static int batchContextPoolThreadLocalCapacity = DefaultBatchContextPoolThreadLocalCapacity; + static int requestCallContextPoolSharedCapacity = DefaultRequestCallContextPoolSharedCapacity; + static int requestCallContextPoolThreadLocalCapacity = DefaultRequestCallContextPoolThreadLocalCapacity; static readonly HashSet<Channel> registeredChannels = new HashSet<Channel>(); static readonly HashSet<Server> registeredServers = new HashSet<Server>(); static ILogger logger = new LogLevelFilterLogger(new ConsoleLogger(), LogLevel.Off, true); readonly IObjectPool<BatchContextSafeHandle> batchContextPool; + readonly IObjectPool<RequestCallContextSafeHandle> requestCallContextPool; readonly GrpcThreadPool threadPool; readonly DebugStats debugStats = new DebugStats(); readonly AtomicCounter cqPickerCounter = new AtomicCounter(); @@ -263,6 +268,26 @@ namespace Grpc.Core } /// <summary> + /// Sets the parameters for a pool that caches request call context instances. Reusing request call context instances + /// instead of creating a new one for every requested call in C core helps reducing the GC pressure. + /// Can be only invoked before the <c>GrpcEnviroment</c> is started and cannot be changed afterwards. + /// This is an advanced setting and you should only use it if you know what you are doing. + /// Most users should rely on the default value provided by gRPC library. + /// Note: this method is part of an experimental API that can change or be removed without any prior notice. + /// </summary> + public static void SetRequestCallContextPoolParams(int sharedCapacity, int threadLocalCapacity) + { + lock (staticLock) + { + GrpcPreconditions.CheckState(instance == null, "Can only be set before GrpcEnvironment is initialized"); + GrpcPreconditions.CheckArgument(sharedCapacity >= 0, "Shared capacity needs to be a non-negative number"); + GrpcPreconditions.CheckArgument(threadLocalCapacity >= 0, "Thread local capacity needs to be a non-negative number"); + requestCallContextPoolSharedCapacity = sharedCapacity; + requestCallContextPoolThreadLocalCapacity = threadLocalCapacity; + } + } + + /// <summary> /// Occurs when <c>GrpcEnvironment</c> is about the start the shutdown logic. /// If <c>GrpcEnvironment</c> is later initialized and shutdown, the event will be fired again (unless unregistered first). /// </summary> @@ -275,6 +300,7 @@ namespace Grpc.Core { GrpcNativeInit(); batchContextPool = new DefaultObjectPool<BatchContextSafeHandle>(() => BatchContextSafeHandle.Create(this.batchContextPool), batchContextPoolSharedCapacity, batchContextPoolThreadLocalCapacity); + requestCallContextPool = new DefaultObjectPool<RequestCallContextSafeHandle>(() => RequestCallContextSafeHandle.Create(this.requestCallContextPool), requestCallContextPoolSharedCapacity, requestCallContextPoolThreadLocalCapacity); threadPool = new GrpcThreadPool(this, GetThreadPoolSizeOrDefault(), GetCompletionQueueCountOrDefault(), inlineHandlers); threadPool.Start(); } @@ -292,6 +318,8 @@ namespace Grpc.Core internal IObjectPool<BatchContextSafeHandle> BatchContextPool => batchContextPool; + internal IObjectPool<RequestCallContextSafeHandle> RequestCallContextPool => requestCallContextPool; + internal bool IsAlive { get diff --git a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs index cf3f3c0995..79d0c91420 100644 --- a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs +++ b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs @@ -37,14 +37,16 @@ namespace Grpc.Core.Internal readonly GrpcEnvironment environment; readonly Func<BatchContextSafeHandle> batchContextFactory; + readonly Func<RequestCallContextSafeHandle> requestCallContextFactory; readonly Dictionary<IntPtr, IOpCompletionCallback> dict = new Dictionary<IntPtr, IOpCompletionCallback>(new IntPtrComparer()); SpinLock spinLock = new SpinLock(Debugger.IsAttached); IntPtr lastRegisteredKey; // only for testing - public CompletionRegistry(GrpcEnvironment environment, Func<BatchContextSafeHandle> batchContextFactory) + public CompletionRegistry(GrpcEnvironment environment, Func<BatchContextSafeHandle> batchContextFactory, Func<RequestCallContextSafeHandle> requestCallContextFactory) { this.environment = GrpcPreconditions.CheckNotNull(environment); this.batchContextFactory = GrpcPreconditions.CheckNotNull(batchContextFactory); + this.requestCallContextFactory = GrpcPreconditions.CheckNotNull(requestCallContextFactory); } public void Register(IntPtr key, IOpCompletionCallback callback) @@ -73,10 +75,12 @@ namespace Grpc.Core.Internal return ctx; } - public void RegisterRequestCallCompletion(RequestCallContextSafeHandle ctx, RequestCallCompletionDelegate callback) + public RequestCallContextSafeHandle RegisterRequestCallCompletion(RequestCallCompletionDelegate callback) { + var ctx = requestCallContextFactory(); ctx.CompletionCallback = callback; Register(ctx.Handle, ctx); + return ctx; } public IOpCompletionCallback Extract(IntPtr key) diff --git a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs index f1b5a4f9ff..8ddda9be5c 100644 --- a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs +++ b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs @@ -219,7 +219,7 @@ namespace Grpc.Core.Internal var list = new List<CompletionQueueSafeHandle>(); for (int i = 0; i < completionQueueCount; i++) { - var completionRegistry = new CompletionRegistry(environment, () => environment.BatchContextPool.Lease()); + var completionRegistry = new CompletionRegistry(environment, () => environment.BatchContextPool.Lease(), () => environment.RequestCallContextPool.Lease()); list.Add(CompletionQueueSafeHandle.CreateAsync(completionRegistry)); } return list.AsReadOnly(); diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.cs index 43acb8f915..8b15c2690f 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMethods.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMethods.cs @@ -61,6 +61,7 @@ namespace Grpc.Core.Internal public readonly Delegates.grpcsharp_request_call_context_host_delegate grpcsharp_request_call_context_host; public readonly Delegates.grpcsharp_request_call_context_deadline_delegate grpcsharp_request_call_context_deadline; public readonly Delegates.grpcsharp_request_call_context_request_metadata_delegate grpcsharp_request_call_context_request_metadata; + public readonly Delegates.grpcsharp_request_call_context_reset_delegate grpcsharp_request_call_context_reset; public readonly Delegates.grpcsharp_request_call_context_destroy_delegate grpcsharp_request_call_context_destroy; public readonly Delegates.grpcsharp_composite_call_credentials_create_delegate grpcsharp_composite_call_credentials_create; @@ -179,6 +180,7 @@ namespace Grpc.Core.Internal this.grpcsharp_request_call_context_host = GetMethodDelegate<Delegates.grpcsharp_request_call_context_host_delegate>(library); this.grpcsharp_request_call_context_deadline = GetMethodDelegate<Delegates.grpcsharp_request_call_context_deadline_delegate>(library); this.grpcsharp_request_call_context_request_metadata = GetMethodDelegate<Delegates.grpcsharp_request_call_context_request_metadata_delegate>(library); + this.grpcsharp_request_call_context_reset = GetMethodDelegate<Delegates.grpcsharp_request_call_context_reset_delegate>(library); this.grpcsharp_request_call_context_destroy = GetMethodDelegate<Delegates.grpcsharp_request_call_context_destroy_delegate>(library); this.grpcsharp_composite_call_credentials_create = GetMethodDelegate<Delegates.grpcsharp_composite_call_credentials_create_delegate>(library); @@ -322,6 +324,7 @@ namespace Grpc.Core.Internal public delegate IntPtr grpcsharp_request_call_context_host_delegate(RequestCallContextSafeHandle ctx, out UIntPtr hostLength); public delegate Timespec grpcsharp_request_call_context_deadline_delegate(RequestCallContextSafeHandle ctx); public delegate IntPtr grpcsharp_request_call_context_request_metadata_delegate(RequestCallContextSafeHandle ctx); + public delegate void grpcsharp_request_call_context_reset_delegate(RequestCallContextSafeHandle ctx); public delegate void grpcsharp_request_call_context_destroy_delegate(IntPtr ctx); public delegate CallCredentialsSafeHandle grpcsharp_composite_call_credentials_create_delegate(CallCredentialsSafeHandle creds1, CallCredentialsSafeHandle creds2); diff --git a/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs index 09f5c3e452..59e9d9b1ab 100644 --- a/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs @@ -30,14 +30,17 @@ namespace Grpc.Core.Internal { static readonly NativeMethods Native = NativeMethods.Get(); static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<RequestCallContextSafeHandle>(); + IObjectPool<RequestCallContextSafeHandle> ownedByPool; private RequestCallContextSafeHandle() { } - public static RequestCallContextSafeHandle Create() + public static RequestCallContextSafeHandle Create(IObjectPool<RequestCallContextSafeHandle> ownedByPool = null) { - return Native.grpcsharp_request_call_context_create(); + var ctx = Native.grpcsharp_request_call_context_create(); + ctx.ownedByPool = ownedByPool; + return ctx; } public IntPtr Handle @@ -71,6 +74,19 @@ namespace Grpc.Core.Internal return new ServerRpcNew(server, call, method, host, deadline, metadata); } + public void Recycle() + { + if (ownedByPool != null) + { + Native.grpcsharp_request_call_context_reset(this); + ownedByPool.Return(this); + } + else + { + Dispose(); + } + } + protected override bool ReleaseHandle() { Native.grpcsharp_request_call_context_destroy(handle); @@ -90,7 +106,7 @@ namespace Grpc.Core.Internal finally { CompletionCallback = null; - Dispose(); + Recycle(); } } } diff --git a/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs index 9b7ea884dd..56dda9cff5 100644 --- a/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs @@ -75,8 +75,7 @@ namespace Grpc.Core.Internal { using (completionQueue.NewScope()) { - var ctx = RequestCallContextSafeHandle.Create(); - completionQueue.CompletionRegistry.RegisterRequestCallCompletion(ctx, callback); + var ctx = completionQueue.CompletionRegistry.RegisterRequestCallCompletion(callback); Native.grpcsharp_server_request_call(this, completionQueue, ctx).CheckOk(); } } diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs index 71c7f108f3..60dacbf126 100644 --- a/src/csharp/Grpc.Core/Server.cs +++ b/src/csharp/Grpc.Core/Server.cs @@ -300,6 +300,7 @@ namespace Grpc.Core { if (!shutdownRequested) { + // TODO(jtattermusch): avoid unnecessary delegate allocation handle.RequestCall((success, ctx) => HandleNewServerRpc(success, ctx, cq), cq); } } diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs index 4ed414400d..e29b1087e4 100644 --- a/src/csharp/Grpc.Examples/MathGrpc.cs +++ b/src/csharp/Grpc.Examples/MathGrpc.cs @@ -1,5 +1,7 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: math/math.proto +// <auto-generated> +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: math/math.proto +// </auto-generated> // Original file comments: // Copyright 2015 gRPC authors. // diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs index 3e8eb34689..24a7259979 100644 --- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs +++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs @@ -1,5 +1,7 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: grpc/health/v1/health.proto +// <auto-generated> +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: grpc/health/v1/health.proto +// </auto-generated> // Original file comments: // Copyright 2015 gRPC authors. // diff --git a/src/csharp/Grpc.IntegrationTesting/Control.cs b/src/csharp/Grpc.IntegrationTesting/Control.cs index b15da8b8e5..8e5da7b9f2 100644 --- a/src/csharp/Grpc.IntegrationTesting/Control.cs +++ b/src/csharp/Grpc.IntegrationTesting/Control.cs @@ -522,10 +522,16 @@ namespace Grpc.Testing { } switch (other.LoadCase) { case LoadOneofCase.ClosedLoop: - ClosedLoop = other.ClosedLoop; + if (ClosedLoop == null) { + ClosedLoop = new global::Grpc.Testing.ClosedLoopParams(); + } + ClosedLoop.MergeFrom(other.ClosedLoop); break; case LoadOneofCase.Poisson: - Poisson = other.Poisson; + if (Poisson == null) { + Poisson = new global::Grpc.Testing.PoissonParams(); + } + Poisson.MergeFrom(other.Poisson); break; } @@ -1901,10 +1907,16 @@ namespace Grpc.Testing { } switch (other.ArgtypeCase) { case ArgtypeOneofCase.Setup: - Setup = other.Setup; + if (Setup == null) { + Setup = new global::Grpc.Testing.ClientConfig(); + } + Setup.MergeFrom(other.Setup); break; case ArgtypeOneofCase.Mark: - Mark = other.Mark; + if (Mark == null) { + Mark = new global::Grpc.Testing.Mark(); + } + Mark.MergeFrom(other.Mark); break; } @@ -2508,10 +2520,16 @@ namespace Grpc.Testing { } switch (other.ArgtypeCase) { case ArgtypeOneofCase.Setup: - Setup = other.Setup; + if (Setup == null) { + Setup = new global::Grpc.Testing.ServerConfig(); + } + Setup.MergeFrom(other.Setup); break; case ArgtypeOneofCase.Mark: - Mark = other.Mark; + if (Mark == null) { + Mark = new global::Grpc.Testing.Mark(); + } + Mark.MergeFrom(other.Mark); break; } diff --git a/src/csharp/Grpc.IntegrationTesting/CoreStats/Stats.cs b/src/csharp/Grpc.IntegrationTesting/CoreStats/Stats.cs new file mode 100644 index 0000000000..380294e335 --- /dev/null +++ b/src/csharp/Grpc.IntegrationTesting/CoreStats/Stats.cs @@ -0,0 +1,623 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: grpc/core/stats.proto +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace Grpc.Core { + + /// <summary>Holder for reflection information generated from grpc/core/stats.proto</summary> + public static partial class StatsReflection { + + #region Descriptor + /// <summary>File descriptor for grpc/core/stats.proto</summary> + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static StatsReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "ChVncnBjL2NvcmUvc3RhdHMucHJvdG8SCWdycGMuY29yZSImCgZCdWNrZXQS", + "DQoFc3RhcnQYASABKAESDQoFY291bnQYAiABKAQiLwoJSGlzdG9ncmFtEiIK", + "B2J1Y2tldHMYASADKAsyES5ncnBjLmNvcmUuQnVja2V0IlsKBk1ldHJpYxIM", + "CgRuYW1lGAEgASgJEg8KBWNvdW50GAogASgESAASKQoJaGlzdG9ncmFtGAsg", + "ASgLMhQuZ3JwYy5jb3JlLkhpc3RvZ3JhbUgAQgcKBXZhbHVlIisKBVN0YXRz", + "EiIKB21ldHJpY3MYASADKAsyES5ncnBjLmNvcmUuTWV0cmljYgZwcm90bzM=")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { }, + new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Core.Bucket), global::Grpc.Core.Bucket.Parser, new[]{ "Start", "Count" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Core.Histogram), global::Grpc.Core.Histogram.Parser, new[]{ "Buckets" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Core.Metric), global::Grpc.Core.Metric.Parser, new[]{ "Name", "Count", "Histogram" }, new[]{ "Value" }, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Core.Stats), global::Grpc.Core.Stats.Parser, new[]{ "Metrics" }, null, null, null) + })); + } + #endregion + + } + #region Messages + public sealed partial class Bucket : pb::IMessage<Bucket> { + private static readonly pb::MessageParser<Bucket> _parser = new pb::MessageParser<Bucket>(() => new Bucket()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser<Bucket> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Grpc.Core.StatsReflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Bucket() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Bucket(Bucket other) : this() { + start_ = other.start_; + count_ = other.count_; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Bucket Clone() { + return new Bucket(this); + } + + /// <summary>Field number for the "start" field.</summary> + public const int StartFieldNumber = 1; + private double start_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double Start { + get { return start_; } + set { + start_ = value; + } + } + + /// <summary>Field number for the "count" field.</summary> + public const int CountFieldNumber = 2; + private ulong count_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public ulong Count { + get { return count_; } + set { + count_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as Bucket); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(Bucket other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Start != other.Start) return false; + if (Count != other.Count) return false; + return true; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (Start != 0D) hash ^= Start.GetHashCode(); + if (Count != 0UL) hash ^= Count.GetHashCode(); + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + if (Start != 0D) { + output.WriteRawTag(9); + output.WriteDouble(Start); + } + if (Count != 0UL) { + output.WriteRawTag(16); + output.WriteUInt64(Count); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (Start != 0D) { + size += 1 + 8; + } + if (Count != 0UL) { + size += 1 + pb::CodedOutputStream.ComputeUInt64Size(Count); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(Bucket other) { + if (other == null) { + return; + } + if (other.Start != 0D) { + Start = other.Start; + } + if (other.Count != 0UL) { + Count = other.Count; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 9: { + Start = input.ReadDouble(); + break; + } + case 16: { + Count = input.ReadUInt64(); + break; + } + } + } + } + + } + + public sealed partial class Histogram : pb::IMessage<Histogram> { + private static readonly pb::MessageParser<Histogram> _parser = new pb::MessageParser<Histogram>(() => new Histogram()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser<Histogram> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Grpc.Core.StatsReflection.Descriptor.MessageTypes[1]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Histogram() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Histogram(Histogram other) : this() { + buckets_ = other.buckets_.Clone(); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Histogram Clone() { + return new Histogram(this); + } + + /// <summary>Field number for the "buckets" field.</summary> + public const int BucketsFieldNumber = 1; + private static readonly pb::FieldCodec<global::Grpc.Core.Bucket> _repeated_buckets_codec + = pb::FieldCodec.ForMessage(10, global::Grpc.Core.Bucket.Parser); + private readonly pbc::RepeatedField<global::Grpc.Core.Bucket> buckets_ = new pbc::RepeatedField<global::Grpc.Core.Bucket>(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public pbc::RepeatedField<global::Grpc.Core.Bucket> Buckets { + get { return buckets_; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as Histogram); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(Histogram other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if(!buckets_.Equals(other.buckets_)) return false; + return true; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + hash ^= buckets_.GetHashCode(); + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + buckets_.WriteTo(output, _repeated_buckets_codec); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + size += buckets_.CalculateSize(_repeated_buckets_codec); + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(Histogram other) { + if (other == null) { + return; + } + buckets_.Add(other.buckets_); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 10: { + buckets_.AddEntriesFrom(input, _repeated_buckets_codec); + break; + } + } + } + } + + } + + public sealed partial class Metric : pb::IMessage<Metric> { + private static readonly pb::MessageParser<Metric> _parser = new pb::MessageParser<Metric>(() => new Metric()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser<Metric> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Grpc.Core.StatsReflection.Descriptor.MessageTypes[2]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Metric() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Metric(Metric other) : this() { + name_ = other.name_; + switch (other.ValueCase) { + case ValueOneofCase.Count: + Count = other.Count; + break; + case ValueOneofCase.Histogram: + Histogram = other.Histogram.Clone(); + break; + } + + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Metric Clone() { + return new Metric(this); + } + + /// <summary>Field number for the "name" field.</summary> + public const int NameFieldNumber = 1; + private string name_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string Name { + get { return name_; } + set { + name_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// <summary>Field number for the "count" field.</summary> + public const int CountFieldNumber = 10; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public ulong Count { + get { return valueCase_ == ValueOneofCase.Count ? (ulong) value_ : 0UL; } + set { + value_ = value; + valueCase_ = ValueOneofCase.Count; + } + } + + /// <summary>Field number for the "histogram" field.</summary> + public const int HistogramFieldNumber = 11; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public global::Grpc.Core.Histogram Histogram { + get { return valueCase_ == ValueOneofCase.Histogram ? (global::Grpc.Core.Histogram) value_ : null; } + set { + value_ = value; + valueCase_ = value == null ? ValueOneofCase.None : ValueOneofCase.Histogram; + } + } + + private object value_; + /// <summary>Enum of possible cases for the "value" oneof.</summary> + public enum ValueOneofCase { + None = 0, + Count = 10, + Histogram = 11, + } + private ValueOneofCase valueCase_ = ValueOneofCase.None; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public ValueOneofCase ValueCase { + get { return valueCase_; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearValue() { + valueCase_ = ValueOneofCase.None; + value_ = null; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as Metric); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(Metric other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Name != other.Name) return false; + if (Count != other.Count) return false; + if (!object.Equals(Histogram, other.Histogram)) return false; + if (ValueCase != other.ValueCase) return false; + return true; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (Name.Length != 0) hash ^= Name.GetHashCode(); + if (valueCase_ == ValueOneofCase.Count) hash ^= Count.GetHashCode(); + if (valueCase_ == ValueOneofCase.Histogram) hash ^= Histogram.GetHashCode(); + hash ^= (int) valueCase_; + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + if (Name.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Name); + } + if (valueCase_ == ValueOneofCase.Count) { + output.WriteRawTag(80); + output.WriteUInt64(Count); + } + if (valueCase_ == ValueOneofCase.Histogram) { + output.WriteRawTag(90); + output.WriteMessage(Histogram); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (Name.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); + } + if (valueCase_ == ValueOneofCase.Count) { + size += 1 + pb::CodedOutputStream.ComputeUInt64Size(Count); + } + if (valueCase_ == ValueOneofCase.Histogram) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Histogram); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(Metric other) { + if (other == null) { + return; + } + if (other.Name.Length != 0) { + Name = other.Name; + } + switch (other.ValueCase) { + case ValueOneofCase.Count: + Count = other.Count; + break; + case ValueOneofCase.Histogram: + if (Histogram == null) { + Histogram = new global::Grpc.Core.Histogram(); + } + Histogram.MergeFrom(other.Histogram); + break; + } + + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 10: { + Name = input.ReadString(); + break; + } + case 80: { + Count = input.ReadUInt64(); + break; + } + case 90: { + global::Grpc.Core.Histogram subBuilder = new global::Grpc.Core.Histogram(); + if (valueCase_ == ValueOneofCase.Histogram) { + subBuilder.MergeFrom(Histogram); + } + input.ReadMessage(subBuilder); + Histogram = subBuilder; + break; + } + } + } + } + + } + + public sealed partial class Stats : pb::IMessage<Stats> { + private static readonly pb::MessageParser<Stats> _parser = new pb::MessageParser<Stats>(() => new Stats()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser<Stats> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Grpc.Core.StatsReflection.Descriptor.MessageTypes[3]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Stats() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Stats(Stats other) : this() { + metrics_ = other.metrics_.Clone(); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Stats Clone() { + return new Stats(this); + } + + /// <summary>Field number for the "metrics" field.</summary> + public const int MetricsFieldNumber = 1; + private static readonly pb::FieldCodec<global::Grpc.Core.Metric> _repeated_metrics_codec + = pb::FieldCodec.ForMessage(10, global::Grpc.Core.Metric.Parser); + private readonly pbc::RepeatedField<global::Grpc.Core.Metric> metrics_ = new pbc::RepeatedField<global::Grpc.Core.Metric>(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public pbc::RepeatedField<global::Grpc.Core.Metric> Metrics { + get { return metrics_; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as Stats); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(Stats other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if(!metrics_.Equals(other.metrics_)) return false; + return true; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + hash ^= metrics_.GetHashCode(); + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + metrics_.WriteTo(output, _repeated_metrics_codec); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + size += metrics_.CalculateSize(_repeated_metrics_codec); + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(Stats other) { + if (other == null) { + return; + } + metrics_.Add(other.metrics_); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 10: { + metrics_.AddEntriesFrom(input, _repeated_metrics_codec); + break; + } + } + } + } + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs b/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs index b2fe73acdf..9581aded58 100644 --- a/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs +++ b/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs @@ -26,7 +26,7 @@ namespace Grpc.Testing { "DGdycGMudGVzdGluZyIyCglEZWJ1Z0luZm8SFQoNc3RhY2tfZW50cmllcxgB", "IAMoCRIOCgZkZXRhaWwYAiABKAkiUAoLRXJyb3JTdGF0dXMSDAoEY29kZRgB", "IAEoBRIVCg1lcnJvcl9tZXNzYWdlGAIgASgJEhwKFGJpbmFyeV9lcnJvcl9k", - "ZXRhaWxzGAMgASgJIskDCg1SZXF1ZXN0UGFyYW1zEhUKDWVjaG9fZGVhZGxp", + "ZXRhaWxzGAMgASgJIuIDCg1SZXF1ZXN0UGFyYW1zEhUKDWVjaG9fZGVhZGxp", "bmUYASABKAgSHgoWY2xpZW50X2NhbmNlbF9hZnRlcl91cxgCIAEoBRIeChZz", "ZXJ2ZXJfY2FuY2VsX2FmdGVyX3VzGAMgASgFEhUKDWVjaG9fbWV0YWRhdGEY", "BCABKAgSGgoSY2hlY2tfYXV0aF9jb250ZXh0GAUgASgIEh8KF3Jlc3BvbnNl", @@ -36,18 +36,19 @@ namespace Grpc.Testing { "X3R5cGUYCiABKAkSKwoKZGVidWdfaW5mbxgLIAEoCzIXLmdycGMudGVzdGlu", "Zy5EZWJ1Z0luZm8SEgoKc2VydmVyX2RpZRgMIAEoCBIcChRiaW5hcnlfZXJy", "b3JfZGV0YWlscxgNIAEoCRIxCg5leHBlY3RlZF9lcnJvchgOIAEoCzIZLmdy", - "cGMudGVzdGluZy5FcnJvclN0YXR1cyJKCgtFY2hvUmVxdWVzdBIPCgdtZXNz", - "YWdlGAEgASgJEioKBXBhcmFtGAIgASgLMhsuZ3JwYy50ZXN0aW5nLlJlcXVl", - "c3RQYXJhbXMiRgoOUmVzcG9uc2VQYXJhbXMSGAoQcmVxdWVzdF9kZWFkbGlu", - "ZRgBIAEoAxIMCgRob3N0GAIgASgJEgwKBHBlZXIYAyABKAkiTAoMRWNob1Jl", - "c3BvbnNlEg8KB21lc3NhZ2UYASABKAkSKwoFcGFyYW0YAiABKAsyHC5ncnBj", - "LnRlc3RpbmcuUmVzcG9uc2VQYXJhbXNiBnByb3RvMw==")); + "cGMudGVzdGluZy5FcnJvclN0YXR1cxIXCg9zZXJ2ZXJfc2xlZXBfdXMYDyAB", + "KAUiSgoLRWNob1JlcXVlc3QSDwoHbWVzc2FnZRgBIAEoCRIqCgVwYXJhbRgC", + "IAEoCzIbLmdycGMudGVzdGluZy5SZXF1ZXN0UGFyYW1zIkYKDlJlc3BvbnNl", + "UGFyYW1zEhgKEHJlcXVlc3RfZGVhZGxpbmUYASABKAMSDAoEaG9zdBgCIAEo", + "CRIMCgRwZWVyGAMgASgJIkwKDEVjaG9SZXNwb25zZRIPCgdtZXNzYWdlGAEg", + "ASgJEisKBXBhcmFtGAIgASgLMhwuZ3JwYy50ZXN0aW5nLlJlc3BvbnNlUGFy", + "YW1zYgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.DebugInfo), global::Grpc.Testing.DebugInfo.Parser, new[]{ "StackEntries", "Detail" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ErrorStatus), global::Grpc.Testing.ErrorStatus.Parser, new[]{ "Code", "ErrorMessage", "BinaryErrorDetails" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.RequestParams), global::Grpc.Testing.RequestParams.Parser, new[]{ "EchoDeadline", "ClientCancelAfterUs", "ServerCancelAfterUs", "EchoMetadata", "CheckAuthContext", "ResponseMessageLength", "EchoPeer", "ExpectedClientIdentity", "SkipCancelledCheck", "ExpectedTransportSecurityType", "DebugInfo", "ServerDie", "BinaryErrorDetails", "ExpectedError" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.RequestParams), global::Grpc.Testing.RequestParams.Parser, new[]{ "EchoDeadline", "ClientCancelAfterUs", "ServerCancelAfterUs", "EchoMetadata", "CheckAuthContext", "ResponseMessageLength", "EchoPeer", "ExpectedClientIdentity", "SkipCancelledCheck", "ExpectedTransportSecurityType", "DebugInfo", "ServerDie", "BinaryErrorDetails", "ExpectedError", "ServerSleepUs" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.EchoRequest), global::Grpc.Testing.EchoRequest.Parser, new[]{ "Message", "Param" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ResponseParams), global::Grpc.Testing.ResponseParams.Parser, new[]{ "RequestDeadline", "Host", "Peer" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.EchoResponse), global::Grpc.Testing.EchoResponse.Parser, new[]{ "Message", "Param" }, null, null, null) @@ -411,6 +412,7 @@ namespace Grpc.Testing { serverDie_ = other.serverDie_; binaryErrorDetails_ = other.binaryErrorDetails_; ExpectedError = other.expectedError_ != null ? other.ExpectedError.Clone() : null; + serverSleepUs_ = other.serverSleepUs_; } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -578,6 +580,20 @@ namespace Grpc.Testing { } } + /// <summary>Field number for the "server_sleep_us" field.</summary> + public const int ServerSleepUsFieldNumber = 15; + private int serverSleepUs_; + /// <summary> + /// Amount to sleep when invoking server + /// </summary> + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int ServerSleepUs { + get { return serverSleepUs_; } + set { + serverSleepUs_ = value; + } + } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as RequestParams); @@ -605,6 +621,7 @@ namespace Grpc.Testing { if (ServerDie != other.ServerDie) return false; if (BinaryErrorDetails != other.BinaryErrorDetails) return false; if (!object.Equals(ExpectedError, other.ExpectedError)) return false; + if (ServerSleepUs != other.ServerSleepUs) return false; return true; } @@ -625,6 +642,7 @@ namespace Grpc.Testing { if (ServerDie != false) hash ^= ServerDie.GetHashCode(); if (BinaryErrorDetails.Length != 0) hash ^= BinaryErrorDetails.GetHashCode(); if (expectedError_ != null) hash ^= ExpectedError.GetHashCode(); + if (ServerSleepUs != 0) hash ^= ServerSleepUs.GetHashCode(); return hash; } @@ -691,6 +709,10 @@ namespace Grpc.Testing { output.WriteRawTag(114); output.WriteMessage(ExpectedError); } + if (ServerSleepUs != 0) { + output.WriteRawTag(120); + output.WriteInt32(ServerSleepUs); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -738,6 +760,9 @@ namespace Grpc.Testing { if (expectedError_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(ExpectedError); } + if (ServerSleepUs != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(ServerSleepUs); + } return size; } @@ -794,6 +819,9 @@ namespace Grpc.Testing { } ExpectedError.MergeFrom(other.ExpectedError); } + if (other.ServerSleepUs != 0) { + ServerSleepUs = other.ServerSleepUs; + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -866,6 +894,10 @@ namespace Grpc.Testing { input.ReadMessage(expectedError_); break; } + case 120: { + ServerSleepUs = input.ReadInt32(); + break; + } } } } diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs index 9a664f3539..f71d6d197d 100644 --- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs @@ -1,5 +1,7 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: src/proto/grpc/testing/metrics.proto +// <auto-generated> +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: src/proto/grpc/testing/metrics.proto +// </auto-generated> // Original file comments: // Copyright 2015-2016 gRPC authors. // diff --git a/src/csharp/Grpc.IntegrationTesting/Payloads.cs b/src/csharp/Grpc.IntegrationTesting/Payloads.cs index f918b9576b..fca8cda6f6 100644 --- a/src/csharp/Grpc.IntegrationTesting/Payloads.cs +++ b/src/csharp/Grpc.IntegrationTesting/Payloads.cs @@ -596,13 +596,22 @@ namespace Grpc.Testing { } switch (other.PayloadCase) { case PayloadOneofCase.BytebufParams: - BytebufParams = other.BytebufParams; + if (BytebufParams == null) { + BytebufParams = new global::Grpc.Testing.ByteBufferParams(); + } + BytebufParams.MergeFrom(other.BytebufParams); break; case PayloadOneofCase.SimpleParams: - SimpleParams = other.SimpleParams; + if (SimpleParams == null) { + SimpleParams = new global::Grpc.Testing.SimpleProtoParams(); + } + SimpleParams.MergeFrom(other.SimpleParams); break; case PayloadOneofCase.ComplexParams: - ComplexParams = other.ComplexParams; + if (ComplexParams == null) { + ComplexParams = new global::Grpc.Testing.ComplexProtoParams(); + } + ComplexParams.MergeFrom(other.ComplexParams); break; } diff --git a/src/csharp/Grpc.IntegrationTesting/Services.cs b/src/csharp/Grpc.IntegrationTesting/Services.cs index 7a0845dffb..4b761706ed 100644 --- a/src/csharp/Grpc.IntegrationTesting/Services.cs +++ b/src/csharp/Grpc.IntegrationTesting/Services.cs @@ -24,28 +24,27 @@ namespace Grpc.Testing { string.Concat( "CiVzcmMvcHJvdG8vZ3JwYy90ZXN0aW5nL3NlcnZpY2VzLnByb3RvEgxncnBj", "LnRlc3RpbmcaJXNyYy9wcm90by9ncnBjL3Rlc3RpbmcvbWVzc2FnZXMucHJv", - "dG8aJHNyYy9wcm90by9ncnBjL3Rlc3RpbmcvY29udHJvbC5wcm90bxoic3Jj", - "L3Byb3RvL2dycGMvdGVzdGluZy9zdGF0cy5wcm90bzKmAwoQQmVuY2htYXJr", - "U2VydmljZRJGCglVbmFyeUNhbGwSGy5ncnBjLnRlc3RpbmcuU2ltcGxlUmVx", - "dWVzdBocLmdycGMudGVzdGluZy5TaW1wbGVSZXNwb25zZRJOCg1TdHJlYW1p", - "bmdDYWxsEhsuZ3JwYy50ZXN0aW5nLlNpbXBsZVJlcXVlc3QaHC5ncnBjLnRl", - "c3RpbmcuU2ltcGxlUmVzcG9uc2UoATABElIKE1N0cmVhbWluZ0Zyb21DbGll", - "bnQSGy5ncnBjLnRlc3RpbmcuU2ltcGxlUmVxdWVzdBocLmdycGMudGVzdGlu", - "Zy5TaW1wbGVSZXNwb25zZSgBElIKE1N0cmVhbWluZ0Zyb21TZXJ2ZXISGy5n", - "cnBjLnRlc3RpbmcuU2ltcGxlUmVxdWVzdBocLmdycGMudGVzdGluZy5TaW1w", - "bGVSZXNwb25zZTABElIKEVN0cmVhbWluZ0JvdGhXYXlzEhsuZ3JwYy50ZXN0", - "aW5nLlNpbXBsZVJlcXVlc3QaHC5ncnBjLnRlc3RpbmcuU2ltcGxlUmVzcG9u", - "c2UoATABMpcCCg1Xb3JrZXJTZXJ2aWNlEkUKCVJ1blNlcnZlchIYLmdycGMu", - "dGVzdGluZy5TZXJ2ZXJBcmdzGhouZ3JwYy50ZXN0aW5nLlNlcnZlclN0YXR1", - "cygBMAESRQoJUnVuQ2xpZW50EhguZ3JwYy50ZXN0aW5nLkNsaWVudEFyZ3Ma", - "Gi5ncnBjLnRlc3RpbmcuQ2xpZW50U3RhdHVzKAEwARJCCglDb3JlQ291bnQS", - "GS5ncnBjLnRlc3RpbmcuQ29yZVJlcXVlc3QaGi5ncnBjLnRlc3RpbmcuQ29y", - "ZVJlc3BvbnNlEjQKClF1aXRXb3JrZXISEi5ncnBjLnRlc3RpbmcuVm9pZBoS", - "LmdycGMudGVzdGluZy5Wb2lkMl4KGFJlcG9ydFFwc1NjZW5hcmlvU2Vydmlj", - "ZRJCCg5SZXBvcnRTY2VuYXJpbxIcLmdycGMudGVzdGluZy5TY2VuYXJpb1Jl", - "c3VsdBoSLmdycGMudGVzdGluZy5Wb2lkYgZwcm90bzM=")); + "dG8aJHNyYy9wcm90by9ncnBjL3Rlc3RpbmcvY29udHJvbC5wcm90bzKmAwoQ", + "QmVuY2htYXJrU2VydmljZRJGCglVbmFyeUNhbGwSGy5ncnBjLnRlc3Rpbmcu", + "U2ltcGxlUmVxdWVzdBocLmdycGMudGVzdGluZy5TaW1wbGVSZXNwb25zZRJO", + "Cg1TdHJlYW1pbmdDYWxsEhsuZ3JwYy50ZXN0aW5nLlNpbXBsZVJlcXVlc3Qa", + "HC5ncnBjLnRlc3RpbmcuU2ltcGxlUmVzcG9uc2UoATABElIKE1N0cmVhbWlu", + "Z0Zyb21DbGllbnQSGy5ncnBjLnRlc3RpbmcuU2ltcGxlUmVxdWVzdBocLmdy", + "cGMudGVzdGluZy5TaW1wbGVSZXNwb25zZSgBElIKE1N0cmVhbWluZ0Zyb21T", + "ZXJ2ZXISGy5ncnBjLnRlc3RpbmcuU2ltcGxlUmVxdWVzdBocLmdycGMudGVz", + "dGluZy5TaW1wbGVSZXNwb25zZTABElIKEVN0cmVhbWluZ0JvdGhXYXlzEhsu", + "Z3JwYy50ZXN0aW5nLlNpbXBsZVJlcXVlc3QaHC5ncnBjLnRlc3RpbmcuU2lt", + "cGxlUmVzcG9uc2UoATABMpcCCg1Xb3JrZXJTZXJ2aWNlEkUKCVJ1blNlcnZl", + "chIYLmdycGMudGVzdGluZy5TZXJ2ZXJBcmdzGhouZ3JwYy50ZXN0aW5nLlNl", + "cnZlclN0YXR1cygBMAESRQoJUnVuQ2xpZW50EhguZ3JwYy50ZXN0aW5nLkNs", + "aWVudEFyZ3MaGi5ncnBjLnRlc3RpbmcuQ2xpZW50U3RhdHVzKAEwARJCCglD", + "b3JlQ291bnQSGS5ncnBjLnRlc3RpbmcuQ29yZVJlcXVlc3QaGi5ncnBjLnRl", + "c3RpbmcuQ29yZVJlc3BvbnNlEjQKClF1aXRXb3JrZXISEi5ncnBjLnRlc3Rp", + "bmcuVm9pZBoSLmdycGMudGVzdGluZy5Wb2lkMl4KGFJlcG9ydFFwc1NjZW5h", + "cmlvU2VydmljZRJCCg5SZXBvcnRTY2VuYXJpbxIcLmdycGMudGVzdGluZy5T", + "Y2VuYXJpb1Jlc3VsdBoSLmdycGMudGVzdGluZy5Wb2lkYgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, - new pbr::FileDescriptor[] { global::Grpc.Testing.MessagesReflection.Descriptor, global::Grpc.Testing.ControlReflection.Descriptor, global::Grpc.Testing.StatsReflection.Descriptor, }, + new pbr::FileDescriptor[] { global::Grpc.Testing.MessagesReflection.Descriptor, global::Grpc.Testing.ControlReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(null, null)); } #endregion diff --git a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs index bfae4ee6ac..d2e4f2e4a5 100644 --- a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs @@ -1,5 +1,7 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: src/proto/grpc/testing/services.proto +// <auto-generated> +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: src/proto/grpc/testing/services.proto +// </auto-generated> // Original file comments: // Copyright 2015 gRPC authors. // diff --git a/src/csharp/Grpc.IntegrationTesting/Stats.cs b/src/csharp/Grpc.IntegrationTesting/Stats.cs index 23b56df6bd..e082ae7719 100644 --- a/src/csharp/Grpc.IntegrationTesting/Stats.cs +++ b/src/csharp/Grpc.IntegrationTesting/Stats.cs @@ -23,28 +23,30 @@ namespace Grpc.Testing { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( "CiJzcmMvcHJvdG8vZ3JwYy90ZXN0aW5nL3N0YXRzLnByb3RvEgxncnBjLnRl", - "c3RpbmcikQEKC1NlcnZlclN0YXRzEhQKDHRpbWVfZWxhcHNlZBgBIAEoARIR", - "Cgl0aW1lX3VzZXIYAiABKAESEwoLdGltZV9zeXN0ZW0YAyABKAESFgoOdG90", - "YWxfY3B1X3RpbWUYBCABKAQSFQoNaWRsZV9jcHVfdGltZRgFIAEoBBIVCg1j", - "cV9wb2xsX2NvdW50GAYgASgEIjsKD0hpc3RvZ3JhbVBhcmFtcxISCgpyZXNv", - "bHV0aW9uGAEgASgBEhQKDG1heF9wb3NzaWJsZRgCIAEoASJ3Cg1IaXN0b2dy", - "YW1EYXRhEg4KBmJ1Y2tldBgBIAMoDRIQCghtaW5fc2VlbhgCIAEoARIQCght", - "YXhfc2VlbhgDIAEoARILCgNzdW0YBCABKAESFgoOc3VtX29mX3NxdWFyZXMY", - "BSABKAESDQoFY291bnQYBiABKAEiOAoSUmVxdWVzdFJlc3VsdENvdW50EhMK", - "C3N0YXR1c19jb2RlGAEgASgFEg0KBWNvdW50GAIgASgDIs0BCgtDbGllbnRT", - "dGF0cxIuCglsYXRlbmNpZXMYASABKAsyGy5ncnBjLnRlc3RpbmcuSGlzdG9n", - "cmFtRGF0YRIUCgx0aW1lX2VsYXBzZWQYAiABKAESEQoJdGltZV91c2VyGAMg", - "ASgBEhMKC3RpbWVfc3lzdGVtGAQgASgBEjkKD3JlcXVlc3RfcmVzdWx0cxgF", - "IAMoCzIgLmdycGMudGVzdGluZy5SZXF1ZXN0UmVzdWx0Q291bnQSFQoNY3Ff", - "cG9sbF9jb3VudBgGIAEoBGIGcHJvdG8z")); + "c3RpbmcaH3NyYy9wcm90by9ncnBjL2NvcmUvc3RhdHMucHJvdG8itwEKC1Nl", + "cnZlclN0YXRzEhQKDHRpbWVfZWxhcHNlZBgBIAEoARIRCgl0aW1lX3VzZXIY", + "AiABKAESEwoLdGltZV9zeXN0ZW0YAyABKAESFgoOdG90YWxfY3B1X3RpbWUY", + "BCABKAQSFQoNaWRsZV9jcHVfdGltZRgFIAEoBBIVCg1jcV9wb2xsX2NvdW50", + "GAYgASgEEiQKCmNvcmVfc3RhdHMYByABKAsyEC5ncnBjLmNvcmUuU3RhdHMi", + "OwoPSGlzdG9ncmFtUGFyYW1zEhIKCnJlc29sdXRpb24YASABKAESFAoMbWF4", + "X3Bvc3NpYmxlGAIgASgBIncKDUhpc3RvZ3JhbURhdGESDgoGYnVja2V0GAEg", + "AygNEhAKCG1pbl9zZWVuGAIgASgBEhAKCG1heF9zZWVuGAMgASgBEgsKA3N1", + "bRgEIAEoARIWCg5zdW1fb2Zfc3F1YXJlcxgFIAEoARINCgVjb3VudBgGIAEo", + "ASI4ChJSZXF1ZXN0UmVzdWx0Q291bnQSEwoLc3RhdHVzX2NvZGUYASABKAUS", + "DQoFY291bnQYAiABKAMi8wEKC0NsaWVudFN0YXRzEi4KCWxhdGVuY2llcxgB", + "IAEoCzIbLmdycGMudGVzdGluZy5IaXN0b2dyYW1EYXRhEhQKDHRpbWVfZWxh", + "cHNlZBgCIAEoARIRCgl0aW1lX3VzZXIYAyABKAESEwoLdGltZV9zeXN0ZW0Y", + "BCABKAESOQoPcmVxdWVzdF9yZXN1bHRzGAUgAygLMiAuZ3JwYy50ZXN0aW5n", + "LlJlcXVlc3RSZXN1bHRDb3VudBIVCg1jcV9wb2xsX2NvdW50GAYgASgEEiQK", + "CmNvcmVfc3RhdHMYByABKAsyEC5ncnBjLmNvcmUuU3RhdHNiBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, - new pbr::FileDescriptor[] { }, + new pbr::FileDescriptor[] { global::Grpc.Core.StatsReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ServerStats), global::Grpc.Testing.ServerStats.Parser, new[]{ "TimeElapsed", "TimeUser", "TimeSystem", "TotalCpuTime", "IdleCpuTime", "CqPollCount" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ServerStats), global::Grpc.Testing.ServerStats.Parser, new[]{ "TimeElapsed", "TimeUser", "TimeSystem", "TotalCpuTime", "IdleCpuTime", "CqPollCount", "CoreStats" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.HistogramParams), global::Grpc.Testing.HistogramParams.Parser, new[]{ "Resolution", "MaxPossible" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.HistogramData), global::Grpc.Testing.HistogramData.Parser, new[]{ "Bucket", "MinSeen", "MaxSeen", "Sum", "SumOfSquares", "Count" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.RequestResultCount), global::Grpc.Testing.RequestResultCount.Parser, new[]{ "StatusCode", "Count" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientStats), global::Grpc.Testing.ClientStats.Parser, new[]{ "Latencies", "TimeElapsed", "TimeUser", "TimeSystem", "RequestResults", "CqPollCount" }, null, null, null) + new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientStats), global::Grpc.Testing.ClientStats.Parser, new[]{ "Latencies", "TimeElapsed", "TimeUser", "TimeSystem", "RequestResults", "CqPollCount", "CoreStats" }, null, null, null) })); } #endregion @@ -81,6 +83,7 @@ namespace Grpc.Testing { totalCpuTime_ = other.totalCpuTime_; idleCpuTime_ = other.idleCpuTime_; cqPollCount_ = other.cqPollCount_; + CoreStats = other.coreStats_ != null ? other.CoreStats.Clone() : null; } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -173,6 +176,20 @@ namespace Grpc.Testing { } } + /// <summary>Field number for the "core_stats" field.</summary> + public const int CoreStatsFieldNumber = 7; + private global::Grpc.Core.Stats coreStats_; + /// <summary> + /// Core library stats + /// </summary> + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public global::Grpc.Core.Stats CoreStats { + get { return coreStats_; } + set { + coreStats_ = value; + } + } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ServerStats); @@ -192,6 +209,7 @@ namespace Grpc.Testing { if (TotalCpuTime != other.TotalCpuTime) return false; if (IdleCpuTime != other.IdleCpuTime) return false; if (CqPollCount != other.CqPollCount) return false; + if (!object.Equals(CoreStats, other.CoreStats)) return false; return true; } @@ -204,6 +222,7 @@ namespace Grpc.Testing { if (TotalCpuTime != 0UL) hash ^= TotalCpuTime.GetHashCode(); if (IdleCpuTime != 0UL) hash ^= IdleCpuTime.GetHashCode(); if (CqPollCount != 0UL) hash ^= CqPollCount.GetHashCode(); + if (coreStats_ != null) hash ^= CoreStats.GetHashCode(); return hash; } @@ -238,6 +257,10 @@ namespace Grpc.Testing { output.WriteRawTag(48); output.WriteUInt64(CqPollCount); } + if (coreStats_ != null) { + output.WriteRawTag(58); + output.WriteMessage(CoreStats); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -261,6 +284,9 @@ namespace Grpc.Testing { if (CqPollCount != 0UL) { size += 1 + pb::CodedOutputStream.ComputeUInt64Size(CqPollCount); } + if (coreStats_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(CoreStats); + } return size; } @@ -287,6 +313,12 @@ namespace Grpc.Testing { if (other.CqPollCount != 0UL) { CqPollCount = other.CqPollCount; } + if (other.coreStats_ != null) { + if (coreStats_ == null) { + coreStats_ = new global::Grpc.Core.Stats(); + } + CoreStats.MergeFrom(other.CoreStats); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -321,6 +353,13 @@ namespace Grpc.Testing { CqPollCount = input.ReadUInt64(); break; } + case 58: { + if (coreStats_ == null) { + coreStats_ = new global::Grpc.Core.Stats(); + } + input.ReadMessage(coreStats_); + break; + } } } } @@ -909,6 +948,7 @@ namespace Grpc.Testing { timeSystem_ = other.timeSystem_; requestResults_ = other.requestResults_.Clone(); cqPollCount_ = other.cqPollCount_; + CoreStats = other.coreStats_ != null ? other.CoreStats.Clone() : null; } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -993,6 +1033,20 @@ namespace Grpc.Testing { } } + /// <summary>Field number for the "core_stats" field.</summary> + public const int CoreStatsFieldNumber = 7; + private global::Grpc.Core.Stats coreStats_; + /// <summary> + /// Core library stats + /// </summary> + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public global::Grpc.Core.Stats CoreStats { + get { return coreStats_; } + set { + coreStats_ = value; + } + } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ClientStats); @@ -1012,6 +1066,7 @@ namespace Grpc.Testing { if (TimeSystem != other.TimeSystem) return false; if(!requestResults_.Equals(other.requestResults_)) return false; if (CqPollCount != other.CqPollCount) return false; + if (!object.Equals(CoreStats, other.CoreStats)) return false; return true; } @@ -1024,6 +1079,7 @@ namespace Grpc.Testing { if (TimeSystem != 0D) hash ^= TimeSystem.GetHashCode(); hash ^= requestResults_.GetHashCode(); if (CqPollCount != 0UL) hash ^= CqPollCount.GetHashCode(); + if (coreStats_ != null) hash ^= CoreStats.GetHashCode(); return hash; } @@ -1055,6 +1111,10 @@ namespace Grpc.Testing { output.WriteRawTag(48); output.WriteUInt64(CqPollCount); } + if (coreStats_ != null) { + output.WriteRawTag(58); + output.WriteMessage(CoreStats); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1076,6 +1136,9 @@ namespace Grpc.Testing { if (CqPollCount != 0UL) { size += 1 + pb::CodedOutputStream.ComputeUInt64Size(CqPollCount); } + if (coreStats_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(CoreStats); + } return size; } @@ -1103,6 +1166,12 @@ namespace Grpc.Testing { if (other.CqPollCount != 0UL) { CqPollCount = other.CqPollCount; } + if (other.coreStats_ != null) { + if (coreStats_ == null) { + coreStats_ = new global::Grpc.Core.Stats(); + } + CoreStats.MergeFrom(other.CoreStats); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1140,6 +1209,13 @@ namespace Grpc.Testing { CqPollCount = input.ReadUInt64(); break; } + case 58: { + if (coreStats_ == null) { + coreStats_ = new global::Grpc.Core.Stats(); + } + input.ReadMessage(coreStats_); + break; + } } } } diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs index b419dd1702..c0d147c150 100644 --- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs @@ -1,5 +1,7 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: src/proto/grpc/testing/test.proto +// <auto-generated> +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: src/proto/grpc/testing/test.proto +// </auto-generated> // Original file comments: // Copyright 2015-2016 gRPC authors. // diff --git a/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs index eefdb50e39..bb57a6968f 100644 --- a/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs +++ b/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs @@ -43,7 +43,7 @@ namespace Grpc.Microbenchmarks public void Run(int threadCount, int iterations, bool useSharedRegistry) { Console.WriteLine(string.Format("CompletionRegistryBenchmark: threads={0}, iterations={1}, useSharedRegistry={2}", threadCount, iterations, useSharedRegistry)); - CompletionRegistry sharedRegistry = useSharedRegistry ? new CompletionRegistry(environment, () => BatchContextSafeHandle.Create()) : null; + CompletionRegistry sharedRegistry = useSharedRegistry ? new CompletionRegistry(environment, () => BatchContextSafeHandle.Create(), () => RequestCallContextSafeHandle.Create()) : null; var threadedBenchmark = new ThreadedBenchmark(threadCount, () => ThreadBody(iterations, sharedRegistry)); threadedBenchmark.Run(); // TODO: parametrize by number of pending completions @@ -51,7 +51,7 @@ namespace Grpc.Microbenchmarks private void ThreadBody(int iterations, CompletionRegistry optionalSharedRegistry) { - var completionRegistry = optionalSharedRegistry ?? new CompletionRegistry(environment, () => BatchContextSafeHandle.Create()); + var completionRegistry = optionalSharedRegistry ?? new CompletionRegistry(environment, () => throw new NotImplementedException(), () => throw new NotImplementedException()); var ctx = BatchContextSafeHandle.Create(); var stopwatch = Stopwatch.StartNew(); diff --git a/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs index da4f35ff96..390c062298 100644 --- a/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs +++ b/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs @@ -52,7 +52,7 @@ namespace Grpc.Microbenchmarks private void ThreadBody(int iterations, int payloadSize) { - var completionRegistry = new CompletionRegistry(environment, () => environment.BatchContextPool.Lease()); + var completionRegistry = new CompletionRegistry(environment, () => environment.BatchContextPool.Lease(), () => throw new NotImplementedException()); var cq = CompletionQueueSafeHandle.CreateAsync(completionRegistry); var call = CreateFakeCall(cq); diff --git a/src/csharp/Grpc.Reflection/Reflection.cs b/src/csharp/Grpc.Reflection/Reflection.cs index 86e9aace8c..60090e5364 100644 --- a/src/csharp/Grpc.Reflection/Reflection.cs +++ b/src/csharp/Grpc.Reflection/Reflection.cs @@ -345,7 +345,10 @@ namespace Grpc.Reflection.V1Alpha { FileContainingSymbol = other.FileContainingSymbol; break; case MessageRequestOneofCase.FileContainingExtension: - FileContainingExtension = other.FileContainingExtension; + if (FileContainingExtension == null) { + FileContainingExtension = new global::Grpc.Reflection.V1Alpha.ExtensionRequest(); + } + FileContainingExtension.MergeFrom(other.FileContainingExtension); break; case MessageRequestOneofCase.AllExtensionNumbersOfType: AllExtensionNumbersOfType = other.AllExtensionNumbersOfType; @@ -816,16 +819,28 @@ namespace Grpc.Reflection.V1Alpha { } switch (other.MessageResponseCase) { case MessageResponseOneofCase.FileDescriptorResponse: - FileDescriptorResponse = other.FileDescriptorResponse; + if (FileDescriptorResponse == null) { + FileDescriptorResponse = new global::Grpc.Reflection.V1Alpha.FileDescriptorResponse(); + } + FileDescriptorResponse.MergeFrom(other.FileDescriptorResponse); break; case MessageResponseOneofCase.AllExtensionNumbersResponse: - AllExtensionNumbersResponse = other.AllExtensionNumbersResponse; + if (AllExtensionNumbersResponse == null) { + AllExtensionNumbersResponse = new global::Grpc.Reflection.V1Alpha.ExtensionNumberResponse(); + } + AllExtensionNumbersResponse.MergeFrom(other.AllExtensionNumbersResponse); break; case MessageResponseOneofCase.ListServicesResponse: - ListServicesResponse = other.ListServicesResponse; + if (ListServicesResponse == null) { + ListServicesResponse = new global::Grpc.Reflection.V1Alpha.ListServiceResponse(); + } + ListServicesResponse.MergeFrom(other.ListServicesResponse); break; case MessageResponseOneofCase.ErrorResponse: - ErrorResponse = other.ErrorResponse; + if (ErrorResponse == null) { + ErrorResponse = new global::Grpc.Reflection.V1Alpha.ErrorResponse(); + } + ErrorResponse.MergeFrom(other.ErrorResponse); break; } diff --git a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs index 58439577e3..0195186eba 100644 --- a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs +++ b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs @@ -1,5 +1,7 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: grpc/reflection/v1alpha/reflection.proto +// <auto-generated> +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: grpc/reflection/v1alpha/reflection.proto +// </auto-generated> // Original file comments: // Copyright 2016 gRPC authors. // diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index 24d779e1e5..6875d40aa0 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -226,17 +226,22 @@ grpcsharp_batch_context_destroy(grpcsharp_batch_context* ctx) { } GPR_EXPORT void GPR_CALLTYPE -grpcsharp_request_call_context_destroy(grpcsharp_request_call_context* ctx) { - if (!ctx) { - return; - } +grpcsharp_request_call_context_reset(grpcsharp_request_call_context* ctx) { /* NOTE: ctx->server_rpc_new.call is not destroyed because callback handler is supposed to take its ownership. */ grpc_call_details_destroy(&(ctx->call_details)); grpcsharp_metadata_array_destroy_metadata_only(&(ctx->request_metadata)); + memset(ctx, 0, sizeof(grpcsharp_request_call_context)); +} +GPR_EXPORT void GPR_CALLTYPE +grpcsharp_request_call_context_destroy(grpcsharp_request_call_context* ctx) { + if (!ctx) { + return; + } + grpcsharp_request_call_context_reset(ctx); gpr_free(ctx); } diff --git a/src/csharp/tests.json b/src/csharp/tests.json index 82573edecb..469328af1a 100644 --- a/src/csharp/tests.json +++ b/src/csharp/tests.json @@ -14,6 +14,7 @@ "Grpc.Core.Tests.CallCancellationTest", "Grpc.Core.Tests.CallCredentialsTest", "Grpc.Core.Tests.CallOptionsTest", + "Grpc.Core.Tests.ChannelConnectivityTest", "Grpc.Core.Tests.ChannelCredentialsTest", "Grpc.Core.Tests.ChannelOptionsTest", "Grpc.Core.Tests.ChannelTest", diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index 62c4e10b99..cf0b07e8c0 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -34,6 +34,19 @@ $BINDIR/interop_server --port=5051 --max_send_message_size=8388608 --use_tls & # Kill them when this script exits. trap 'kill -9 `jobs -p` ; echo "EXIT TIME: $(date)"' EXIT +# Boot Xcode first with several retries since Xcode might fail due to a bug: +# http://www.openradar.me/29785686 +xcrun simctl list | egrep 'iPhone 6 \(' +udid=`xcrun simctl list | egrep 'iPhone 6 \(.*\) \(.*\)' | sed -E 's/ *iPhone 6 \(([^\)]*)\).*/\1/g' | head -n 1` +retries=0 +while [ $retries -lt 3 ] && ! open -a Simulator --args -CurrentDeviceUDID $udid ; do +retries=$(($retries+1)) +done +if [ $retries == 3 ]; then + echo "Xcode simulator failed to start after 3 retries." + exit 1 +fi + # xcodebuild is very verbose. We filter its output and tell Bash to fail if any # element of the pipe fails. # TODO(jcanizales): Use xctool instead? Issue #2540. diff --git a/src/php/ext/grpc/channel_credentials.c b/src/php/ext/grpc/channel_credentials.c index 86e4f46c67..d120d6e90f 100644 --- a/src/php/ext/grpc/channel_credentials.c +++ b/src/php/ext/grpc/channel_credentials.c @@ -35,6 +35,7 @@ #include <zend_hash.h> #include <grpc/support/alloc.h> +#include <grpc/support/string_util.h> #include <grpc/grpc.h> #include <grpc/grpc_security.h> @@ -46,10 +47,11 @@ static char *default_pem_root_certs = NULL; static grpc_ssl_roots_override_result get_ssl_roots_override( char **pem_root_certs) { - *pem_root_certs = default_pem_root_certs; - if (default_pem_root_certs == NULL) { + if (!default_pem_root_certs) { + *pem_root_certs = NULL; return GRPC_SSL_ROOTS_OVERRIDE_FAIL; } + *pem_root_certs = gpr_strdup(default_pem_root_certs); return GRPC_SSL_ROOTS_OVERRIDE_OK; } @@ -101,7 +103,7 @@ PHP_METHOD(ChannelCredentials, setDefaultRootsPem) { "setDefaultRootsPem expects 1 string", 1 TSRMLS_CC); return; } - default_pem_root_certs = gpr_malloc((pem_roots_length + 1) * sizeof(char)); + default_pem_root_certs = gpr_realloc(default_pem_root_certs, (pem_roots_length + 1) * sizeof(char)); memcpy(default_pem_root_certs, pem_roots, pem_roots_length + 1); } diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index 564772527e..8b913ac949 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -342,6 +342,170 @@ class Call(six.with_metaclass(abc.ABCMeta, RpcContext)): raise NotImplementedError() +############## Invocation-Side Interceptor Interfaces & Classes ############## + + +class ClientCallDetails(six.with_metaclass(abc.ABCMeta)): + """Describes an RPC to be invoked. + + This is an EXPERIMENTAL API. + + Attributes: + method: The method name of the RPC. + timeout: An optional duration of time in seconds to allow for the RPC. + metadata: Optional :term:`metadata` to be transmitted to + the service-side of the RPC. + credentials: An optional CallCredentials for the RPC. + """ + + +class UnaryUnaryClientInterceptor(six.with_metaclass(abc.ABCMeta)): + """Affords intercepting unary-unary invocations. + + This is an EXPERIMENTAL API. + """ + + @abc.abstractmethod + def intercept_unary_unary(self, continuation, client_call_details, request): + """Intercepts a unary-unary invocation asynchronously. + + Args: + continuation: A function that proceeds with the invocation by + executing the next interceptor in chain or invoking the + actual RPC on the underlying Channel. It is the interceptor's + responsibility to call it if it decides to move the RPC forward. + The interceptor can use + `response_future = continuation(client_call_details, request)` + to continue with the RPC. `continuation` returns an object that is + both a Call for the RPC and a Future. In the event of RPC + completion, the return Call-Future's result value will be + the response message of the RPC. Should the event terminate + with non-OK status, the returned Call-Future's exception value + will be an RpcError. + client_call_details: A ClientCallDetails object describing the + outgoing RPC. + request: The request value for the RPC. + + Returns: + An object that is both a Call for the RPC and a Future. + In the event of RPC completion, the return Call-Future's + result value will be the response message of the RPC. + Should the event terminate with non-OK status, the returned + Call-Future's exception value will be an RpcError. + """ + raise NotImplementedError() + + +class UnaryStreamClientInterceptor(six.with_metaclass(abc.ABCMeta)): + """Affords intercepting unary-stream invocations. + + This is an EXPERIMENTAL API. + """ + + @abc.abstractmethod + def intercept_unary_stream(self, continuation, client_call_details, + request): + """Intercepts a unary-stream invocation. + + Args: + continuation: A function that proceeds with the invocation by + executing the next interceptor in chain or invoking the + actual RPC on the underlying Channel. It is the interceptor's + responsibility to call it if it decides to move the RPC forward. + The interceptor can use + `response_iterator = continuation(client_call_details, request)` + to continue with the RPC. `continuation` returns an object that is + both a Call for the RPC and an iterator for response values. + Drawing response values from the returned Call-iterator may + raise RpcError indicating termination of the RPC with non-OK + status. + client_call_details: A ClientCallDetails object describing the + outgoing RPC. + request: The request value for the RPC. + + Returns: + An object that is both a Call for the RPC and an iterator of + response values. Drawing response values from the returned + Call-iterator may raise RpcError indicating termination of + the RPC with non-OK status. + """ + raise NotImplementedError() + + +class StreamUnaryClientInterceptor(six.with_metaclass(abc.ABCMeta)): + """Affords intercepting stream-unary invocations. + + This is an EXPERIMENTAL API. + """ + + @abc.abstractmethod + def intercept_stream_unary(self, continuation, client_call_details, + request_iterator): + """Intercepts a stream-unary invocation asynchronously. + + Args: + continuation: A function that proceeds with the invocation by + executing the next interceptor in chain or invoking the + actual RPC on the underlying Channel. It is the interceptor's + responsibility to call it if it decides to move the RPC forward. + The interceptor can use + `response_future = continuation(client_call_details, + request_iterator)` + to continue with the RPC. `continuation` returns an object that is + both a Call for the RPC and a Future. In the event of RPC completion, + the return Call-Future's result value will be the response message + of the RPC. Should the event terminate with non-OK status, the + returned Call-Future's exception value will be an RpcError. + client_call_details: A ClientCallDetails object describing the + outgoing RPC. + request_iterator: An iterator that yields request values for the RPC. + + Returns: + An object that is both a Call for the RPC and a Future. + In the event of RPC completion, the return Call-Future's + result value will be the response message of the RPC. + Should the event terminate with non-OK status, the returned + Call-Future's exception value will be an RpcError. + """ + raise NotImplementedError() + + +class StreamStreamClientInterceptor(six.with_metaclass(abc.ABCMeta)): + """Affords intercepting stream-stream invocations. + + This is an EXPERIMENTAL API. + """ + + @abc.abstractmethod + def intercept_stream_stream(self, continuation, client_call_details, + request_iterator): + """Intercepts a stream-stream invocation. + + continuation: A function that proceeds with the invocation by + executing the next interceptor in chain or invoking the + actual RPC on the underlying Channel. It is the interceptor's + responsibility to call it if it decides to move the RPC forward. + The interceptor can use + `response_iterator = continuation(client_call_details, + request_iterator)` + to continue with the RPC. `continuation` returns an object that is + both a Call for the RPC and an iterator for response values. + Drawing response values from the returned Call-iterator may + raise RpcError indicating termination of the RPC with non-OK + status. + client_call_details: A ClientCallDetails object describing the + outgoing RPC. + request_iterator: An iterator that yields request values for the RPC. + + Returns: + An object that is both a Call for the RPC and an iterator of + response values. Drawing response values from the returned + Call-iterator may raise RpcError indicating termination of + the RPC with non-OK status. + """ + raise NotImplementedError() + + ############ Authentication & Authorization Interfaces & Classes ############# @@ -835,27 +999,47 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)): raise NotImplementedError() @abc.abstractmethod + def abort(self, code, details): + """Raises an exception to terminate the RPC with a non-OK status. + + The code and details passed as arguments will supercede any existing + ones. + + Args: + code: A StatusCode object to be sent to the client. + It must not be StatusCode.OK. + details: An ASCII-encodable string to be sent to the client upon + termination of the RPC. + + Raises: + Exception: An exception is always raised to signal the abortion the + RPC to the gRPC runtime. + """ + raise NotImplementedError() + + @abc.abstractmethod def set_code(self, code): """Sets the value to be used as status code upon RPC completion. - This method need not be called by method implementations if they wish the - gRPC runtime to determine the status code of the RPC. + This method need not be called by method implementations if they wish + the gRPC runtime to determine the status code of the RPC. - Args: - code: A StatusCode object to be sent to the client. - """ + Args: + code: A StatusCode object to be sent to the client. + """ raise NotImplementedError() @abc.abstractmethod def set_details(self, details): """Sets the value to be used as detail string upon RPC completion. - This method need not be called by method implementations if they have no - details to transmit. + This method need not be called by method implementations if they have + no details to transmit. - Args: - details: An arbitrary string to be sent to the client upon completion. - """ + Args: + details: An ASCII-encodable string to be sent to the client upon + termination of the RPC. + """ raise NotImplementedError() @@ -942,6 +1126,34 @@ class ServiceRpcHandler(six.with_metaclass(abc.ABCMeta, GenericRpcHandler)): raise NotImplementedError() +#################### Service-Side Interceptor Interfaces ##################### + + +class ServerInterceptor(six.with_metaclass(abc.ABCMeta)): + """Affords intercepting incoming RPCs on the service-side. + + This is an EXPERIMENTAL API. + """ + + @abc.abstractmethod + def intercept_service(self, continuation, handler_call_details): + """Intercepts incoming RPCs before handing them over to a handler. + + Args: + continuation: A function that takes a HandlerCallDetails and + proceeds to invoke the next interceptor in the chain, if any, + or the RPC handler lookup logic, with the call details passed + as an argument, and returns an RpcMethodHandler instance if + the RPC is considered serviced, or None otherwise. + handler_call_details: A HandlerCallDetails describing the RPC. + + Returns: + An RpcMethodHandler with which the RPC may be serviced if the + interceptor chooses to service this RPC, or None otherwise. + """ + raise NotImplementedError() + + ############################# Server Interface ############################### @@ -1356,53 +1568,88 @@ def secure_channel(target, credentials, options=None): credentials._credentials) +def intercept_channel(channel, *interceptors): + """Intercepts a channel through a set of interceptors. + + This is an EXPERIMENTAL API. + + Args: + channel: A Channel. + interceptors: Zero or more objects of type + UnaryUnaryClientInterceptor, + UnaryStreamClientInterceptor, + StreamUnaryClientInterceptor, or + StreamStreamClientInterceptor. + Interceptors are given control in the order they are listed. + + Returns: + A Channel that intercepts each invocation via the provided interceptors. + + Raises: + TypeError: If interceptor does not derive from any of + UnaryUnaryClientInterceptor, + UnaryStreamClientInterceptor, + StreamUnaryClientInterceptor, or + StreamStreamClientInterceptor. + """ + from grpc import _interceptor # pylint: disable=cyclic-import + return _interceptor.intercept_channel(channel, *interceptors) + + def server(thread_pool, handlers=None, + interceptors=None, options=None, maximum_concurrent_rpcs=None): """Creates a Server with which RPCs can be serviced. - Args: - thread_pool: A futures.ThreadPoolExecutor to be used by the Server - to execute RPC handlers. - handlers: An optional list of GenericRpcHandlers used for executing RPCs. - More handlers may be added by calling add_generic_rpc_handlers any time - before the server is started. - options: An optional list of key-value pairs (channel args in gRPC runtime) - to configure the channel. - maximum_concurrent_rpcs: The maximum number of concurrent RPCs this server - will service before returning RESOURCE_EXHAUSTED status, or None to - indicate no limit. + Args: + thread_pool: A futures.ThreadPoolExecutor to be used by the Server + to execute RPC handlers. + handlers: An optional list of GenericRpcHandlers used for executing RPCs. + More handlers may be added by calling add_generic_rpc_handlers any time + before the server is started. + interceptors: An optional list of ServerInterceptor objects that observe + and optionally manipulate the incoming RPCs before handing them over to + handlers. The interceptors are given control in the order they are + specified. This is an EXPERIMENTAL API. + options: An optional list of key-value pairs (channel args in gRPC runtime) + to configure the channel. + maximum_concurrent_rpcs: The maximum number of concurrent RPCs this server + will service before returning RESOURCE_EXHAUSTED status, or None to + indicate no limit. - Returns: - A Server object. - """ + Returns: + A Server object. + """ from grpc import _server # pylint: disable=cyclic-import return _server.Server(thread_pool, () if handlers is None else handlers, () - if options is None else options, - maximum_concurrent_rpcs) + if interceptors is None else interceptors, () if + options is None else options, maximum_concurrent_rpcs) ################################### __all__ ################################# -__all__ = ('FutureTimeoutError', 'FutureCancelledError', 'Future', - 'ChannelConnectivity', 'StatusCode', 'RpcError', 'RpcContext', - 'Call', 'ChannelCredentials', 'CallCredentials', - 'AuthMetadataContext', 'AuthMetadataPluginCallback', - 'AuthMetadataPlugin', 'ServerCertificateConfiguration', - 'ServerCredentials', 'UnaryUnaryMultiCallable', - 'UnaryStreamMultiCallable', 'StreamUnaryMultiCallable', - 'StreamStreamMultiCallable', 'Channel', 'ServicerContext', - 'RpcMethodHandler', 'HandlerCallDetails', 'GenericRpcHandler', - 'ServiceRpcHandler', 'Server', 'unary_unary_rpc_method_handler', - 'unary_stream_rpc_method_handler', 'stream_unary_rpc_method_handler', - 'stream_stream_rpc_method_handler', - 'method_handlers_generic_handler', 'ssl_channel_credentials', - 'metadata_call_credentials', 'access_token_call_credentials', - 'composite_call_credentials', 'composite_channel_credentials', - 'ssl_server_credentials', 'ssl_server_certificate_configuration', - 'dynamic_ssl_server_credentials', 'channel_ready_future', - 'insecure_channel', 'secure_channel', 'server',) +__all__ = ( + 'FutureTimeoutError', 'FutureCancelledError', 'Future', + 'ChannelConnectivity', 'StatusCode', 'RpcError', 'RpcContext', 'Call', + 'ChannelCredentials', 'CallCredentials', 'AuthMetadataContext', + 'AuthMetadataPluginCallback', 'AuthMetadataPlugin', 'ClientCallDetails', + 'ServerCertificateConfiguration', 'ServerCredentials', + 'UnaryUnaryMultiCallable', 'UnaryStreamMultiCallable', + 'StreamUnaryMultiCallable', 'StreamStreamMultiCallable', + 'UnaryUnaryClientInterceptor', 'UnaryStreamClientInterceptor', + 'StreamUnaryClientInterceptor', 'StreamStreamClientInterceptor', 'Channel', + 'ServicerContext', 'RpcMethodHandler', 'HandlerCallDetails', + 'GenericRpcHandler', 'ServiceRpcHandler', 'Server', 'ServerInterceptor', + 'unary_unary_rpc_method_handler', 'unary_stream_rpc_method_handler', + 'stream_unary_rpc_method_handler', 'stream_stream_rpc_method_handler', + 'method_handlers_generic_handler', 'ssl_channel_credentials', + 'metadata_call_credentials', 'access_token_call_credentials', + 'composite_call_credentials', 'composite_channel_credentials', + 'ssl_server_credentials', 'ssl_server_certificate_configuration', + 'dynamic_ssl_server_credentials', 'channel_ready_future', + 'insecure_channel', 'secure_channel', 'intercept_channel', 'server',) ############################### Extension Shims ################################ diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index cf4ce0941b..d7456a3dd1 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -122,8 +122,8 @@ def _abort(state, code, details): state.code = code state.details = details if state.initial_metadata is None: - state.initial_metadata = _common.EMPTY_METADATA - state.trailing_metadata = _common.EMPTY_METADATA + state.initial_metadata = () + state.trailing_metadata = () def _handle_event(event, state, response_deserializer): @@ -202,8 +202,7 @@ def _consume_request_iterator(request_iterator, state, call, else: operations = (cygrpc.operation_send_message( serialized_request, _EMPTY_FLAGS),) - call.start_client_batch( - cygrpc.Operations(operations), event_handler) + call.start_client_batch(operations, event_handler) state.due.add(cygrpc.OperationType.send_message) while True: state.condition.wait() @@ -218,8 +217,7 @@ def _consume_request_iterator(request_iterator, state, call, if state.code is None: operations = ( cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),) - call.start_client_batch( - cygrpc.Operations(operations), event_handler) + call.start_client_batch(operations, event_handler) state.due.add(cygrpc.OperationType.send_close_from_client) def stop_consumption_thread(timeout): # pylint: disable=unused-argument @@ -321,8 +319,7 @@ class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call): event_handler = _event_handler(self._state, self._call, self._response_deserializer) self._call.start_client_batch( - cygrpc.Operations( - (cygrpc.operation_receive_message(_EMPTY_FLAGS),)), + (cygrpc.operation_receive_message(_EMPTY_FLAGS),), event_handler) self._state.due.add(cygrpc.OperationType.receive_message) elif self._state.code is grpc.StatusCode.OK: @@ -372,14 +369,13 @@ class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call): with self._state.condition: while self._state.initial_metadata is None: self._state.condition.wait() - return _common.to_application_metadata(self._state.initial_metadata) + return self._state.initial_metadata def trailing_metadata(self): with self._state.condition: while self._state.trailing_metadata is None: self._state.condition.wait() - return _common.to_application_metadata( - self._state.trailing_metadata) + return self._state.trailing_metadata def code(self): with self._state.condition: @@ -420,8 +416,7 @@ def _start_unary_request(request, timeout, request_serializer): deadline, deadline_timespec = _deadline(timeout) serialized_request = _common.serialize(request, request_serializer) if serialized_request is None: - state = _RPCState((), _common.EMPTY_METADATA, _common.EMPTY_METADATA, - grpc.StatusCode.INTERNAL, + state = _RPCState((), (), (), grpc.StatusCode.INTERNAL, 'Exception serializing request!') rendezvous = _Rendezvous(state, None, None, deadline) return deadline, deadline_timespec, None, rendezvous @@ -458,8 +453,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): else: state = _RPCState(_UNARY_UNARY_INITIAL_DUE, None, None, None, None) operations = ( - cygrpc.operation_send_initial_metadata( - _common.to_cygrpc_metadata(metadata), _EMPTY_FLAGS), + cygrpc.operation_send_initial_metadata(metadata, _EMPTY_FLAGS), cygrpc.operation_send_message(serialized_request, _EMPTY_FLAGS), cygrpc.operation_send_close_from_client(_EMPTY_FLAGS), cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS), @@ -479,8 +473,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): deadline_timespec) if credentials is not None: call.set_credentials(credentials._credentials) - call_error = call.start_client_batch( - cygrpc.Operations(operations), None) + call_error = call.start_client_batch(operations, None) _check_call_error(call_error, metadata) _handle_event(completion_queue.poll(), state, self._response_deserializer) @@ -509,8 +502,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): event_handler = _event_handler(state, call, self._response_deserializer) with state.condition: - call_error = call.start_client_batch( - cygrpc.Operations(operations), event_handler) + call_error = call.start_client_batch(operations, event_handler) if call_error != cygrpc.CallError.ok: _call_error_set_RPCstate(state, call_error, metadata) return _Rendezvous(state, None, None, deadline) @@ -544,18 +536,15 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): self._response_deserializer) with state.condition: call.start_client_batch( - cygrpc.Operations(( - cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS), - )), event_handler) + (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),), + event_handler) operations = ( cygrpc.operation_send_initial_metadata( - _common.to_cygrpc_metadata(metadata), - _EMPTY_FLAGS), cygrpc.operation_send_message( + metadata, _EMPTY_FLAGS), cygrpc.operation_send_message( serialized_request, _EMPTY_FLAGS), cygrpc.operation_send_close_from_client(_EMPTY_FLAGS), cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),) - call_error = call.start_client_batch( - cygrpc.Operations(operations), event_handler) + call_error = call.start_client_batch(operations, event_handler) if call_error != cygrpc.CallError.ok: _call_error_set_RPCstate(state, call_error, metadata) return _Rendezvous(state, None, None, deadline) @@ -584,16 +573,13 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): call.set_credentials(credentials._credentials) with state.condition: call.start_client_batch( - cygrpc.Operations( - (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)), + (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),), None) operations = ( - cygrpc.operation_send_initial_metadata( - _common.to_cygrpc_metadata(metadata), _EMPTY_FLAGS), + cygrpc.operation_send_initial_metadata(metadata, _EMPTY_FLAGS), cygrpc.operation_receive_message(_EMPTY_FLAGS), cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),) - call_error = call.start_client_batch( - cygrpc.Operations(operations), None) + call_error = call.start_client_batch(operations, None) _check_call_error(call_error, metadata) _consume_request_iterator(request_iterator, state, call, self._request_serializer) @@ -638,16 +624,13 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): event_handler = _event_handler(state, call, self._response_deserializer) with state.condition: call.start_client_batch( - cygrpc.Operations( - (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)), + (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),), event_handler) operations = ( - cygrpc.operation_send_initial_metadata( - _common.to_cygrpc_metadata(metadata), _EMPTY_FLAGS), + cygrpc.operation_send_initial_metadata(metadata, _EMPTY_FLAGS), cygrpc.operation_receive_message(_EMPTY_FLAGS), cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),) - call_error = call.start_client_batch( - cygrpc.Operations(operations), event_handler) + call_error = call.start_client_batch(operations, event_handler) if call_error != cygrpc.CallError.ok: _call_error_set_RPCstate(state, call_error, metadata) return _Rendezvous(state, None, None, deadline) @@ -681,15 +664,12 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable): event_handler = _event_handler(state, call, self._response_deserializer) with state.condition: call.start_client_batch( - cygrpc.Operations( - (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)), + (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),), event_handler) operations = ( - cygrpc.operation_send_initial_metadata( - _common.to_cygrpc_metadata(metadata), _EMPTY_FLAGS), + cygrpc.operation_send_initial_metadata(metadata, _EMPTY_FLAGS), cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),) - call_error = call.start_client_batch( - cygrpc.Operations(operations), event_handler) + call_error = call.start_client_batch(operations, event_handler) if call_error != cygrpc.CallError.ok: _call_error_set_RPCstate(state, call_error, metadata) return _Rendezvous(state, None, None, deadline) diff --git a/src/python/grpcio/grpc/_common.py b/src/python/grpcio/grpc/_common.py index 740d4639db..130fc42630 100644 --- a/src/python/grpcio/grpc/_common.py +++ b/src/python/grpcio/grpc/_common.py @@ -22,8 +22,6 @@ import six import grpc from grpc._cython import cygrpc -EMPTY_METADATA = cygrpc.Metadata(()) - CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY = { cygrpc.ConnectivityState.idle: grpc.ChannelConnectivity.IDLE, @@ -91,21 +89,6 @@ def channel_args(options): return cygrpc.ChannelArgs(cygrpc_args) -def to_cygrpc_metadata(application_metadata): - return EMPTY_METADATA if application_metadata is None else cygrpc.Metadata( - cygrpc.Metadatum(encode(key), encode(value)) - for key, value in application_metadata) - - -def to_application_metadata(cygrpc_metadata): - if cygrpc_metadata is None: - return () - else: - return tuple((decode(key), value - if key[-4:] == b'-bin' else decode(value)) - for key, value in cygrpc_metadata) - - def _transform(message, transformer, exception_message): if transformer is None: return message diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi index 6b3a276097..6361669757 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi @@ -26,20 +26,16 @@ cdef class Call: def _start_batch(self, operations, tag, retain_self): if not self.is_valid: raise ValueError("invalid call object cannot be used from Python") - cdef grpc_call_error result - cdef Operations cy_operations = Operations(operations) - cdef OperationTag operation_tag = OperationTag(tag) + cdef OperationTag operation_tag = OperationTag(tag, operations) if retain_self: operation_tag.operation_call = self else: operation_tag.operation_call = None - operation_tag.batch_operations = cy_operations + operation_tag.store_ops() cpython.Py_INCREF(operation_tag) - with nogil: - result = grpc_call_start_batch( - self.c_call, cy_operations.c_ops, cy_operations.c_nops, + return grpc_call_start_batch( + self.c_call, operation_tag.c_ops, operation_tag.c_nops, <cpython.PyObject *>operation_tag, NULL) - return result def start_client_batch(self, operations, tag): # We don't reference this call in the operations tag because diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi index 4c397f8f64..644df674cc 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi @@ -76,7 +76,7 @@ cdef class Channel: def watch_connectivity_state( self, grpc_connectivity_state last_observed_state, Timespec deadline not None, CompletionQueue queue not None, tag): - cdef OperationTag operation_tag = OperationTag(tag) + cdef OperationTag operation_tag = OperationTag(tag, None) cpython.Py_INCREF(operation_tag) with nogil: grpc_channel_watch_connectivity_state( diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi index 237f430799..140fc357b9 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi @@ -42,7 +42,7 @@ cdef class CompletionQueue: cdef Call operation_call = None cdef CallDetails request_call_details = None cdef object request_metadata = None - cdef Operations batch_operations = None + cdef object batch_operations = None if event.type == GRPC_QUEUE_TIMEOUT: return Event( event.type, False, None, None, None, None, False, None) @@ -61,9 +61,10 @@ cdef class CompletionQueue: user_tag = tag.user_tag operation_call = tag.operation_call request_call_details = tag.request_call_details - if tag.request_metadata is not None: - request_metadata = tuple(tag.request_metadata) - batch_operations = tag.batch_operations + if tag.is_new_request: + request_metadata = _metadata(&tag._c_request_metadata) + grpc_metadata_array_destroy(&tag._c_request_metadata) + batch_operations = tag.release_ops() if tag.is_new_request: # Stuff in the tag not explicitly handled by us needs to live through # the life of the call diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index 246a271893..500086f6cb 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -30,9 +30,13 @@ cdef int _get_metadata( grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX], size_t *num_creds_md, grpc_status_code *status, const char **error_details) with gil: - def callback(Metadata metadata, grpc_status_code status, bytes error_details): + cdef size_t metadata_count + cdef grpc_metadata *c_metadata + def callback(metadata, grpc_status_code status, bytes error_details): if status is StatusCode.ok: - cb(user_data, metadata.c_metadata, metadata.c_count, status, NULL) + _store_c_metadata(metadata, &c_metadata, &metadata_count) + cb(user_data, c_metadata, metadata_count, status, NULL) + _release_c_metadata(c_metadata, metadata_count) else: cb(user_data, NULL, 0, status, error_details) args = context.service_url, context.method_name, callback, diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi index c8f11f8e19..e3cad9acb3 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import logging + # This function will ascii encode unicode string inputs if neccesary. # In Python3, unicode strings are the default str type. @@ -22,3 +24,25 @@ cdef bytes str_to_bytes(object s): return s.encode('ascii') else: raise TypeError('Expected bytes, str, or unicode, not {}'.format(type(s))) + + +cdef bytes _encode(str native_string_or_none): + if native_string_or_none is None: + return b'' + elif isinstance(native_string_or_none, (bytes,)): + return <bytes>native_string_or_none + elif isinstance(native_string_or_none, (unicode,)): + return native_string_or_none.encode('ascii') + else: + raise TypeError('Expected str, not {}'.format(type(native_string_or_none))) + + +cdef str _decode(bytes bytestring): + if isinstance(bytestring, (str,)): + return <str>bytestring + else: + try: + return bytestring.decode('utf8') + except UnicodeDecodeError: + logging.exception('Invalid encoding on %s', bytestring) + return bytestring.decode('latin1') diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pxd.pxi new file mode 100644 index 0000000000..a18c365807 --- /dev/null +++ b/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pxd.pxi @@ -0,0 +1,26 @@ +# Copyright 2017 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +cdef void _store_c_metadata( + metadata, grpc_metadata **c_metadata, size_t *c_count) + + +cdef void _release_c_metadata(grpc_metadata *c_metadata, int count) + + +cdef tuple _metadatum(grpc_slice key_slice, grpc_slice value_slice) + + +cdef tuple _metadata(grpc_metadata_array *c_metadata_array) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pyx.pxi new file mode 100644 index 0000000000..c39fef08fa --- /dev/null +++ b/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pyx.pxi @@ -0,0 +1,62 @@ +# Copyright 2017 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import collections + + +_Metadatum = collections.namedtuple('_Metadatum', ('key', 'value',)) + + +cdef void _store_c_metadata( + metadata, grpc_metadata **c_metadata, size_t *c_count): + if metadata is None: + c_count[0] = 0 + c_metadata[0] = NULL + else: + metadatum_count = len(metadata) + if metadatum_count == 0: + c_count[0] = 0 + c_metadata[0] = NULL + else: + c_count[0] = metadatum_count + c_metadata[0] = <grpc_metadata *>gpr_malloc( + metadatum_count * sizeof(grpc_metadata)) + for index, (key, value) in enumerate(metadata): + encoded_key = _encode(key) + encoded_value = value if encoded_key[-4:] == b'-bin' else _encode(value) + c_metadata[0][index].key = _slice_from_bytes(encoded_key) + c_metadata[0][index].value = _slice_from_bytes(encoded_value) + + +cdef void _release_c_metadata(grpc_metadata *c_metadata, int count): + if 0 < count: + for index in range(count): + grpc_slice_unref(c_metadata[index].key) + grpc_slice_unref(c_metadata[index].value) + gpr_free(c_metadata) + + +cdef tuple _metadatum(grpc_slice key_slice, grpc_slice value_slice): + cdef bytes key = _slice_bytes(key_slice) + cdef bytes value = _slice_bytes(value_slice) + return <tuple>_Metadatum( + _decode(key), value if key[-4:] == b'-bin' else _decode(value)) + + +cdef tuple _metadata(grpc_metadata_array *c_metadata_array): + return tuple( + _metadatum( + c_metadata_array.metadata[index].key, + c_metadata_array.metadata[index].value) + for index in range(c_metadata_array.count)) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi index 9c40ebf0c2..594fdb1a8b 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi @@ -37,10 +37,15 @@ cdef class OperationTag: cdef Server shutting_down_server cdef Call operation_call cdef CallDetails request_call_details - cdef MetadataArray request_metadata - cdef Operations batch_operations + cdef grpc_metadata_array _c_request_metadata + cdef grpc_op *c_ops + cdef size_t c_nops + cdef readonly object _operations cdef bint is_new_request + cdef void store_ops(self) + cdef object release_ops(self) + cdef class Event: @@ -57,7 +62,7 @@ cdef class Event: cdef readonly Call operation_call # For Call.start_batch - cdef readonly Operations batch_operations + cdef readonly object batch_operations cdef class ByteBuffer: @@ -84,28 +89,15 @@ cdef class ChannelArgs: cdef list args -cdef class Metadatum: - - cdef grpc_metadata c_metadata - cdef void _copy_metadatum(self, grpc_metadata *destination) nogil - - -cdef class Metadata: - - cdef grpc_metadata *c_metadata - cdef readonly size_t c_count - - -cdef class MetadataArray: - - cdef grpc_metadata_array c_metadata_array - - cdef class Operation: cdef grpc_op c_op + cdef bint _c_metadata_needs_release + cdef size_t _c_metadata_count + cdef grpc_metadata *_c_metadata cdef ByteBuffer _received_message - cdef MetadataArray _received_metadata + cdef bint _c_metadata_array_needs_destruction + cdef grpc_metadata_array _c_metadata_array cdef grpc_status_code _received_status_code cdef grpc_slice _status_details cdef int _received_cancelled @@ -113,13 +105,6 @@ cdef class Operation: cdef object references -cdef class Operations: - - cdef grpc_op *c_ops - cdef size_t c_nops - cdef list operations - - cdef class CompressionOptions: cdef grpc_compression_options c_options diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi index e92953b45f..4e49b24050 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi @@ -220,9 +220,26 @@ cdef class CallDetails: cdef class OperationTag: - def __cinit__(self, user_tag): + def __cinit__(self, user_tag, operations): self.user_tag = user_tag self.references = [] + self._operations = operations + + cdef void store_ops(self): + self.c_nops = 0 if self._operations is None else len(self._operations) + if 0 < self.c_nops: + self.c_ops = <grpc_op *>gpr_malloc(sizeof(grpc_op) * self.c_nops) + for index in range(self.c_nops): + self.c_ops[index] = (<Operation>(self._operations[index])).c_op + + cdef object release_ops(self): + if 0 < self.c_nops: + for index, operation in enumerate(self._operations): + (<Operation>operation).c_op = self.c_ops[index] + gpr_free(self.c_ops) + return self._operations + else: + return () cdef class Event: @@ -232,7 +249,7 @@ cdef class Event: CallDetails request_call_details, object request_metadata, bint is_new_request, - Operations batch_operations): + object batch_operations): self.type = type self.success = success self.tag = tag @@ -390,140 +407,13 @@ cdef class ChannelArgs: return self.args[i] -cdef class Metadatum: - - def __cinit__(self, bytes key, bytes value): - self.c_metadata.key = _slice_from_bytes(key) - self.c_metadata.value = _slice_from_bytes(value) - - cdef void _copy_metadatum(self, grpc_metadata *destination) nogil: - destination[0].key = _copy_slice(self.c_metadata.key) - destination[0].value = _copy_slice(self.c_metadata.value) - - @property - def key(self): - return _slice_bytes(self.c_metadata.key) - - @property - def value(self): - return _slice_bytes(self.c_metadata.value) - - def __len__(self): - return 2 - - def __getitem__(self, size_t i): - if i == 0: - return self.key - elif i == 1: - return self.value - else: - raise IndexError("index must be 0 (key) or 1 (value)") - - def __iter__(self): - return iter((self.key, self.value)) - - def __dealloc__(self): - grpc_slice_unref(self.c_metadata.key) - grpc_slice_unref(self.c_metadata.value) - -cdef class _MetadataIterator: - - cdef size_t i - cdef size_t _length - cdef object _metadatum_indexable - - def __cinit__(self, length, metadatum_indexable): - self._length = length - self._metadatum_indexable = metadatum_indexable - self.i = 0 - - def __iter__(self): - return self - - def __next__(self): - if self.i < self._length: - result = self._metadatum_indexable[self.i] - self.i = self.i + 1 - return result - else: - raise StopIteration() - - -# TODO(https://github.com/grpc/grpc/issues/7950): Eliminate this; just use an -# ordinary sequence of pairs of bytestrings all the way down to the -# grpc_call_start_batch call. -cdef class Metadata: - """Metadata being passed from application to core.""" - - def __cinit__(self, metadata_iterable): - metadata_sequence = tuple(metadata_iterable) - cdef size_t count = len(metadata_sequence) - with nogil: - grpc_init() - self.c_metadata = <grpc_metadata *>gpr_malloc( - count * sizeof(grpc_metadata)) - self.c_count = count - for index, metadatum in enumerate(metadata_sequence): - self.c_metadata[index].key = grpc_slice_copy( - (<Metadatum>metadatum).c_metadata.key) - self.c_metadata[index].value = grpc_slice_copy( - (<Metadatum>metadatum).c_metadata.value) - - def __dealloc__(self): - with nogil: - for index in range(self.c_count): - grpc_slice_unref(self.c_metadata[index].key) - grpc_slice_unref(self.c_metadata[index].value) - gpr_free(self.c_metadata) - grpc_shutdown() - - def __len__(self): - return self.c_count - - def __getitem__(self, size_t index): - if index < self.c_count: - key = _slice_bytes(self.c_metadata[index].key) - value = _slice_bytes(self.c_metadata[index].value) - return Metadatum(key, value) - else: - raise IndexError() - - def __iter__(self): - return _MetadataIterator(self.c_count, self) - - -cdef class MetadataArray: - """Metadata being passed from core to application.""" - - def __cinit__(self): - with nogil: - grpc_init() - grpc_metadata_array_init(&self.c_metadata_array) - - def __dealloc__(self): - with nogil: - grpc_metadata_array_destroy(&self.c_metadata_array) - grpc_shutdown() - - def __len__(self): - return self.c_metadata_array.count - - def __getitem__(self, size_t i): - if i >= self.c_metadata_array.count: - raise IndexError() - key = _slice_bytes(self.c_metadata_array.metadata[i].key) - value = _slice_bytes(self.c_metadata_array.metadata[i].value) - return Metadatum(key=key, value=value) - - def __iter__(self): - return _MetadataIterator(self.c_metadata_array.count, self) - - cdef class Operation: def __cinit__(self): grpc_init() self.references = [] + self._c_metadata_needs_release = False + self._c_metadata_array_needs_destruction = False self._status_details = grpc_empty_slice() self.is_valid = False @@ -556,13 +446,7 @@ cdef class Operation: if (self.c_op.type != GRPC_OP_RECV_INITIAL_METADATA and self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT): raise TypeError("self must be an operation receiving metadata") - # TODO(https://github.com/grpc/grpc/issues/7950): Drop the "all Cython - # objects must be legitimate for use from Python at any time" policy in - # place today, shift the policy toward "Operation objects are only usable - # while their calls are active", and move this making-a-copy-because-this- - # data-needs-to-live-much-longer-than-the-call-from-which-it-arose to the - # lowest Python layer. - return tuple(self._received_metadata) + return _metadata(&self._c_metadata_array) @property def received_status_code(self): @@ -602,16 +486,21 @@ cdef class Operation: return False if self._received_cancelled == 0 else True def __dealloc__(self): + if self._c_metadata_needs_release: + _release_c_metadata(self._c_metadata, self._c_metadata_count) + if self._c_metadata_array_needs_destruction: + grpc_metadata_array_destroy(&self._c_metadata_array) grpc_slice_unref(self._status_details) grpc_shutdown() -def operation_send_initial_metadata(Metadata metadata, int flags): +def operation_send_initial_metadata(metadata, int flags): cdef Operation op = Operation() op.c_op.type = GRPC_OP_SEND_INITIAL_METADATA op.c_op.flags = flags - op.c_op.data.send_initial_metadata.count = metadata.c_count - op.c_op.data.send_initial_metadata.metadata = metadata.c_metadata - op.references.append(metadata) + _store_c_metadata(metadata, &op._c_metadata, &op._c_metadata_count) + op._c_metadata_needs_release = True + op.c_op.data.send_initial_metadata.count = op._c_metadata_count + op.c_op.data.send_initial_metadata.metadata = op._c_metadata op.is_valid = True return op @@ -633,18 +522,19 @@ def operation_send_close_from_client(int flags): return op def operation_send_status_from_server( - Metadata metadata, grpc_status_code code, bytes details, int flags): + metadata, grpc_status_code code, bytes details, int flags): cdef Operation op = Operation() op.c_op.type = GRPC_OP_SEND_STATUS_FROM_SERVER op.c_op.flags = flags + _store_c_metadata(metadata, &op._c_metadata, &op._c_metadata_count) + op._c_metadata_needs_release = True op.c_op.data.send_status_from_server.trailing_metadata_count = ( - metadata.c_count) - op.c_op.data.send_status_from_server.trailing_metadata = metadata.c_metadata + op._c_metadata_count) + op.c_op.data.send_status_from_server.trailing_metadata = op._c_metadata op.c_op.data.send_status_from_server.status = code grpc_slice_unref(op._status_details) op._status_details = _slice_from_bytes(details) op.c_op.data.send_status_from_server.status_details = &op._status_details - op.references.append(metadata) op.is_valid = True return op @@ -652,9 +542,10 @@ def operation_receive_initial_metadata(int flags): cdef Operation op = Operation() op.c_op.type = GRPC_OP_RECV_INITIAL_METADATA op.c_op.flags = flags - op._received_metadata = MetadataArray() + grpc_metadata_array_init(&op._c_metadata_array) op.c_op.data.receive_initial_metadata.receive_initial_metadata = ( - &op._received_metadata.c_metadata_array) + &op._c_metadata_array) + op._c_metadata_array_needs_destruction = True op.is_valid = True return op @@ -675,9 +566,10 @@ def operation_receive_status_on_client(int flags): cdef Operation op = Operation() op.c_op.type = GRPC_OP_RECV_STATUS_ON_CLIENT op.c_op.flags = flags - op._received_metadata = MetadataArray() + grpc_metadata_array_init(&op._c_metadata_array) op.c_op.data.receive_status_on_client.trailing_metadata = ( - &op._received_metadata.c_metadata_array) + &op._c_metadata_array) + op._c_metadata_array_needs_destruction = True op.c_op.data.receive_status_on_client.status = ( &op._received_status_code) op.c_op.data.receive_status_on_client.status_details = ( @@ -694,59 +586,6 @@ def operation_receive_close_on_server(int flags): return op -cdef class _OperationsIterator: - - cdef size_t i - cdef Operations operations - - def __cinit__(self, Operations operations not None): - self.i = 0 - self.operations = operations - - def __iter__(self): - return self - - def __next__(self): - if self.i < len(self.operations): - result = self.operations[self.i] - self.i = self.i + 1 - return result - else: - raise StopIteration() - - -cdef class Operations: - - def __cinit__(self, operations): - grpc_init() - self.operations = list(operations) # normalize iterable - self.c_ops = NULL - self.c_nops = 0 - for operation in self.operations: - if not isinstance(operation, Operation): - raise TypeError("expected operations to be iterable of Operation") - self.c_nops = len(self.operations) - with nogil: - self.c_ops = <grpc_op *>gpr_malloc(sizeof(grpc_op)*self.c_nops) - for i in range(self.c_nops): - self.c_ops[i] = (<Operation>(self.operations[i])).c_op - - def __len__(self): - return self.c_nops - - def __getitem__(self, size_t i): - # self.operations is never stale; it's only updated from this file - return self.operations[i] - - def __dealloc__(self): - with nogil: - gpr_free(self.c_ops) - grpc_shutdown() - - def __iter__(self): - return _OperationsIterator(self) - - cdef class CompressionOptions: def __cinit__(self): diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index 5f3405936c..f8d7892858 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -78,23 +78,19 @@ cdef class Server: raise ValueError("server must be started and not shutting down") if server_queue not in self.registered_completion_queues: raise ValueError("server_queue must be a registered completion queue") - cdef grpc_call_error result - cdef OperationTag operation_tag = OperationTag(tag) + cdef OperationTag operation_tag = OperationTag(tag, None) operation_tag.operation_call = Call() operation_tag.request_call_details = CallDetails() - operation_tag.request_metadata = MetadataArray() + grpc_metadata_array_init(&operation_tag._c_request_metadata) operation_tag.references.extend([self, call_queue, server_queue]) operation_tag.is_new_request = True - operation_tag.batch_operations = Operations([]) cpython.Py_INCREF(operation_tag) - with nogil: - result = grpc_server_request_call( - self.c_server, &operation_tag.operation_call.c_call, - &operation_tag.request_call_details.c_details, - &operation_tag.request_metadata.c_metadata_array, - call_queue.c_completion_queue, server_queue.c_completion_queue, - <cpython.PyObject *>operation_tag) - return result + return grpc_server_request_call( + self.c_server, &operation_tag.operation_call.c_call, + &operation_tag.request_call_details.c_details, + &operation_tag._c_request_metadata, + call_queue.c_completion_queue, server_queue.c_completion_queue, + <cpython.PyObject *>operation_tag) def register_completion_queue( self, CompletionQueue queue not None): @@ -135,7 +131,7 @@ cdef class Server: cdef _c_shutdown(self, CompletionQueue queue, tag): self.is_shutting_down = True - operation_tag = OperationTag(tag) + operation_tag = OperationTag(tag, None) operation_tag.shutting_down_server = self cpython.Py_INCREF(operation_tag) with nogil: diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pxd b/src/python/grpcio/grpc/_cython/cygrpc.pxd index fc6cc5fb9f..6fc5638d5d 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pxd +++ b/src/python/grpcio/grpc/_cython/cygrpc.pxd @@ -18,6 +18,7 @@ include "_cygrpc/call.pxd.pxi" include "_cygrpc/channel.pxd.pxi" include "_cygrpc/credentials.pxd.pxi" include "_cygrpc/completion_queue.pxd.pxi" +include "_cygrpc/metadata.pxd.pxi" include "_cygrpc/records.pxd.pxi" include "_cygrpc/security.pxd.pxi" include "_cygrpc/server.pxd.pxi" diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx index 57165d5f5a..d605229822 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pyx +++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx @@ -25,6 +25,7 @@ include "_cygrpc/call.pyx.pxi" include "_cygrpc/channel.pyx.pxi" include "_cygrpc/credentials.pyx.pxi" include "_cygrpc/completion_queue.pyx.pxi" +include "_cygrpc/metadata.pyx.pxi" include "_cygrpc/records.pyx.pxi" include "_cygrpc/security.pyx.pxi" include "_cygrpc/server.pyx.pxi" diff --git a/src/python/grpcio/grpc/_interceptor.py b/src/python/grpcio/grpc/_interceptor.py new file mode 100644 index 0000000000..fffb269845 --- /dev/null +++ b/src/python/grpcio/grpc/_interceptor.py @@ -0,0 +1,318 @@ +# Copyright 2017 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Implementation of gRPC Python interceptors.""" + +import collections +import sys + +import grpc + + +class _ServicePipeline(object): + + def __init__(self, interceptors): + self.interceptors = tuple(interceptors) + + def _continuation(self, thunk, index): + return lambda context: self._intercept_at(thunk, index, context) + + def _intercept_at(self, thunk, index, context): + if index < len(self.interceptors): + interceptor = self.interceptors[index] + thunk = self._continuation(thunk, index + 1) + return interceptor.intercept_service(thunk, context) + else: + return thunk(context) + + def execute(self, thunk, context): + return self._intercept_at(thunk, 0, context) + + +def service_pipeline(interceptors): + return _ServicePipeline(interceptors) if interceptors else None + + +class _ClientCallDetails( + collections.namedtuple('_ClientCallDetails', + ('method', 'timeout', 'metadata', + 'credentials')), grpc.ClientCallDetails): + pass + + +class _LocalFailure(grpc.RpcError, grpc.Future, grpc.Call): + + def __init__(self, exception, traceback): + super(_LocalFailure, self).__init__() + self._exception = exception + self._traceback = traceback + + def initial_metadata(self): + return None + + def trailing_metadata(self): + return None + + def code(self): + return grpc.StatusCode.INTERNAL + + def details(self): + return 'Exception raised while intercepting the RPC' + + def cancel(self): + return False + + def cancelled(self): + return False + + def running(self): + return False + + def done(self): + return True + + def result(self, ignored_timeout=None): + raise self._exception + + def exception(self, ignored_timeout=None): + return self._exception + + def traceback(self, ignored_timeout=None): + return self._traceback + + def add_done_callback(self, fn): + fn(self) + + def __iter__(self): + return self + + def next(self): + raise self._exception + + +class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): + + def __init__(self, thunk, method, interceptor): + self._thunk = thunk + self._method = method + self._interceptor = interceptor + + def __call__(self, request, timeout=None, metadata=None, credentials=None): + call_future = self.future( + request, + timeout=timeout, + metadata=metadata, + credentials=credentials) + return call_future.result() + + def with_call(self, request, timeout=None, metadata=None, credentials=None): + call_future = self.future( + request, + timeout=timeout, + metadata=metadata, + credentials=credentials) + return call_future.result(), call_future + + def future(self, request, timeout=None, metadata=None, credentials=None): + + def continuation(client_call_details, request): + return self._thunk(client_call_details.method).future( + request, + timeout=client_call_details.timeout, + metadata=client_call_details.metadata, + credentials=client_call_details.credentials) + + client_call_details = _ClientCallDetails(self._method, timeout, + metadata, credentials) + try: + return self._interceptor.intercept_unary_unary( + continuation, client_call_details, request) + except Exception as exception: # pylint:disable=broad-except + return _LocalFailure(exception, sys.exc_info()[2]) + + +class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): + + def __init__(self, thunk, method, interceptor): + self._thunk = thunk + self._method = method + self._interceptor = interceptor + + def __call__(self, request, timeout=None, metadata=None, credentials=None): + + def continuation(client_call_details, request): + return self._thunk(client_call_details.method)( + request, + timeout=client_call_details.timeout, + metadata=client_call_details.metadata, + credentials=client_call_details.credentials) + + client_call_details = _ClientCallDetails(self._method, timeout, + metadata, credentials) + try: + return self._interceptor.intercept_unary_stream( + continuation, client_call_details, request) + except Exception as exception: # pylint:disable=broad-except + return _LocalFailure(exception, sys.exc_info()[2]) + + +class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): + + def __init__(self, thunk, method, interceptor): + self._thunk = thunk + self._method = method + self._interceptor = interceptor + + def __call__(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None): + call_future = self.future( + request_iterator, + timeout=timeout, + metadata=metadata, + credentials=credentials) + return call_future.result() + + def with_call(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None): + call_future = self.future( + request_iterator, + timeout=timeout, + metadata=metadata, + credentials=credentials) + return call_future.result(), call_future + + def future(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None): + + def continuation(client_call_details, request_iterator): + return self._thunk(client_call_details.method).future( + request_iterator, + timeout=client_call_details.timeout, + metadata=client_call_details.metadata, + credentials=client_call_details.credentials) + + client_call_details = _ClientCallDetails(self._method, timeout, + metadata, credentials) + + try: + return self._interceptor.intercept_stream_unary( + continuation, client_call_details, request_iterator) + except Exception as exception: # pylint:disable=broad-except + return _LocalFailure(exception, sys.exc_info()[2]) + + +class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable): + + def __init__(self, thunk, method, interceptor): + self._thunk = thunk + self._method = method + self._interceptor = interceptor + + def __call__(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None): + + def continuation(client_call_details, request_iterator): + return self._thunk(client_call_details.method)( + request_iterator, + timeout=client_call_details.timeout, + metadata=client_call_details.metadata, + credentials=client_call_details.credentials) + + client_call_details = _ClientCallDetails(self._method, timeout, + metadata, credentials) + + try: + return self._interceptor.intercept_stream_stream( + continuation, client_call_details, request_iterator) + except Exception as exception: # pylint:disable=broad-except + return _LocalFailure(exception, sys.exc_info()[2]) + + +class _Channel(grpc.Channel): + + def __init__(self, channel, interceptor): + self._channel = channel + self._interceptor = interceptor + + def subscribe(self, *args, **kwargs): + self._channel.subscribe(*args, **kwargs) + + def unsubscribe(self, *args, **kwargs): + self._channel.unsubscribe(*args, **kwargs) + + def unary_unary(self, + method, + request_serializer=None, + response_deserializer=None): + thunk = lambda m: self._channel.unary_unary(m, request_serializer, response_deserializer) + if isinstance(self._interceptor, grpc.UnaryUnaryClientInterceptor): + return _UnaryUnaryMultiCallable(thunk, method, self._interceptor) + else: + return thunk(method) + + def unary_stream(self, + method, + request_serializer=None, + response_deserializer=None): + thunk = lambda m: self._channel.unary_stream(m, request_serializer, response_deserializer) + if isinstance(self._interceptor, grpc.UnaryStreamClientInterceptor): + return _UnaryStreamMultiCallable(thunk, method, self._interceptor) + else: + return thunk(method) + + def stream_unary(self, + method, + request_serializer=None, + response_deserializer=None): + thunk = lambda m: self._channel.stream_unary(m, request_serializer, response_deserializer) + if isinstance(self._interceptor, grpc.StreamUnaryClientInterceptor): + return _StreamUnaryMultiCallable(thunk, method, self._interceptor) + else: + return thunk(method) + + def stream_stream(self, + method, + request_serializer=None, + response_deserializer=None): + thunk = lambda m: self._channel.stream_stream(m, request_serializer, response_deserializer) + if isinstance(self._interceptor, grpc.StreamStreamClientInterceptor): + return _StreamStreamMultiCallable(thunk, method, self._interceptor) + else: + return thunk(method) + + +def intercept_channel(channel, *interceptors): + for interceptor in reversed(list(interceptors)): + if not isinstance(interceptor, grpc.UnaryUnaryClientInterceptor) and \ + not isinstance(interceptor, grpc.UnaryStreamClientInterceptor) and \ + not isinstance(interceptor, grpc.StreamUnaryClientInterceptor) and \ + not isinstance(interceptor, grpc.StreamStreamClientInterceptor): + raise TypeError('interceptor must be ' + 'grpc.UnaryUnaryClientInterceptor or ' + 'grpc.UnaryStreamClientInterceptor or ' + 'grpc.StreamUnaryClientInterceptor or ' + 'grpc.StreamStreamClientInterceptor or ') + channel = _Channel(channel, interceptor) + return channel diff --git a/src/python/grpcio/grpc/_plugin_wrapping.py b/src/python/grpcio/grpc/_plugin_wrapping.py index cd17f4a049..f7287956dc 100644 --- a/src/python/grpcio/grpc/_plugin_wrapping.py +++ b/src/python/grpcio/grpc/_plugin_wrapping.py @@ -54,9 +54,7 @@ class _AuthMetadataPluginCallback(grpc.AuthMetadataPluginCallback): 'AuthMetadataPluginCallback raised exception "{}"!'.format( self._state.exception)) if error is None: - self._callback( - _common.to_cygrpc_metadata(metadata), cygrpc.StatusCode.ok, - None) + self._callback(metadata, cygrpc.StatusCode.ok, None) else: self._callback(None, cygrpc.StatusCode.internal, _common.encode(str(error))) diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index 5b4812bffe..8857bd3eb5 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -23,6 +23,7 @@ import six import grpc from grpc import _common +from grpc import _interceptor from grpc._cython import cygrpc from grpc.framework.foundation import callable_util @@ -96,6 +97,7 @@ class _RPCState(object): self.statused = False self.rpc_errors = [] self.callbacks = [] + self.abortion = None def _raise_rpc_error(state): @@ -129,19 +131,17 @@ def _abort(state, call, code, details): effective_details = details if state.details is None else state.details if state.initial_metadata_allowed: operations = (cygrpc.operation_send_initial_metadata( - _common.EMPTY_METADATA, - _EMPTY_FLAGS), cygrpc.operation_send_status_from_server( - _common.to_cygrpc_metadata(state.trailing_metadata), - effective_code, effective_details, _EMPTY_FLAGS),) + (), _EMPTY_FLAGS), cygrpc.operation_send_status_from_server( + state.trailing_metadata, effective_code, effective_details, + _EMPTY_FLAGS),) token = _SEND_INITIAL_METADATA_AND_SEND_STATUS_FROM_SERVER_TOKEN else: operations = (cygrpc.operation_send_status_from_server( - _common.to_cygrpc_metadata(state.trailing_metadata), - effective_code, effective_details, _EMPTY_FLAGS),) + state.trailing_metadata, effective_code, effective_details, + _EMPTY_FLAGS),) token = _SEND_STATUS_FROM_SERVER_TOKEN - call.start_server_batch( - cygrpc.Operations(operations), - _send_status_from_server(state, token)) + call.start_server_batch(operations, + _send_status_from_server(state, token)) state.statused = True state.due.add(token) @@ -237,7 +237,7 @@ class _Context(grpc.ServicerContext): self._state.disable_next_compression = True def invocation_metadata(self): - return _common.to_application_metadata(self._rpc_event.request_metadata) + return self._rpc_event.request_metadata def peer(self): return _common.decode(self._rpc_event.operation_call.peer()) @@ -263,11 +263,9 @@ class _Context(grpc.ServicerContext): else: if self._state.initial_metadata_allowed: operation = cygrpc.operation_send_initial_metadata( - _common.to_cygrpc_metadata(initial_metadata), - _EMPTY_FLAGS) + initial_metadata, _EMPTY_FLAGS) self._rpc_event.operation_call.start_server_batch( - cygrpc.Operations((operation,)), - _send_initial_metadata(self._state)) + (operation,), _send_initial_metadata(self._state)) self._state.initial_metadata_allowed = False self._state.due.add(_SEND_INITIAL_METADATA_TOKEN) else: @@ -275,8 +273,14 @@ class _Context(grpc.ServicerContext): def set_trailing_metadata(self, trailing_metadata): with self._state.condition: - self._state.trailing_metadata = _common.to_cygrpc_metadata( - trailing_metadata) + self._state.trailing_metadata = trailing_metadata + + def abort(self, code, details): + with self._state.condition: + self._state.code = code + self._state.details = _common.encode(details) + self._state.abortion = Exception() + raise self._state.abortion def set_code(self, code): with self._state.condition: @@ -301,8 +305,7 @@ class _RequestIterator(object): raise StopIteration() else: self._call.start_server_batch( - cygrpc.Operations( - (cygrpc.operation_receive_message(_EMPTY_FLAGS),)), + (cygrpc.operation_receive_message(_EMPTY_FLAGS),), _receive_message(self._state, self._call, self._request_deserializer)) self._state.due.add(_RECEIVE_MESSAGE_TOKEN) @@ -345,8 +348,7 @@ def _unary_request(rpc_event, state, request_deserializer): return None else: rpc_event.operation_call.start_server_batch( - cygrpc.Operations( - (cygrpc.operation_receive_message(_EMPTY_FLAGS),)), + (cygrpc.operation_receive_message(_EMPTY_FLAGS),), _receive_message(state, rpc_event.operation_call, request_deserializer)) state.due.add(_RECEIVE_MESSAGE_TOKEN) @@ -376,7 +378,10 @@ def _call_behavior(rpc_event, state, behavior, argument, request_deserializer): return behavior(argument, context), True except Exception as exception: # pylint: disable=broad-except with state.condition: - if exception not in state.rpc_errors: + if exception is state.abortion: + _abort(state, rpc_event.operation_call, + cygrpc.StatusCode.unknown, b'RPC Aborted') + elif exception not in state.rpc_errors: details = 'Exception calling application: {}'.format(exception) logging.exception(details) _abort(state, rpc_event.operation_call, @@ -391,7 +396,10 @@ def _take_response_from_response_iterator(rpc_event, state, response_iterator): return None, True except Exception as exception: # pylint: disable=broad-except with state.condition: - if exception not in state.rpc_errors: + if exception is state.abortion: + _abort(state, rpc_event.operation_call, + cygrpc.StatusCode.unknown, b'RPC Aborted') + elif exception not in state.rpc_errors: details = 'Exception iterating responses: {}'.format(exception) logging.exception(details) _abort(state, rpc_event.operation_call, @@ -417,9 +425,8 @@ def _send_response(rpc_event, state, serialized_response): else: if state.initial_metadata_allowed: operations = (cygrpc.operation_send_initial_metadata( - _common.EMPTY_METADATA, _EMPTY_FLAGS), - cygrpc.operation_send_message(serialized_response, - _EMPTY_FLAGS),) + (), _EMPTY_FLAGS), cygrpc.operation_send_message( + serialized_response, _EMPTY_FLAGS),) state.initial_metadata_allowed = False token = _SEND_INITIAL_METADATA_AND_SEND_MESSAGE_TOKEN else: @@ -427,7 +434,7 @@ def _send_response(rpc_event, state, serialized_response): _EMPTY_FLAGS),) token = _SEND_MESSAGE_TOKEN rpc_event.operation_call.start_server_batch( - cygrpc.Operations(operations), _send_message(state, token)) + operations, _send_message(state, token)) state.due.add(token) while True: state.condition.wait() @@ -438,24 +445,21 @@ def _send_response(rpc_event, state, serialized_response): def _status(rpc_event, state, serialized_response): with state.condition: if state.client is not _CANCELLED: - trailing_metadata = _common.to_cygrpc_metadata( - state.trailing_metadata) code = _completion_code(state) details = _details(state) operations = [ cygrpc.operation_send_status_from_server( - trailing_metadata, code, details, _EMPTY_FLAGS), + state.trailing_metadata, code, details, _EMPTY_FLAGS), ] if state.initial_metadata_allowed: operations.append( - cygrpc.operation_send_initial_metadata( - _common.EMPTY_METADATA, _EMPTY_FLAGS)) + cygrpc.operation_send_initial_metadata((), _EMPTY_FLAGS)) if serialized_response is not None: operations.append( cygrpc.operation_send_message(serialized_response, _EMPTY_FLAGS)) rpc_event.operation_call.start_server_batch( - cygrpc.Operations(operations), + operations, _send_status_from_server(state, _SEND_STATUS_FROM_SERVER_TOKEN)) state.statused = True state.due.add(_SEND_STATUS_FROM_SERVER_TOKEN) @@ -538,24 +542,31 @@ def _handle_stream_stream(rpc_event, state, method_handler, thread_pool): method_handler.request_deserializer, method_handler.response_serializer) -def _find_method_handler(rpc_event, generic_handlers): - for generic_handler in generic_handlers: - method_handler = generic_handler.service( - _HandlerCallDetails( - _common.decode(rpc_event.request_call_details.method), - rpc_event.request_metadata)) - if method_handler is not None: - return method_handler - else: +def _find_method_handler(rpc_event, generic_handlers, interceptor_pipeline): + + def query_handlers(handler_call_details): + for generic_handler in generic_handlers: + method_handler = generic_handler.service(handler_call_details) + if method_handler is not None: + return method_handler return None + handler_call_details = _HandlerCallDetails( + _common.decode(rpc_event.request_call_details.method), + rpc_event.request_metadata) + + if interceptor_pipeline is not None: + return interceptor_pipeline.execute(query_handlers, + handler_call_details) + else: + return query_handlers(handler_call_details) + def _reject_rpc(rpc_event, status, details): - operations = (cygrpc.operation_send_initial_metadata(_common.EMPTY_METADATA, - _EMPTY_FLAGS), + operations = (cygrpc.operation_send_initial_metadata((), _EMPTY_FLAGS), cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS), - cygrpc.operation_send_status_from_server( - _common.EMPTY_METADATA, status, details, _EMPTY_FLAGS),) + cygrpc.operation_send_status_from_server((), status, details, + _EMPTY_FLAGS),) rpc_state = _RPCState() rpc_event.operation_call.start_server_batch( operations, lambda ignored_event: (rpc_state, (),)) @@ -566,8 +577,7 @@ def _handle_with_method_handler(rpc_event, method_handler, thread_pool): state = _RPCState() with state.condition: rpc_event.operation_call.start_server_batch( - cygrpc.Operations( - (cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),)), + (cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),), _receive_close_on_server(state)) state.due.add(_RECEIVE_CLOSE_ON_SERVER_TOKEN) if method_handler.request_streaming: @@ -586,13 +596,14 @@ def _handle_with_method_handler(rpc_event, method_handler, thread_pool): method_handler, thread_pool) -def _handle_call(rpc_event, generic_handlers, thread_pool, +def _handle_call(rpc_event, generic_handlers, interceptor_pipeline, thread_pool, concurrency_exceeded): if not rpc_event.success: return None, None if rpc_event.request_call_details.method is not None: try: - method_handler = _find_method_handler(rpc_event, generic_handlers) + method_handler = _find_method_handler(rpc_event, generic_handlers, + interceptor_pipeline) except Exception as exception: # pylint: disable=broad-except details = 'Exception servicing handler: {}'.format(exception) logging.exception(details) @@ -620,12 +631,14 @@ class _ServerStage(enum.Enum): class _ServerState(object): - def __init__(self, completion_queue, server, generic_handlers, thread_pool, - maximum_concurrent_rpcs): + # pylint: disable=too-many-arguments + def __init__(self, completion_queue, server, generic_handlers, + interceptor_pipeline, thread_pool, maximum_concurrent_rpcs): self.lock = threading.Lock() self.completion_queue = completion_queue self.server = server self.generic_handlers = list(generic_handlers) + self.interceptor_pipeline = interceptor_pipeline self.thread_pool = thread_pool self.stage = _ServerStage.STOPPED self.shutdown_events = None @@ -690,8 +703,8 @@ def _serve(state): state.maximum_concurrent_rpcs is not None and state.active_rpc_count >= state.maximum_concurrent_rpcs) rpc_state, rpc_future = _handle_call( - event, state.generic_handlers, state.thread_pool, - concurrency_exceeded) + event, state.generic_handlers, state.interceptor_pipeline, + state.thread_pool, concurrency_exceeded) if rpc_state is not None: state.rpc_states.add(rpc_state) if rpc_future is not None: @@ -779,12 +792,14 @@ def _start(state): class Server(grpc.Server): - def __init__(self, thread_pool, generic_handlers, options, + # pylint: disable=too-many-arguments + def __init__(self, thread_pool, generic_handlers, interceptors, options, maximum_concurrent_rpcs): completion_queue = cygrpc.CompletionQueue() server = cygrpc.Server(_common.channel_args(options)) server.register_completion_queue(completion_queue) self._state = _ServerState(completion_queue, server, generic_handlers, + _interceptor.service_pipeline(interceptors), thread_pool, maximum_concurrent_rpcs) def add_generic_rpc_handlers(self, generic_rpc_handlers): diff --git a/src/python/grpcio/grpc/beta/_client_adaptations.py b/src/python/grpcio/grpc/beta/_client_adaptations.py index 73ce22fa98..dcaa0eeaa2 100644 --- a/src/python/grpcio/grpc/beta/_client_adaptations.py +++ b/src/python/grpcio/grpc/beta/_client_adaptations.py @@ -15,6 +15,7 @@ import grpc from grpc import _common +from grpc.beta import _metadata from grpc.beta import interfaces from grpc.framework.common import cardinality from grpc.framework.foundation import future @@ -157,10 +158,10 @@ class _Rendezvous(future.Future, face.Call): return _InvocationProtocolContext() def initial_metadata(self): - return self._call.initial_metadata() + return _metadata.beta(self._call.initial_metadata()) def terminal_metadata(self): - return self._call.terminal_metadata() + return _metadata.beta(self._call.terminal_metadata()) def code(self): return self._call.code() @@ -182,14 +183,14 @@ def _blocking_unary_unary(channel, group, method, timeout, with_call, response, call = multi_callable.with_call( request, timeout=timeout, - metadata=effective_metadata, + metadata=_metadata.unbeta(effective_metadata), credentials=_credentials(protocol_options)) return response, _Rendezvous(None, None, call) else: return multi_callable( request, timeout=timeout, - metadata=effective_metadata, + metadata=_metadata.unbeta(effective_metadata), credentials=_credentials(protocol_options)) except grpc.RpcError as rpc_error_call: raise _abortion_error(rpc_error_call) @@ -206,7 +207,7 @@ def _future_unary_unary(channel, group, method, timeout, protocol_options, response_future = multi_callable.future( request, timeout=timeout, - metadata=effective_metadata, + metadata=_metadata.unbeta(effective_metadata), credentials=_credentials(protocol_options)) return _Rendezvous(response_future, None, response_future) @@ -222,7 +223,7 @@ def _unary_stream(channel, group, method, timeout, protocol_options, metadata, response_iterator = multi_callable( request, timeout=timeout, - metadata=effective_metadata, + metadata=_metadata.unbeta(effective_metadata), credentials=_credentials(protocol_options)) return _Rendezvous(None, response_iterator, response_iterator) @@ -241,14 +242,14 @@ def _blocking_stream_unary(channel, group, method, timeout, with_call, response, call = multi_callable.with_call( request_iterator, timeout=timeout, - metadata=effective_metadata, + metadata=_metadata.unbeta(effective_metadata), credentials=_credentials(protocol_options)) return response, _Rendezvous(None, None, call) else: return multi_callable( request_iterator, timeout=timeout, - metadata=effective_metadata, + metadata=_metadata.unbeta(effective_metadata), credentials=_credentials(protocol_options)) except grpc.RpcError as rpc_error_call: raise _abortion_error(rpc_error_call) @@ -265,7 +266,7 @@ def _future_stream_unary(channel, group, method, timeout, protocol_options, response_future = multi_callable.future( request_iterator, timeout=timeout, - metadata=effective_metadata, + metadata=_metadata.unbeta(effective_metadata), credentials=_credentials(protocol_options)) return _Rendezvous(response_future, None, response_future) @@ -281,7 +282,7 @@ def _stream_stream(channel, group, method, timeout, protocol_options, metadata, response_iterator = multi_callable( request_iterator, timeout=timeout, - metadata=effective_metadata, + metadata=_metadata.unbeta(effective_metadata), credentials=_credentials(protocol_options)) return _Rendezvous(None, response_iterator, response_iterator) diff --git a/src/python/grpcio/grpc/beta/_metadata.py b/src/python/grpcio/grpc/beta/_metadata.py new file mode 100644 index 0000000000..e135f4dff4 --- /dev/null +++ b/src/python/grpcio/grpc/beta/_metadata.py @@ -0,0 +1,49 @@ +# Copyright 2017 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""API metadata conversion utilities.""" + +import collections + +_Metadatum = collections.namedtuple('_Metadatum', ('key', 'value',)) + + +def _beta_metadatum(key, value): + beta_key = key if isinstance(key, (bytes,)) else key.encode('ascii') + beta_value = value if isinstance(value, (bytes,)) else value.encode('ascii') + return _Metadatum(beta_key, beta_value) + + +def _metadatum(beta_key, beta_value): + key = beta_key if isinstance(beta_key, (str,)) else beta_key.decode('utf8') + if isinstance(beta_value, (str,)) or key[-4:] == '-bin': + value = beta_value + else: + value = beta_value.decode('utf8') + return _Metadatum(key, value) + + +def beta(metadata): + if metadata is None: + return () + else: + return tuple(_beta_metadatum(key, value) for key, value in metadata) + + +def unbeta(beta_metadata): + if beta_metadata is None: + return () + else: + return tuple( + _metadatum(beta_key, beta_value) + for beta_key, beta_value in beta_metadata) diff --git a/src/python/grpcio/grpc/beta/_server_adaptations.py b/src/python/grpcio/grpc/beta/_server_adaptations.py index ec363e9bc9..1c22dbe3bb 100644 --- a/src/python/grpcio/grpc/beta/_server_adaptations.py +++ b/src/python/grpcio/grpc/beta/_server_adaptations.py @@ -18,6 +18,7 @@ import threading import grpc from grpc import _common +from grpc.beta import _metadata from grpc.beta import interfaces from grpc.framework.common import cardinality from grpc.framework.common import style @@ -65,14 +66,15 @@ class _FaceServicerContext(face.ServicerContext): return _ServerProtocolContext(self._servicer_context) def invocation_metadata(self): - return _common.to_cygrpc_metadata( - self._servicer_context.invocation_metadata()) + return _metadata.beta(self._servicer_context.invocation_metadata()) def initial_metadata(self, initial_metadata): - self._servicer_context.send_initial_metadata(initial_metadata) + self._servicer_context.send_initial_metadata( + _metadata.unbeta(initial_metadata)) def terminal_metadata(self, terminal_metadata): - self._servicer_context.set_terminal_metadata(terminal_metadata) + self._servicer_context.set_terminal_metadata( + _metadata.unbeta(terminal_metadata)) def code(self, code): self._servicer_context.set_code(code) diff --git a/src/python/grpcio/grpc/beta/implementations.py b/src/python/grpcio/grpc/beta/implementations.py index e52ce764b5..312daf033e 100644 --- a/src/python/grpcio/grpc/beta/implementations.py +++ b/src/python/grpcio/grpc/beta/implementations.py @@ -21,6 +21,7 @@ import threading # pylint: disable=unused-import import grpc from grpc import _auth from grpc.beta import _client_adaptations +from grpc.beta import _metadata from grpc.beta import _server_adaptations from grpc.beta import interfaces # pylint: disable=unused-import from grpc.framework.common import cardinality # pylint: disable=unused-import @@ -31,7 +32,18 @@ from grpc.framework.interfaces.face import face # pylint: disable=unused-import ChannelCredentials = grpc.ChannelCredentials ssl_channel_credentials = grpc.ssl_channel_credentials CallCredentials = grpc.CallCredentials -metadata_call_credentials = grpc.metadata_call_credentials + + +def metadata_call_credentials(metadata_plugin, name=None): + + def plugin(context, callback): + + def wrapped_callback(beta_metadata, error): + callback(_metadata.unbeta(beta_metadata), error) + + metadata_plugin(context, wrapped_callback) + + return grpc.metadata_call_credentials(plugin, name=name) def google_call_credentials(credentials): diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index d6644ffc59..a369ec0dff 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -15,669 +15,669 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_core_dependencies.py.template`!!! CORE_SOURCE_FILES = [ - 'src/core/lib/profiling/basic_timers.cc', - 'src/core/lib/profiling/stap_timers.cc', - 'src/core/lib/support/alloc.cc', - 'src/core/lib/support/arena.cc', - 'src/core/lib/support/atm.cc', - 'src/core/lib/support/avl.cc', - 'src/core/lib/support/cmdline.cc', - 'src/core/lib/support/cpu_iphone.cc', - 'src/core/lib/support/cpu_linux.cc', - 'src/core/lib/support/cpu_posix.cc', - 'src/core/lib/support/cpu_windows.cc', - 'src/core/lib/support/env_linux.cc', - 'src/core/lib/support/env_posix.cc', - 'src/core/lib/support/env_windows.cc', - 'src/core/lib/support/fork.cc', - 'src/core/lib/support/host_port.cc', - 'src/core/lib/support/log.cc', - 'src/core/lib/support/log_android.cc', - 'src/core/lib/support/log_linux.cc', - 'src/core/lib/support/log_posix.cc', - 'src/core/lib/support/log_windows.cc', - 'src/core/lib/support/mpscq.cc', - 'src/core/lib/support/murmur_hash.cc', - 'src/core/lib/support/string.cc', - 'src/core/lib/support/string_posix.cc', - 'src/core/lib/support/string_util_windows.cc', - 'src/core/lib/support/string_windows.cc', - 'src/core/lib/support/subprocess_posix.cc', - 'src/core/lib/support/subprocess_windows.cc', - 'src/core/lib/support/sync.cc', - 'src/core/lib/support/sync_posix.cc', - 'src/core/lib/support/sync_windows.cc', - 'src/core/lib/support/thd.cc', - 'src/core/lib/support/thd_posix.cc', - 'src/core/lib/support/thd_windows.cc', - 'src/core/lib/support/time.cc', - 'src/core/lib/support/time_posix.cc', - 'src/core/lib/support/time_precise.cc', - 'src/core/lib/support/time_windows.cc', - 'src/core/lib/support/tls_pthread.cc', - 'src/core/lib/support/tmpfile_msys.cc', - 'src/core/lib/support/tmpfile_posix.cc', - 'src/core/lib/support/tmpfile_windows.cc', - 'src/core/lib/support/wrap_memcpy.cc', - 'src/core/lib/surface/init.cc', - 'src/core/lib/backoff/backoff.cc', - 'src/core/lib/channel/channel_args.cc', - 'src/core/lib/channel/channel_stack.cc', - 'src/core/lib/channel/channel_stack_builder.cc', - 'src/core/lib/channel/connected_channel.cc', - 'src/core/lib/channel/handshaker.cc', - 'src/core/lib/channel/handshaker_factory.cc', - 'src/core/lib/channel/handshaker_registry.cc', - 'src/core/lib/compression/compression.cc', - 'src/core/lib/compression/compression_internal.cc', - 'src/core/lib/compression/compression_ruby.cc', - 'src/core/lib/compression/message_compress.cc', - 'src/core/lib/compression/stream_compression.cc', - 'src/core/lib/compression/stream_compression_gzip.cc', - 'src/core/lib/compression/stream_compression_identity.cc', - 'src/core/lib/debug/stats.cc', - 'src/core/lib/debug/stats_data.cc', - 'src/core/lib/http/format_request.cc', - 'src/core/lib/http/httpcli.cc', - 'src/core/lib/http/parser.cc', - 'src/core/lib/iomgr/call_combiner.cc', - 'src/core/lib/iomgr/combiner.cc', - 'src/core/lib/iomgr/endpoint.cc', - 'src/core/lib/iomgr/endpoint_pair_posix.cc', - 'src/core/lib/iomgr/endpoint_pair_uv.cc', - 'src/core/lib/iomgr/endpoint_pair_windows.cc', - 'src/core/lib/iomgr/error.cc', - 'src/core/lib/iomgr/ev_epoll1_linux.cc', - 'src/core/lib/iomgr/ev_epollex_linux.cc', - 'src/core/lib/iomgr/ev_epollsig_linux.cc', - 'src/core/lib/iomgr/ev_poll_posix.cc', - 'src/core/lib/iomgr/ev_posix.cc', - 'src/core/lib/iomgr/ev_windows.cc', - 'src/core/lib/iomgr/exec_ctx.cc', - 'src/core/lib/iomgr/executor.cc', - 'src/core/lib/iomgr/fork_posix.cc', - 'src/core/lib/iomgr/fork_windows.cc', - 'src/core/lib/iomgr/gethostname_fallback.cc', - 'src/core/lib/iomgr/gethostname_host_name_max.cc', - 'src/core/lib/iomgr/gethostname_sysconf.cc', - 'src/core/lib/iomgr/iocp_windows.cc', - 'src/core/lib/iomgr/iomgr.cc', - 'src/core/lib/iomgr/iomgr_posix.cc', - 'src/core/lib/iomgr/iomgr_uv.cc', - 'src/core/lib/iomgr/iomgr_windows.cc', - 'src/core/lib/iomgr/is_epollexclusive_available.cc', - 'src/core/lib/iomgr/load_file.cc', - 'src/core/lib/iomgr/lockfree_event.cc', - 'src/core/lib/iomgr/network_status_tracker.cc', - 'src/core/lib/iomgr/polling_entity.cc', - 'src/core/lib/iomgr/pollset_set_uv.cc', - 'src/core/lib/iomgr/pollset_set_windows.cc', - 'src/core/lib/iomgr/pollset_uv.cc', - 'src/core/lib/iomgr/pollset_windows.cc', - 'src/core/lib/iomgr/resolve_address_posix.cc', - 'src/core/lib/iomgr/resolve_address_uv.cc', - 'src/core/lib/iomgr/resolve_address_windows.cc', - 'src/core/lib/iomgr/resource_quota.cc', - 'src/core/lib/iomgr/sockaddr_utils.cc', - 'src/core/lib/iomgr/socket_factory_posix.cc', - 'src/core/lib/iomgr/socket_mutator.cc', - 'src/core/lib/iomgr/socket_utils_common_posix.cc', - 'src/core/lib/iomgr/socket_utils_linux.cc', - 'src/core/lib/iomgr/socket_utils_posix.cc', - 'src/core/lib/iomgr/socket_utils_uv.cc', - 'src/core/lib/iomgr/socket_utils_windows.cc', - 'src/core/lib/iomgr/socket_windows.cc', - 'src/core/lib/iomgr/tcp_client_posix.cc', - 'src/core/lib/iomgr/tcp_client_uv.cc', - 'src/core/lib/iomgr/tcp_client_windows.cc', - 'src/core/lib/iomgr/tcp_posix.cc', - 'src/core/lib/iomgr/tcp_server_posix.cc', - 'src/core/lib/iomgr/tcp_server_utils_posix_common.cc', - 'src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc', - 'src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc', - 'src/core/lib/iomgr/tcp_server_uv.cc', - 'src/core/lib/iomgr/tcp_server_windows.cc', - 'src/core/lib/iomgr/tcp_uv.cc', - 'src/core/lib/iomgr/tcp_windows.cc', - 'src/core/lib/iomgr/time_averaged_stats.cc', - 'src/core/lib/iomgr/timer_generic.cc', - 'src/core/lib/iomgr/timer_heap.cc', - 'src/core/lib/iomgr/timer_manager.cc', - 'src/core/lib/iomgr/timer_uv.cc', - 'src/core/lib/iomgr/udp_server.cc', - 'src/core/lib/iomgr/unix_sockets_posix.cc', - 'src/core/lib/iomgr/unix_sockets_posix_noop.cc', - 'src/core/lib/iomgr/wakeup_fd_cv.cc', - 'src/core/lib/iomgr/wakeup_fd_eventfd.cc', - 'src/core/lib/iomgr/wakeup_fd_nospecial.cc', - 'src/core/lib/iomgr/wakeup_fd_pipe.cc', - 'src/core/lib/iomgr/wakeup_fd_posix.cc', - 'src/core/lib/json/json.cc', - 'src/core/lib/json/json_reader.cc', - 'src/core/lib/json/json_string.cc', - 'src/core/lib/json/json_writer.cc', - 'src/core/lib/slice/b64.cc', - 'src/core/lib/slice/percent_encoding.cc', - 'src/core/lib/slice/slice.cc', - 'src/core/lib/slice/slice_buffer.cc', - 'src/core/lib/slice/slice_hash_table.cc', - 'src/core/lib/slice/slice_intern.cc', - 'src/core/lib/slice/slice_string_helpers.cc', - 'src/core/lib/surface/alarm.cc', - 'src/core/lib/surface/api_trace.cc', - 'src/core/lib/surface/byte_buffer.cc', - 'src/core/lib/surface/byte_buffer_reader.cc', - 'src/core/lib/surface/call.cc', - 'src/core/lib/surface/call_details.cc', - 'src/core/lib/surface/call_log_batch.cc', - 'src/core/lib/surface/channel.cc', - 'src/core/lib/surface/channel_init.cc', - 'src/core/lib/surface/channel_ping.cc', - 'src/core/lib/surface/channel_stack_type.cc', - 'src/core/lib/surface/completion_queue.cc', - 'src/core/lib/surface/completion_queue_factory.cc', - 'src/core/lib/surface/event_string.cc', - 'src/core/lib/surface/lame_client.cc', - 'src/core/lib/surface/metadata_array.cc', - 'src/core/lib/surface/server.cc', - 'src/core/lib/surface/validate_metadata.cc', - 'src/core/lib/surface/version.cc', - 'src/core/lib/transport/bdp_estimator.cc', - 'src/core/lib/transport/byte_stream.cc', - 'src/core/lib/transport/connectivity_state.cc', - 'src/core/lib/transport/error_utils.cc', - 'src/core/lib/transport/metadata.cc', - 'src/core/lib/transport/metadata_batch.cc', - 'src/core/lib/transport/pid_controller.cc', - 'src/core/lib/transport/service_config.cc', - 'src/core/lib/transport/static_metadata.cc', - 'src/core/lib/transport/status_conversion.cc', - 'src/core/lib/transport/timeout_encoding.cc', - 'src/core/lib/transport/transport.cc', - 'src/core/lib/transport/transport_op_string.cc', - 'src/core/lib/debug/trace.cc', - 'src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc', - 'src/core/ext/transport/chttp2/transport/bin_decoder.cc', - 'src/core/ext/transport/chttp2/transport/bin_encoder.cc', - 'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc', - 'src/core/ext/transport/chttp2/transport/chttp2_transport.cc', - 'src/core/ext/transport/chttp2/transport/flow_control.cc', - 'src/core/ext/transport/chttp2/transport/frame_data.cc', - 'src/core/ext/transport/chttp2/transport/frame_goaway.cc', - 'src/core/ext/transport/chttp2/transport/frame_ping.cc', - 'src/core/ext/transport/chttp2/transport/frame_rst_stream.cc', - 'src/core/ext/transport/chttp2/transport/frame_settings.cc', - 'src/core/ext/transport/chttp2/transport/frame_window_update.cc', - 'src/core/ext/transport/chttp2/transport/hpack_encoder.cc', - 'src/core/ext/transport/chttp2/transport/hpack_parser.cc', - 'src/core/ext/transport/chttp2/transport/hpack_table.cc', - 'src/core/ext/transport/chttp2/transport/http2_settings.cc', - 'src/core/ext/transport/chttp2/transport/huffsyms.cc', - 'src/core/ext/transport/chttp2/transport/incoming_metadata.cc', - 'src/core/ext/transport/chttp2/transport/parsing.cc', - 'src/core/ext/transport/chttp2/transport/stream_lists.cc', - 'src/core/ext/transport/chttp2/transport/stream_map.cc', - 'src/core/ext/transport/chttp2/transport/varint.cc', - 'src/core/ext/transport/chttp2/transport/writing.cc', - 'src/core/ext/transport/chttp2/alpn/alpn.cc', - 'src/core/ext/filters/http/client/http_client_filter.cc', - 'src/core/ext/filters/http/http_filters_plugin.cc', - 'src/core/ext/filters/http/message_compress/message_compress_filter.cc', - 'src/core/ext/filters/http/server/http_server_filter.cc', - 'src/core/lib/http/httpcli_security_connector.cc', - 'src/core/lib/security/context/security_context.cc', - 'src/core/lib/security/credentials/composite/composite_credentials.cc', - 'src/core/lib/security/credentials/credentials.cc', - 'src/core/lib/security/credentials/credentials_metadata.cc', - 'src/core/lib/security/credentials/fake/fake_credentials.cc', - 'src/core/lib/security/credentials/google_default/credentials_generic.cc', - 'src/core/lib/security/credentials/google_default/google_default_credentials.cc', - 'src/core/lib/security/credentials/iam/iam_credentials.cc', - 'src/core/lib/security/credentials/jwt/json_token.cc', - 'src/core/lib/security/credentials/jwt/jwt_credentials.cc', - 'src/core/lib/security/credentials/jwt/jwt_verifier.cc', - 'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc', - 'src/core/lib/security/credentials/plugin/plugin_credentials.cc', - 'src/core/lib/security/credentials/ssl/ssl_credentials.cc', - 'src/core/lib/security/transport/client_auth_filter.cc', - 'src/core/lib/security/transport/lb_targets_info.cc', - 'src/core/lib/security/transport/secure_endpoint.cc', - 'src/core/lib/security/transport/security_connector.cc', - 'src/core/lib/security/transport/security_handshaker.cc', - 'src/core/lib/security/transport/server_auth_filter.cc', - 'src/core/lib/security/transport/tsi_error.cc', - 'src/core/lib/security/util/json_util.cc', - 'src/core/lib/surface/init_secure.cc', - 'src/core/tsi/fake_transport_security.cc', - 'src/core/tsi/gts_transport_security.cc', - 'src/core/tsi/ssl_transport_security.cc', - 'src/core/tsi/transport_security_grpc.cc', - 'src/core/tsi/transport_security.cc', - 'src/core/tsi/transport_security_adapter.cc', - 'src/core/ext/transport/chttp2/server/chttp2_server.cc', - 'src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc', - 'src/core/ext/filters/client_channel/backup_poller.cc', - 'src/core/ext/filters/client_channel/channel_connectivity.cc', - 'src/core/ext/filters/client_channel/client_channel.cc', - 'src/core/ext/filters/client_channel/client_channel_factory.cc', - 'src/core/ext/filters/client_channel/client_channel_plugin.cc', - 'src/core/ext/filters/client_channel/connector.cc', - 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', - 'src/core/ext/filters/client_channel/http_proxy.cc', - 'src/core/ext/filters/client_channel/lb_policy.cc', - 'src/core/ext/filters/client_channel/lb_policy_factory.cc', - 'src/core/ext/filters/client_channel/lb_policy_registry.cc', - 'src/core/ext/filters/client_channel/parse_address.cc', - 'src/core/ext/filters/client_channel/proxy_mapper.cc', - 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', - 'src/core/ext/filters/client_channel/resolver.cc', - 'src/core/ext/filters/client_channel/resolver_factory.cc', - 'src/core/ext/filters/client_channel/resolver_registry.cc', - 'src/core/ext/filters/client_channel/retry_throttle.cc', - 'src/core/ext/filters/client_channel/subchannel.cc', - 'src/core/ext/filters/client_channel/subchannel_index.cc', - 'src/core/ext/filters/client_channel/uri_parser.cc', - 'src/core/ext/filters/deadline/deadline_filter.cc', - 'src/core/ext/transport/chttp2/client/chttp2_connector.cc', - 'src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc', - 'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc', - 'src/core/ext/transport/chttp2/client/insecure/channel_create.cc', - 'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc', - 'src/core/ext/transport/inproc/inproc_plugin.cc', - 'src/core/ext/transport/inproc/inproc_transport.cc', - 'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc', - 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc', - 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc', - 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc', - 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc', - 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c', - 'third_party/nanopb/pb_common.c', - 'third_party/nanopb/pb_decode.c', - 'third_party/nanopb/pb_encode.c', - 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc', - 'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc', - 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc', - 'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', - 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', - 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', - 'src/core/ext/filters/load_reporting/server_load_reporting_filter.cc', - 'src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc', - 'src/core/ext/census/grpc_context.cc', - 'src/core/ext/filters/max_age/max_age_filter.cc', - 'src/core/ext/filters/message_size/message_size_filter.cc', - 'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc', - 'src/core/ext/filters/workarounds/workaround_utils.cc', - 'src/core/plugin_registry/grpc_plugin_registry.cc', - 'src/boringssl/err_data.c', - 'third_party/boringssl/crypto/aes/aes.c', - 'third_party/boringssl/crypto/aes/key_wrap.c', - 'third_party/boringssl/crypto/aes/mode_wrappers.c', - 'third_party/boringssl/crypto/asn1/a_bitstr.c', - 'third_party/boringssl/crypto/asn1/a_bool.c', - 'third_party/boringssl/crypto/asn1/a_d2i_fp.c', - 'third_party/boringssl/crypto/asn1/a_dup.c', - 'third_party/boringssl/crypto/asn1/a_enum.c', - 'third_party/boringssl/crypto/asn1/a_gentm.c', - 'third_party/boringssl/crypto/asn1/a_i2d_fp.c', - 'third_party/boringssl/crypto/asn1/a_int.c', - 'third_party/boringssl/crypto/asn1/a_mbstr.c', - 'third_party/boringssl/crypto/asn1/a_object.c', - 'third_party/boringssl/crypto/asn1/a_octet.c', - 'third_party/boringssl/crypto/asn1/a_print.c', - 'third_party/boringssl/crypto/asn1/a_strnid.c', - 'third_party/boringssl/crypto/asn1/a_time.c', - 'third_party/boringssl/crypto/asn1/a_type.c', - 'third_party/boringssl/crypto/asn1/a_utctm.c', - 'third_party/boringssl/crypto/asn1/a_utf8.c', - 'third_party/boringssl/crypto/asn1/asn1_lib.c', - 'third_party/boringssl/crypto/asn1/asn1_par.c', - 'third_party/boringssl/crypto/asn1/asn_pack.c', - 'third_party/boringssl/crypto/asn1/f_enum.c', - 'third_party/boringssl/crypto/asn1/f_int.c', - 'third_party/boringssl/crypto/asn1/f_string.c', - 'third_party/boringssl/crypto/asn1/t_bitst.c', - 'third_party/boringssl/crypto/asn1/tasn_dec.c', - 'third_party/boringssl/crypto/asn1/tasn_enc.c', - 'third_party/boringssl/crypto/asn1/tasn_fre.c', - 'third_party/boringssl/crypto/asn1/tasn_new.c', - 'third_party/boringssl/crypto/asn1/tasn_typ.c', - 'third_party/boringssl/crypto/asn1/tasn_utl.c', - 'third_party/boringssl/crypto/asn1/time_support.c', - 'third_party/boringssl/crypto/asn1/x_bignum.c', - 'third_party/boringssl/crypto/asn1/x_long.c', - 'third_party/boringssl/crypto/base64/base64.c', - 'third_party/boringssl/crypto/bio/bio.c', - 'third_party/boringssl/crypto/bio/bio_mem.c', - 'third_party/boringssl/crypto/bio/connect.c', - 'third_party/boringssl/crypto/bio/fd.c', - 'third_party/boringssl/crypto/bio/file.c', - 'third_party/boringssl/crypto/bio/hexdump.c', - 'third_party/boringssl/crypto/bio/pair.c', - 'third_party/boringssl/crypto/bio/printf.c', - 'third_party/boringssl/crypto/bio/socket.c', - 'third_party/boringssl/crypto/bio/socket_helper.c', - 'third_party/boringssl/crypto/bn/add.c', - 'third_party/boringssl/crypto/bn/asm/x86_64-gcc.c', - 'third_party/boringssl/crypto/bn/bn.c', - 'third_party/boringssl/crypto/bn/bn_asn1.c', - 'third_party/boringssl/crypto/bn/cmp.c', - 'third_party/boringssl/crypto/bn/convert.c', - 'third_party/boringssl/crypto/bn/ctx.c', - 'third_party/boringssl/crypto/bn/div.c', - 'third_party/boringssl/crypto/bn/exponentiation.c', - 'third_party/boringssl/crypto/bn/gcd.c', - 'third_party/boringssl/crypto/bn/generic.c', - 'third_party/boringssl/crypto/bn/kronecker.c', - 'third_party/boringssl/crypto/bn/montgomery.c', - 'third_party/boringssl/crypto/bn/montgomery_inv.c', - 'third_party/boringssl/crypto/bn/mul.c', - 'third_party/boringssl/crypto/bn/prime.c', - 'third_party/boringssl/crypto/bn/random.c', - 'third_party/boringssl/crypto/bn/rsaz_exp.c', - 'third_party/boringssl/crypto/bn/shift.c', - 'third_party/boringssl/crypto/bn/sqrt.c', - 'third_party/boringssl/crypto/buf/buf.c', - 'third_party/boringssl/crypto/bytestring/asn1_compat.c', - 'third_party/boringssl/crypto/bytestring/ber.c', - 'third_party/boringssl/crypto/bytestring/cbb.c', - 'third_party/boringssl/crypto/bytestring/cbs.c', - 'third_party/boringssl/crypto/chacha/chacha.c', - 'third_party/boringssl/crypto/cipher/aead.c', - 'third_party/boringssl/crypto/cipher/cipher.c', - 'third_party/boringssl/crypto/cipher/derive_key.c', - 'third_party/boringssl/crypto/cipher/e_aes.c', - 'third_party/boringssl/crypto/cipher/e_chacha20poly1305.c', - 'third_party/boringssl/crypto/cipher/e_des.c', - 'third_party/boringssl/crypto/cipher/e_null.c', - 'third_party/boringssl/crypto/cipher/e_rc2.c', - 'third_party/boringssl/crypto/cipher/e_rc4.c', - 'third_party/boringssl/crypto/cipher/e_ssl3.c', - 'third_party/boringssl/crypto/cipher/e_tls.c', - 'third_party/boringssl/crypto/cipher/tls_cbc.c', - 'third_party/boringssl/crypto/cmac/cmac.c', - 'third_party/boringssl/crypto/conf/conf.c', - 'third_party/boringssl/crypto/cpu-aarch64-linux.c', - 'third_party/boringssl/crypto/cpu-arm-linux.c', - 'third_party/boringssl/crypto/cpu-arm.c', - 'third_party/boringssl/crypto/cpu-intel.c', - 'third_party/boringssl/crypto/cpu-ppc64le.c', - 'third_party/boringssl/crypto/crypto.c', - 'third_party/boringssl/crypto/curve25519/curve25519.c', - 'third_party/boringssl/crypto/curve25519/spake25519.c', - 'third_party/boringssl/crypto/curve25519/x25519-x86_64.c', - 'third_party/boringssl/crypto/des/des.c', - 'third_party/boringssl/crypto/dh/check.c', - 'third_party/boringssl/crypto/dh/dh.c', - 'third_party/boringssl/crypto/dh/dh_asn1.c', - 'third_party/boringssl/crypto/dh/params.c', - 'third_party/boringssl/crypto/digest/digest.c', - 'third_party/boringssl/crypto/digest/digests.c', - 'third_party/boringssl/crypto/dsa/dsa.c', - 'third_party/boringssl/crypto/dsa/dsa_asn1.c', - 'third_party/boringssl/crypto/ec/ec.c', - 'third_party/boringssl/crypto/ec/ec_asn1.c', - 'third_party/boringssl/crypto/ec/ec_key.c', - 'third_party/boringssl/crypto/ec/ec_montgomery.c', - 'third_party/boringssl/crypto/ec/oct.c', - 'third_party/boringssl/crypto/ec/p224-64.c', - 'third_party/boringssl/crypto/ec/p256-64.c', - 'third_party/boringssl/crypto/ec/p256-x86_64.c', - 'third_party/boringssl/crypto/ec/simple.c', - 'third_party/boringssl/crypto/ec/util-64.c', - 'third_party/boringssl/crypto/ec/wnaf.c', - 'third_party/boringssl/crypto/ecdh/ecdh.c', - 'third_party/boringssl/crypto/ecdsa/ecdsa.c', - 'third_party/boringssl/crypto/ecdsa/ecdsa_asn1.c', - 'third_party/boringssl/crypto/engine/engine.c', - 'third_party/boringssl/crypto/err/err.c', - 'third_party/boringssl/crypto/evp/digestsign.c', - 'third_party/boringssl/crypto/evp/evp.c', - 'third_party/boringssl/crypto/evp/evp_asn1.c', - 'third_party/boringssl/crypto/evp/evp_ctx.c', - 'third_party/boringssl/crypto/evp/p_dsa_asn1.c', - 'third_party/boringssl/crypto/evp/p_ec.c', - 'third_party/boringssl/crypto/evp/p_ec_asn1.c', - 'third_party/boringssl/crypto/evp/p_rsa.c', - 'third_party/boringssl/crypto/evp/p_rsa_asn1.c', - 'third_party/boringssl/crypto/evp/pbkdf.c', - 'third_party/boringssl/crypto/evp/print.c', - 'third_party/boringssl/crypto/evp/sign.c', - 'third_party/boringssl/crypto/ex_data.c', - 'third_party/boringssl/crypto/hkdf/hkdf.c', - 'third_party/boringssl/crypto/hmac/hmac.c', - 'third_party/boringssl/crypto/lhash/lhash.c', - 'third_party/boringssl/crypto/md4/md4.c', - 'third_party/boringssl/crypto/md5/md5.c', - 'third_party/boringssl/crypto/mem.c', - 'third_party/boringssl/crypto/modes/cbc.c', - 'third_party/boringssl/crypto/modes/cfb.c', - 'third_party/boringssl/crypto/modes/ctr.c', - 'third_party/boringssl/crypto/modes/gcm.c', - 'third_party/boringssl/crypto/modes/ofb.c', - 'third_party/boringssl/crypto/modes/polyval.c', - 'third_party/boringssl/crypto/obj/obj.c', - 'third_party/boringssl/crypto/obj/obj_xref.c', - 'third_party/boringssl/crypto/pem/pem_all.c', - 'third_party/boringssl/crypto/pem/pem_info.c', - 'third_party/boringssl/crypto/pem/pem_lib.c', - 'third_party/boringssl/crypto/pem/pem_oth.c', - 'third_party/boringssl/crypto/pem/pem_pk8.c', - 'third_party/boringssl/crypto/pem/pem_pkey.c', - 'third_party/boringssl/crypto/pem/pem_x509.c', - 'third_party/boringssl/crypto/pem/pem_xaux.c', - 'third_party/boringssl/crypto/pkcs8/p5_pbev2.c', - 'third_party/boringssl/crypto/pkcs8/p8_pkey.c', - 'third_party/boringssl/crypto/pkcs8/pkcs8.c', - 'third_party/boringssl/crypto/poly1305/poly1305.c', - 'third_party/boringssl/crypto/poly1305/poly1305_arm.c', - 'third_party/boringssl/crypto/poly1305/poly1305_vec.c', - 'third_party/boringssl/crypto/pool/pool.c', - 'third_party/boringssl/crypto/rand/deterministic.c', - 'third_party/boringssl/crypto/rand/fuchsia.c', - 'third_party/boringssl/crypto/rand/rand.c', - 'third_party/boringssl/crypto/rand/urandom.c', - 'third_party/boringssl/crypto/rand/windows.c', - 'third_party/boringssl/crypto/rc4/rc4.c', - 'third_party/boringssl/crypto/refcount_c11.c', - 'third_party/boringssl/crypto/refcount_lock.c', - 'third_party/boringssl/crypto/rsa/blinding.c', - 'third_party/boringssl/crypto/rsa/padding.c', - 'third_party/boringssl/crypto/rsa/rsa.c', - 'third_party/boringssl/crypto/rsa/rsa_asn1.c', - 'third_party/boringssl/crypto/rsa/rsa_impl.c', - 'third_party/boringssl/crypto/sha/sha1-altivec.c', - 'third_party/boringssl/crypto/sha/sha1.c', - 'third_party/boringssl/crypto/sha/sha256.c', - 'third_party/boringssl/crypto/sha/sha512.c', - 'third_party/boringssl/crypto/stack/stack.c', - 'third_party/boringssl/crypto/thread.c', - 'third_party/boringssl/crypto/thread_none.c', - 'third_party/boringssl/crypto/thread_pthread.c', - 'third_party/boringssl/crypto/thread_win.c', - 'third_party/boringssl/crypto/x509/a_digest.c', - 'third_party/boringssl/crypto/x509/a_sign.c', - 'third_party/boringssl/crypto/x509/a_strex.c', - 'third_party/boringssl/crypto/x509/a_verify.c', - 'third_party/boringssl/crypto/x509/algorithm.c', - 'third_party/boringssl/crypto/x509/asn1_gen.c', - 'third_party/boringssl/crypto/x509/by_dir.c', - 'third_party/boringssl/crypto/x509/by_file.c', - 'third_party/boringssl/crypto/x509/i2d_pr.c', - 'third_party/boringssl/crypto/x509/pkcs7.c', - 'third_party/boringssl/crypto/x509/rsa_pss.c', - 'third_party/boringssl/crypto/x509/t_crl.c', - 'third_party/boringssl/crypto/x509/t_req.c', - 'third_party/boringssl/crypto/x509/t_x509.c', - 'third_party/boringssl/crypto/x509/t_x509a.c', - 'third_party/boringssl/crypto/x509/x509.c', - 'third_party/boringssl/crypto/x509/x509_att.c', - 'third_party/boringssl/crypto/x509/x509_cmp.c', - 'third_party/boringssl/crypto/x509/x509_d2.c', - 'third_party/boringssl/crypto/x509/x509_def.c', - 'third_party/boringssl/crypto/x509/x509_ext.c', - 'third_party/boringssl/crypto/x509/x509_lu.c', - 'third_party/boringssl/crypto/x509/x509_obj.c', - 'third_party/boringssl/crypto/x509/x509_r2x.c', - 'third_party/boringssl/crypto/x509/x509_req.c', - 'third_party/boringssl/crypto/x509/x509_set.c', - 'third_party/boringssl/crypto/x509/x509_trs.c', - 'third_party/boringssl/crypto/x509/x509_txt.c', - 'third_party/boringssl/crypto/x509/x509_v3.c', - 'third_party/boringssl/crypto/x509/x509_vfy.c', - 'third_party/boringssl/crypto/x509/x509_vpm.c', - 'third_party/boringssl/crypto/x509/x509cset.c', - 'third_party/boringssl/crypto/x509/x509name.c', - 'third_party/boringssl/crypto/x509/x509rset.c', - 'third_party/boringssl/crypto/x509/x509spki.c', - 'third_party/boringssl/crypto/x509/x509type.c', - 'third_party/boringssl/crypto/x509/x_algor.c', - 'third_party/boringssl/crypto/x509/x_all.c', - 'third_party/boringssl/crypto/x509/x_attrib.c', - 'third_party/boringssl/crypto/x509/x_crl.c', - 'third_party/boringssl/crypto/x509/x_exten.c', - 'third_party/boringssl/crypto/x509/x_info.c', - 'third_party/boringssl/crypto/x509/x_name.c', - 'third_party/boringssl/crypto/x509/x_pkey.c', - 'third_party/boringssl/crypto/x509/x_pubkey.c', - 'third_party/boringssl/crypto/x509/x_req.c', - 'third_party/boringssl/crypto/x509/x_sig.c', - 'third_party/boringssl/crypto/x509/x_spki.c', - 'third_party/boringssl/crypto/x509/x_val.c', - 'third_party/boringssl/crypto/x509/x_x509.c', - 'third_party/boringssl/crypto/x509/x_x509a.c', - 'third_party/boringssl/crypto/x509v3/pcy_cache.c', - 'third_party/boringssl/crypto/x509v3/pcy_data.c', - 'third_party/boringssl/crypto/x509v3/pcy_lib.c', - 'third_party/boringssl/crypto/x509v3/pcy_map.c', - 'third_party/boringssl/crypto/x509v3/pcy_node.c', - 'third_party/boringssl/crypto/x509v3/pcy_tree.c', - 'third_party/boringssl/crypto/x509v3/v3_akey.c', - 'third_party/boringssl/crypto/x509v3/v3_akeya.c', - 'third_party/boringssl/crypto/x509v3/v3_alt.c', - 'third_party/boringssl/crypto/x509v3/v3_bcons.c', - 'third_party/boringssl/crypto/x509v3/v3_bitst.c', - 'third_party/boringssl/crypto/x509v3/v3_conf.c', - 'third_party/boringssl/crypto/x509v3/v3_cpols.c', - 'third_party/boringssl/crypto/x509v3/v3_crld.c', - 'third_party/boringssl/crypto/x509v3/v3_enum.c', - 'third_party/boringssl/crypto/x509v3/v3_extku.c', - 'third_party/boringssl/crypto/x509v3/v3_genn.c', - 'third_party/boringssl/crypto/x509v3/v3_ia5.c', - 'third_party/boringssl/crypto/x509v3/v3_info.c', - 'third_party/boringssl/crypto/x509v3/v3_int.c', - 'third_party/boringssl/crypto/x509v3/v3_lib.c', - 'third_party/boringssl/crypto/x509v3/v3_ncons.c', - 'third_party/boringssl/crypto/x509v3/v3_pci.c', - 'third_party/boringssl/crypto/x509v3/v3_pcia.c', - 'third_party/boringssl/crypto/x509v3/v3_pcons.c', - 'third_party/boringssl/crypto/x509v3/v3_pku.c', - 'third_party/boringssl/crypto/x509v3/v3_pmaps.c', - 'third_party/boringssl/crypto/x509v3/v3_prn.c', - 'third_party/boringssl/crypto/x509v3/v3_purp.c', - 'third_party/boringssl/crypto/x509v3/v3_skey.c', - 'third_party/boringssl/crypto/x509v3/v3_sxnet.c', - 'third_party/boringssl/crypto/x509v3/v3_utl.c', - 'third_party/boringssl/ssl/bio_ssl.c', - 'third_party/boringssl/ssl/custom_extensions.c', - 'third_party/boringssl/ssl/d1_both.c', - 'third_party/boringssl/ssl/d1_lib.c', - 'third_party/boringssl/ssl/d1_pkt.c', - 'third_party/boringssl/ssl/d1_srtp.c', - 'third_party/boringssl/ssl/dtls_method.c', - 'third_party/boringssl/ssl/dtls_record.c', - 'third_party/boringssl/ssl/handshake_client.c', - 'third_party/boringssl/ssl/handshake_server.c', - 'third_party/boringssl/ssl/s3_both.c', - 'third_party/boringssl/ssl/s3_lib.c', - 'third_party/boringssl/ssl/s3_pkt.c', - 'third_party/boringssl/ssl/ssl_aead_ctx.c', - 'third_party/boringssl/ssl/ssl_asn1.c', - 'third_party/boringssl/ssl/ssl_buffer.c', - 'third_party/boringssl/ssl/ssl_cert.c', - 'third_party/boringssl/ssl/ssl_cipher.c', - 'third_party/boringssl/ssl/ssl_ecdh.c', - 'third_party/boringssl/ssl/ssl_file.c', - 'third_party/boringssl/ssl/ssl_lib.c', - 'third_party/boringssl/ssl/ssl_privkey.c', - 'third_party/boringssl/ssl/ssl_privkey_cc.cc', - 'third_party/boringssl/ssl/ssl_session.c', - 'third_party/boringssl/ssl/ssl_stat.c', - 'third_party/boringssl/ssl/ssl_transcript.c', - 'third_party/boringssl/ssl/ssl_x509.c', - 'third_party/boringssl/ssl/t1_enc.c', - 'third_party/boringssl/ssl/t1_lib.c', - 'third_party/boringssl/ssl/tls13_both.c', - 'third_party/boringssl/ssl/tls13_client.c', - 'third_party/boringssl/ssl/tls13_enc.c', - 'third_party/boringssl/ssl/tls13_server.c', - 'third_party/boringssl/ssl/tls_method.c', - 'third_party/boringssl/ssl/tls_record.c', - 'third_party/zlib/adler32.c', - 'third_party/zlib/compress.c', - 'third_party/zlib/crc32.c', - 'third_party/zlib/deflate.c', - 'third_party/zlib/gzclose.c', - 'third_party/zlib/gzlib.c', - 'third_party/zlib/gzread.c', - 'third_party/zlib/gzwrite.c', - 'third_party/zlib/infback.c', - 'third_party/zlib/inffast.c', - 'third_party/zlib/inflate.c', - 'third_party/zlib/inftrees.c', - 'third_party/zlib/trees.c', - 'third_party/zlib/uncompr.c', - 'third_party/zlib/zutil.c', - 'third_party/cares/cares/ares__close_sockets.c', - 'third_party/cares/cares/ares__get_hostent.c', - 'third_party/cares/cares/ares__read_line.c', - 'third_party/cares/cares/ares__timeval.c', - 'third_party/cares/cares/ares_cancel.c', - 'third_party/cares/cares/ares_create_query.c', - 'third_party/cares/cares/ares_data.c', - 'third_party/cares/cares/ares_destroy.c', - 'third_party/cares/cares/ares_expand_name.c', - 'third_party/cares/cares/ares_expand_string.c', - 'third_party/cares/cares/ares_fds.c', - 'third_party/cares/cares/ares_free_hostent.c', - 'third_party/cares/cares/ares_free_string.c', - 'third_party/cares/cares/ares_getenv.c', - 'third_party/cares/cares/ares_gethostbyaddr.c', - 'third_party/cares/cares/ares_gethostbyname.c', - 'third_party/cares/cares/ares_getnameinfo.c', - 'third_party/cares/cares/ares_getopt.c', - 'third_party/cares/cares/ares_getsock.c', - 'third_party/cares/cares/ares_init.c', - 'third_party/cares/cares/ares_library_init.c', - 'third_party/cares/cares/ares_llist.c', - 'third_party/cares/cares/ares_mkquery.c', - 'third_party/cares/cares/ares_nowarn.c', - 'third_party/cares/cares/ares_options.c', - 'third_party/cares/cares/ares_parse_a_reply.c', - 'third_party/cares/cares/ares_parse_aaaa_reply.c', - 'third_party/cares/cares/ares_parse_mx_reply.c', - 'third_party/cares/cares/ares_parse_naptr_reply.c', - 'third_party/cares/cares/ares_parse_ns_reply.c', - 'third_party/cares/cares/ares_parse_ptr_reply.c', - 'third_party/cares/cares/ares_parse_soa_reply.c', - 'third_party/cares/cares/ares_parse_srv_reply.c', - 'third_party/cares/cares/ares_parse_txt_reply.c', - 'third_party/cares/cares/ares_platform.c', - 'third_party/cares/cares/ares_process.c', - 'third_party/cares/cares/ares_query.c', - 'third_party/cares/cares/ares_search.c', - 'third_party/cares/cares/ares_send.c', - 'third_party/cares/cares/ares_strcasecmp.c', - 'third_party/cares/cares/ares_strdup.c', - 'third_party/cares/cares/ares_strerror.c', - 'third_party/cares/cares/ares_timeout.c', - 'third_party/cares/cares/ares_version.c', - 'third_party/cares/cares/ares_writev.c', - 'third_party/cares/cares/bitncmp.c', - 'third_party/cares/cares/inet_net_pton.c', - 'third_party/cares/cares/inet_ntop.c', - 'third_party/cares/cares/windows_port.c', + 'src/core/lib/profiling/basic_timers.cc', + 'src/core/lib/profiling/stap_timers.cc', + 'src/core/lib/support/alloc.cc', + 'src/core/lib/support/arena.cc', + 'src/core/lib/support/atm.cc', + 'src/core/lib/support/avl.cc', + 'src/core/lib/support/cmdline.cc', + 'src/core/lib/support/cpu_iphone.cc', + 'src/core/lib/support/cpu_linux.cc', + 'src/core/lib/support/cpu_posix.cc', + 'src/core/lib/support/cpu_windows.cc', + 'src/core/lib/support/env_linux.cc', + 'src/core/lib/support/env_posix.cc', + 'src/core/lib/support/env_windows.cc', + 'src/core/lib/support/fork.cc', + 'src/core/lib/support/host_port.cc', + 'src/core/lib/support/log.cc', + 'src/core/lib/support/log_android.cc', + 'src/core/lib/support/log_linux.cc', + 'src/core/lib/support/log_posix.cc', + 'src/core/lib/support/log_windows.cc', + 'src/core/lib/support/mpscq.cc', + 'src/core/lib/support/murmur_hash.cc', + 'src/core/lib/support/string.cc', + 'src/core/lib/support/string_posix.cc', + 'src/core/lib/support/string_util_windows.cc', + 'src/core/lib/support/string_windows.cc', + 'src/core/lib/support/subprocess_posix.cc', + 'src/core/lib/support/subprocess_windows.cc', + 'src/core/lib/support/sync.cc', + 'src/core/lib/support/sync_posix.cc', + 'src/core/lib/support/sync_windows.cc', + 'src/core/lib/support/thd.cc', + 'src/core/lib/support/thd_posix.cc', + 'src/core/lib/support/thd_windows.cc', + 'src/core/lib/support/time.cc', + 'src/core/lib/support/time_posix.cc', + 'src/core/lib/support/time_precise.cc', + 'src/core/lib/support/time_windows.cc', + 'src/core/lib/support/tls_pthread.cc', + 'src/core/lib/support/tmpfile_msys.cc', + 'src/core/lib/support/tmpfile_posix.cc', + 'src/core/lib/support/tmpfile_windows.cc', + 'src/core/lib/support/wrap_memcpy.cc', + 'src/core/lib/surface/init.cc', + 'src/core/lib/backoff/backoff.cc', + 'src/core/lib/channel/channel_args.cc', + 'src/core/lib/channel/channel_stack.cc', + 'src/core/lib/channel/channel_stack_builder.cc', + 'src/core/lib/channel/connected_channel.cc', + 'src/core/lib/channel/handshaker.cc', + 'src/core/lib/channel/handshaker_factory.cc', + 'src/core/lib/channel/handshaker_registry.cc', + 'src/core/lib/compression/compression.cc', + 'src/core/lib/compression/compression_internal.cc', + 'src/core/lib/compression/compression_ruby.cc', + 'src/core/lib/compression/message_compress.cc', + 'src/core/lib/compression/stream_compression.cc', + 'src/core/lib/compression/stream_compression_gzip.cc', + 'src/core/lib/compression/stream_compression_identity.cc', + 'src/core/lib/debug/stats.cc', + 'src/core/lib/debug/stats_data.cc', + 'src/core/lib/http/format_request.cc', + 'src/core/lib/http/httpcli.cc', + 'src/core/lib/http/parser.cc', + 'src/core/lib/iomgr/call_combiner.cc', + 'src/core/lib/iomgr/combiner.cc', + 'src/core/lib/iomgr/endpoint.cc', + 'src/core/lib/iomgr/endpoint_pair_posix.cc', + 'src/core/lib/iomgr/endpoint_pair_uv.cc', + 'src/core/lib/iomgr/endpoint_pair_windows.cc', + 'src/core/lib/iomgr/error.cc', + 'src/core/lib/iomgr/ev_epoll1_linux.cc', + 'src/core/lib/iomgr/ev_epollex_linux.cc', + 'src/core/lib/iomgr/ev_epollsig_linux.cc', + 'src/core/lib/iomgr/ev_poll_posix.cc', + 'src/core/lib/iomgr/ev_posix.cc', + 'src/core/lib/iomgr/ev_windows.cc', + 'src/core/lib/iomgr/exec_ctx.cc', + 'src/core/lib/iomgr/executor.cc', + 'src/core/lib/iomgr/fork_posix.cc', + 'src/core/lib/iomgr/fork_windows.cc', + 'src/core/lib/iomgr/gethostname_fallback.cc', + 'src/core/lib/iomgr/gethostname_host_name_max.cc', + 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/iocp_windows.cc', + 'src/core/lib/iomgr/iomgr.cc', + 'src/core/lib/iomgr/iomgr_posix.cc', + 'src/core/lib/iomgr/iomgr_uv.cc', + 'src/core/lib/iomgr/iomgr_windows.cc', + 'src/core/lib/iomgr/is_epollexclusive_available.cc', + 'src/core/lib/iomgr/load_file.cc', + 'src/core/lib/iomgr/lockfree_event.cc', + 'src/core/lib/iomgr/network_status_tracker.cc', + 'src/core/lib/iomgr/polling_entity.cc', + 'src/core/lib/iomgr/pollset_set_uv.cc', + 'src/core/lib/iomgr/pollset_set_windows.cc', + 'src/core/lib/iomgr/pollset_uv.cc', + 'src/core/lib/iomgr/pollset_windows.cc', + 'src/core/lib/iomgr/resolve_address_posix.cc', + 'src/core/lib/iomgr/resolve_address_uv.cc', + 'src/core/lib/iomgr/resolve_address_windows.cc', + 'src/core/lib/iomgr/resource_quota.cc', + 'src/core/lib/iomgr/sockaddr_utils.cc', + 'src/core/lib/iomgr/socket_factory_posix.cc', + 'src/core/lib/iomgr/socket_mutator.cc', + 'src/core/lib/iomgr/socket_utils_common_posix.cc', + 'src/core/lib/iomgr/socket_utils_linux.cc', + 'src/core/lib/iomgr/socket_utils_posix.cc', + 'src/core/lib/iomgr/socket_utils_uv.cc', + 'src/core/lib/iomgr/socket_utils_windows.cc', + 'src/core/lib/iomgr/socket_windows.cc', + 'src/core/lib/iomgr/tcp_client_posix.cc', + 'src/core/lib/iomgr/tcp_client_uv.cc', + 'src/core/lib/iomgr/tcp_client_windows.cc', + 'src/core/lib/iomgr/tcp_posix.cc', + 'src/core/lib/iomgr/tcp_server_posix.cc', + 'src/core/lib/iomgr/tcp_server_utils_posix_common.cc', + 'src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc', + 'src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc', + 'src/core/lib/iomgr/tcp_server_uv.cc', + 'src/core/lib/iomgr/tcp_server_windows.cc', + 'src/core/lib/iomgr/tcp_uv.cc', + 'src/core/lib/iomgr/tcp_windows.cc', + 'src/core/lib/iomgr/time_averaged_stats.cc', + 'src/core/lib/iomgr/timer_generic.cc', + 'src/core/lib/iomgr/timer_heap.cc', + 'src/core/lib/iomgr/timer_manager.cc', + 'src/core/lib/iomgr/timer_uv.cc', + 'src/core/lib/iomgr/udp_server.cc', + 'src/core/lib/iomgr/unix_sockets_posix.cc', + 'src/core/lib/iomgr/unix_sockets_posix_noop.cc', + 'src/core/lib/iomgr/wakeup_fd_cv.cc', + 'src/core/lib/iomgr/wakeup_fd_eventfd.cc', + 'src/core/lib/iomgr/wakeup_fd_nospecial.cc', + 'src/core/lib/iomgr/wakeup_fd_pipe.cc', + 'src/core/lib/iomgr/wakeup_fd_posix.cc', + 'src/core/lib/json/json.cc', + 'src/core/lib/json/json_reader.cc', + 'src/core/lib/json/json_string.cc', + 'src/core/lib/json/json_writer.cc', + 'src/core/lib/slice/b64.cc', + 'src/core/lib/slice/percent_encoding.cc', + 'src/core/lib/slice/slice.cc', + 'src/core/lib/slice/slice_buffer.cc', + 'src/core/lib/slice/slice_hash_table.cc', + 'src/core/lib/slice/slice_intern.cc', + 'src/core/lib/slice/slice_string_helpers.cc', + 'src/core/lib/surface/alarm.cc', + 'src/core/lib/surface/api_trace.cc', + 'src/core/lib/surface/byte_buffer.cc', + 'src/core/lib/surface/byte_buffer_reader.cc', + 'src/core/lib/surface/call.cc', + 'src/core/lib/surface/call_details.cc', + 'src/core/lib/surface/call_log_batch.cc', + 'src/core/lib/surface/channel.cc', + 'src/core/lib/surface/channel_init.cc', + 'src/core/lib/surface/channel_ping.cc', + 'src/core/lib/surface/channel_stack_type.cc', + 'src/core/lib/surface/completion_queue.cc', + 'src/core/lib/surface/completion_queue_factory.cc', + 'src/core/lib/surface/event_string.cc', + 'src/core/lib/surface/lame_client.cc', + 'src/core/lib/surface/metadata_array.cc', + 'src/core/lib/surface/server.cc', + 'src/core/lib/surface/validate_metadata.cc', + 'src/core/lib/surface/version.cc', + 'src/core/lib/transport/bdp_estimator.cc', + 'src/core/lib/transport/byte_stream.cc', + 'src/core/lib/transport/connectivity_state.cc', + 'src/core/lib/transport/error_utils.cc', + 'src/core/lib/transport/metadata.cc', + 'src/core/lib/transport/metadata_batch.cc', + 'src/core/lib/transport/pid_controller.cc', + 'src/core/lib/transport/service_config.cc', + 'src/core/lib/transport/static_metadata.cc', + 'src/core/lib/transport/status_conversion.cc', + 'src/core/lib/transport/timeout_encoding.cc', + 'src/core/lib/transport/transport.cc', + 'src/core/lib/transport/transport_op_string.cc', + 'src/core/lib/debug/trace.cc', + 'src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc', + 'src/core/ext/transport/chttp2/transport/bin_decoder.cc', + 'src/core/ext/transport/chttp2/transport/bin_encoder.cc', + 'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc', + 'src/core/ext/transport/chttp2/transport/chttp2_transport.cc', + 'src/core/ext/transport/chttp2/transport/flow_control.cc', + 'src/core/ext/transport/chttp2/transport/frame_data.cc', + 'src/core/ext/transport/chttp2/transport/frame_goaway.cc', + 'src/core/ext/transport/chttp2/transport/frame_ping.cc', + 'src/core/ext/transport/chttp2/transport/frame_rst_stream.cc', + 'src/core/ext/transport/chttp2/transport/frame_settings.cc', + 'src/core/ext/transport/chttp2/transport/frame_window_update.cc', + 'src/core/ext/transport/chttp2/transport/hpack_encoder.cc', + 'src/core/ext/transport/chttp2/transport/hpack_parser.cc', + 'src/core/ext/transport/chttp2/transport/hpack_table.cc', + 'src/core/ext/transport/chttp2/transport/http2_settings.cc', + 'src/core/ext/transport/chttp2/transport/huffsyms.cc', + 'src/core/ext/transport/chttp2/transport/incoming_metadata.cc', + 'src/core/ext/transport/chttp2/transport/parsing.cc', + 'src/core/ext/transport/chttp2/transport/stream_lists.cc', + 'src/core/ext/transport/chttp2/transport/stream_map.cc', + 'src/core/ext/transport/chttp2/transport/varint.cc', + 'src/core/ext/transport/chttp2/transport/writing.cc', + 'src/core/ext/transport/chttp2/alpn/alpn.cc', + 'src/core/ext/filters/http/client/http_client_filter.cc', + 'src/core/ext/filters/http/http_filters_plugin.cc', + 'src/core/ext/filters/http/message_compress/message_compress_filter.cc', + 'src/core/ext/filters/http/server/http_server_filter.cc', + 'src/core/lib/http/httpcli_security_connector.cc', + 'src/core/lib/security/context/security_context.cc', + 'src/core/lib/security/credentials/composite/composite_credentials.cc', + 'src/core/lib/security/credentials/credentials.cc', + 'src/core/lib/security/credentials/credentials_metadata.cc', + 'src/core/lib/security/credentials/fake/fake_credentials.cc', + 'src/core/lib/security/credentials/google_default/credentials_generic.cc', + 'src/core/lib/security/credentials/google_default/google_default_credentials.cc', + 'src/core/lib/security/credentials/iam/iam_credentials.cc', + 'src/core/lib/security/credentials/jwt/json_token.cc', + 'src/core/lib/security/credentials/jwt/jwt_credentials.cc', + 'src/core/lib/security/credentials/jwt/jwt_verifier.cc', + 'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc', + 'src/core/lib/security/credentials/plugin/plugin_credentials.cc', + 'src/core/lib/security/credentials/ssl/ssl_credentials.cc', + 'src/core/lib/security/transport/client_auth_filter.cc', + 'src/core/lib/security/transport/lb_targets_info.cc', + 'src/core/lib/security/transport/secure_endpoint.cc', + 'src/core/lib/security/transport/security_connector.cc', + 'src/core/lib/security/transport/security_handshaker.cc', + 'src/core/lib/security/transport/server_auth_filter.cc', + 'src/core/lib/security/transport/tsi_error.cc', + 'src/core/lib/security/util/json_util.cc', + 'src/core/lib/surface/init_secure.cc', + 'src/core/tsi/fake_transport_security.cc', + 'src/core/tsi/gts_transport_security.cc', + 'src/core/tsi/ssl_transport_security.cc', + 'src/core/tsi/transport_security_grpc.cc', + 'src/core/tsi/transport_security.cc', + 'src/core/tsi/transport_security_adapter.cc', + 'src/core/ext/transport/chttp2/server/chttp2_server.cc', + 'src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc', + 'src/core/ext/filters/client_channel/backup_poller.cc', + 'src/core/ext/filters/client_channel/channel_connectivity.cc', + 'src/core/ext/filters/client_channel/client_channel.cc', + 'src/core/ext/filters/client_channel/client_channel_factory.cc', + 'src/core/ext/filters/client_channel/client_channel_plugin.cc', + 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', + 'src/core/ext/filters/client_channel/http_proxy.cc', + 'src/core/ext/filters/client_channel/lb_policy.cc', + 'src/core/ext/filters/client_channel/lb_policy_factory.cc', + 'src/core/ext/filters/client_channel/lb_policy_registry.cc', + 'src/core/ext/filters/client_channel/parse_address.cc', + 'src/core/ext/filters/client_channel/proxy_mapper.cc', + 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', + 'src/core/ext/filters/client_channel/resolver.cc', + 'src/core/ext/filters/client_channel/resolver_factory.cc', + 'src/core/ext/filters/client_channel/resolver_registry.cc', + 'src/core/ext/filters/client_channel/retry_throttle.cc', + 'src/core/ext/filters/client_channel/subchannel.cc', + 'src/core/ext/filters/client_channel/subchannel_index.cc', + 'src/core/ext/filters/client_channel/uri_parser.cc', + 'src/core/ext/filters/deadline/deadline_filter.cc', + 'src/core/ext/transport/chttp2/client/chttp2_connector.cc', + 'src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc', + 'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc', + 'src/core/ext/transport/chttp2/client/insecure/channel_create.cc', + 'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc', + 'src/core/ext/transport/inproc/inproc_plugin.cc', + 'src/core/ext/transport/inproc/inproc_transport.cc', + 'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc', + 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc', + 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc', + 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc', + 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc', + 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c', + 'third_party/nanopb/pb_common.c', + 'third_party/nanopb/pb_decode.c', + 'third_party/nanopb/pb_encode.c', + 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc', + 'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc', + 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc', + 'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', + 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', + 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', + 'src/core/ext/filters/load_reporting/server_load_reporting_filter.cc', + 'src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc', + 'src/core/ext/census/grpc_context.cc', + 'src/core/ext/filters/max_age/max_age_filter.cc', + 'src/core/ext/filters/message_size/message_size_filter.cc', + 'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc', + 'src/core/ext/filters/workarounds/workaround_utils.cc', + 'src/core/plugin_registry/grpc_plugin_registry.cc', + 'src/boringssl/err_data.c', + 'third_party/boringssl/crypto/aes/aes.c', + 'third_party/boringssl/crypto/aes/key_wrap.c', + 'third_party/boringssl/crypto/aes/mode_wrappers.c', + 'third_party/boringssl/crypto/asn1/a_bitstr.c', + 'third_party/boringssl/crypto/asn1/a_bool.c', + 'third_party/boringssl/crypto/asn1/a_d2i_fp.c', + 'third_party/boringssl/crypto/asn1/a_dup.c', + 'third_party/boringssl/crypto/asn1/a_enum.c', + 'third_party/boringssl/crypto/asn1/a_gentm.c', + 'third_party/boringssl/crypto/asn1/a_i2d_fp.c', + 'third_party/boringssl/crypto/asn1/a_int.c', + 'third_party/boringssl/crypto/asn1/a_mbstr.c', + 'third_party/boringssl/crypto/asn1/a_object.c', + 'third_party/boringssl/crypto/asn1/a_octet.c', + 'third_party/boringssl/crypto/asn1/a_print.c', + 'third_party/boringssl/crypto/asn1/a_strnid.c', + 'third_party/boringssl/crypto/asn1/a_time.c', + 'third_party/boringssl/crypto/asn1/a_type.c', + 'third_party/boringssl/crypto/asn1/a_utctm.c', + 'third_party/boringssl/crypto/asn1/a_utf8.c', + 'third_party/boringssl/crypto/asn1/asn1_lib.c', + 'third_party/boringssl/crypto/asn1/asn1_par.c', + 'third_party/boringssl/crypto/asn1/asn_pack.c', + 'third_party/boringssl/crypto/asn1/f_enum.c', + 'third_party/boringssl/crypto/asn1/f_int.c', + 'third_party/boringssl/crypto/asn1/f_string.c', + 'third_party/boringssl/crypto/asn1/t_bitst.c', + 'third_party/boringssl/crypto/asn1/tasn_dec.c', + 'third_party/boringssl/crypto/asn1/tasn_enc.c', + 'third_party/boringssl/crypto/asn1/tasn_fre.c', + 'third_party/boringssl/crypto/asn1/tasn_new.c', + 'third_party/boringssl/crypto/asn1/tasn_typ.c', + 'third_party/boringssl/crypto/asn1/tasn_utl.c', + 'third_party/boringssl/crypto/asn1/time_support.c', + 'third_party/boringssl/crypto/asn1/x_bignum.c', + 'third_party/boringssl/crypto/asn1/x_long.c', + 'third_party/boringssl/crypto/base64/base64.c', + 'third_party/boringssl/crypto/bio/bio.c', + 'third_party/boringssl/crypto/bio/bio_mem.c', + 'third_party/boringssl/crypto/bio/connect.c', + 'third_party/boringssl/crypto/bio/fd.c', + 'third_party/boringssl/crypto/bio/file.c', + 'third_party/boringssl/crypto/bio/hexdump.c', + 'third_party/boringssl/crypto/bio/pair.c', + 'third_party/boringssl/crypto/bio/printf.c', + 'third_party/boringssl/crypto/bio/socket.c', + 'third_party/boringssl/crypto/bio/socket_helper.c', + 'third_party/boringssl/crypto/bn/add.c', + 'third_party/boringssl/crypto/bn/asm/x86_64-gcc.c', + 'third_party/boringssl/crypto/bn/bn.c', + 'third_party/boringssl/crypto/bn/bn_asn1.c', + 'third_party/boringssl/crypto/bn/cmp.c', + 'third_party/boringssl/crypto/bn/convert.c', + 'third_party/boringssl/crypto/bn/ctx.c', + 'third_party/boringssl/crypto/bn/div.c', + 'third_party/boringssl/crypto/bn/exponentiation.c', + 'third_party/boringssl/crypto/bn/gcd.c', + 'third_party/boringssl/crypto/bn/generic.c', + 'third_party/boringssl/crypto/bn/kronecker.c', + 'third_party/boringssl/crypto/bn/montgomery.c', + 'third_party/boringssl/crypto/bn/montgomery_inv.c', + 'third_party/boringssl/crypto/bn/mul.c', + 'third_party/boringssl/crypto/bn/prime.c', + 'third_party/boringssl/crypto/bn/random.c', + 'third_party/boringssl/crypto/bn/rsaz_exp.c', + 'third_party/boringssl/crypto/bn/shift.c', + 'third_party/boringssl/crypto/bn/sqrt.c', + 'third_party/boringssl/crypto/buf/buf.c', + 'third_party/boringssl/crypto/bytestring/asn1_compat.c', + 'third_party/boringssl/crypto/bytestring/ber.c', + 'third_party/boringssl/crypto/bytestring/cbb.c', + 'third_party/boringssl/crypto/bytestring/cbs.c', + 'third_party/boringssl/crypto/chacha/chacha.c', + 'third_party/boringssl/crypto/cipher/aead.c', + 'third_party/boringssl/crypto/cipher/cipher.c', + 'third_party/boringssl/crypto/cipher/derive_key.c', + 'third_party/boringssl/crypto/cipher/e_aes.c', + 'third_party/boringssl/crypto/cipher/e_chacha20poly1305.c', + 'third_party/boringssl/crypto/cipher/e_des.c', + 'third_party/boringssl/crypto/cipher/e_null.c', + 'third_party/boringssl/crypto/cipher/e_rc2.c', + 'third_party/boringssl/crypto/cipher/e_rc4.c', + 'third_party/boringssl/crypto/cipher/e_ssl3.c', + 'third_party/boringssl/crypto/cipher/e_tls.c', + 'third_party/boringssl/crypto/cipher/tls_cbc.c', + 'third_party/boringssl/crypto/cmac/cmac.c', + 'third_party/boringssl/crypto/conf/conf.c', + 'third_party/boringssl/crypto/cpu-aarch64-linux.c', + 'third_party/boringssl/crypto/cpu-arm-linux.c', + 'third_party/boringssl/crypto/cpu-arm.c', + 'third_party/boringssl/crypto/cpu-intel.c', + 'third_party/boringssl/crypto/cpu-ppc64le.c', + 'third_party/boringssl/crypto/crypto.c', + 'third_party/boringssl/crypto/curve25519/curve25519.c', + 'third_party/boringssl/crypto/curve25519/spake25519.c', + 'third_party/boringssl/crypto/curve25519/x25519-x86_64.c', + 'third_party/boringssl/crypto/des/des.c', + 'third_party/boringssl/crypto/dh/check.c', + 'third_party/boringssl/crypto/dh/dh.c', + 'third_party/boringssl/crypto/dh/dh_asn1.c', + 'third_party/boringssl/crypto/dh/params.c', + 'third_party/boringssl/crypto/digest/digest.c', + 'third_party/boringssl/crypto/digest/digests.c', + 'third_party/boringssl/crypto/dsa/dsa.c', + 'third_party/boringssl/crypto/dsa/dsa_asn1.c', + 'third_party/boringssl/crypto/ec/ec.c', + 'third_party/boringssl/crypto/ec/ec_asn1.c', + 'third_party/boringssl/crypto/ec/ec_key.c', + 'third_party/boringssl/crypto/ec/ec_montgomery.c', + 'third_party/boringssl/crypto/ec/oct.c', + 'third_party/boringssl/crypto/ec/p224-64.c', + 'third_party/boringssl/crypto/ec/p256-64.c', + 'third_party/boringssl/crypto/ec/p256-x86_64.c', + 'third_party/boringssl/crypto/ec/simple.c', + 'third_party/boringssl/crypto/ec/util-64.c', + 'third_party/boringssl/crypto/ec/wnaf.c', + 'third_party/boringssl/crypto/ecdh/ecdh.c', + 'third_party/boringssl/crypto/ecdsa/ecdsa.c', + 'third_party/boringssl/crypto/ecdsa/ecdsa_asn1.c', + 'third_party/boringssl/crypto/engine/engine.c', + 'third_party/boringssl/crypto/err/err.c', + 'third_party/boringssl/crypto/evp/digestsign.c', + 'third_party/boringssl/crypto/evp/evp.c', + 'third_party/boringssl/crypto/evp/evp_asn1.c', + 'third_party/boringssl/crypto/evp/evp_ctx.c', + 'third_party/boringssl/crypto/evp/p_dsa_asn1.c', + 'third_party/boringssl/crypto/evp/p_ec.c', + 'third_party/boringssl/crypto/evp/p_ec_asn1.c', + 'third_party/boringssl/crypto/evp/p_rsa.c', + 'third_party/boringssl/crypto/evp/p_rsa_asn1.c', + 'third_party/boringssl/crypto/evp/pbkdf.c', + 'third_party/boringssl/crypto/evp/print.c', + 'third_party/boringssl/crypto/evp/sign.c', + 'third_party/boringssl/crypto/ex_data.c', + 'third_party/boringssl/crypto/hkdf/hkdf.c', + 'third_party/boringssl/crypto/hmac/hmac.c', + 'third_party/boringssl/crypto/lhash/lhash.c', + 'third_party/boringssl/crypto/md4/md4.c', + 'third_party/boringssl/crypto/md5/md5.c', + 'third_party/boringssl/crypto/mem.c', + 'third_party/boringssl/crypto/modes/cbc.c', + 'third_party/boringssl/crypto/modes/cfb.c', + 'third_party/boringssl/crypto/modes/ctr.c', + 'third_party/boringssl/crypto/modes/gcm.c', + 'third_party/boringssl/crypto/modes/ofb.c', + 'third_party/boringssl/crypto/modes/polyval.c', + 'third_party/boringssl/crypto/obj/obj.c', + 'third_party/boringssl/crypto/obj/obj_xref.c', + 'third_party/boringssl/crypto/pem/pem_all.c', + 'third_party/boringssl/crypto/pem/pem_info.c', + 'third_party/boringssl/crypto/pem/pem_lib.c', + 'third_party/boringssl/crypto/pem/pem_oth.c', + 'third_party/boringssl/crypto/pem/pem_pk8.c', + 'third_party/boringssl/crypto/pem/pem_pkey.c', + 'third_party/boringssl/crypto/pem/pem_x509.c', + 'third_party/boringssl/crypto/pem/pem_xaux.c', + 'third_party/boringssl/crypto/pkcs8/p5_pbev2.c', + 'third_party/boringssl/crypto/pkcs8/p8_pkey.c', + 'third_party/boringssl/crypto/pkcs8/pkcs8.c', + 'third_party/boringssl/crypto/poly1305/poly1305.c', + 'third_party/boringssl/crypto/poly1305/poly1305_arm.c', + 'third_party/boringssl/crypto/poly1305/poly1305_vec.c', + 'third_party/boringssl/crypto/pool/pool.c', + 'third_party/boringssl/crypto/rand/deterministic.c', + 'third_party/boringssl/crypto/rand/fuchsia.c', + 'third_party/boringssl/crypto/rand/rand.c', + 'third_party/boringssl/crypto/rand/urandom.c', + 'third_party/boringssl/crypto/rand/windows.c', + 'third_party/boringssl/crypto/rc4/rc4.c', + 'third_party/boringssl/crypto/refcount_c11.c', + 'third_party/boringssl/crypto/refcount_lock.c', + 'third_party/boringssl/crypto/rsa/blinding.c', + 'third_party/boringssl/crypto/rsa/padding.c', + 'third_party/boringssl/crypto/rsa/rsa.c', + 'third_party/boringssl/crypto/rsa/rsa_asn1.c', + 'third_party/boringssl/crypto/rsa/rsa_impl.c', + 'third_party/boringssl/crypto/sha/sha1-altivec.c', + 'third_party/boringssl/crypto/sha/sha1.c', + 'third_party/boringssl/crypto/sha/sha256.c', + 'third_party/boringssl/crypto/sha/sha512.c', + 'third_party/boringssl/crypto/stack/stack.c', + 'third_party/boringssl/crypto/thread.c', + 'third_party/boringssl/crypto/thread_none.c', + 'third_party/boringssl/crypto/thread_pthread.c', + 'third_party/boringssl/crypto/thread_win.c', + 'third_party/boringssl/crypto/x509/a_digest.c', + 'third_party/boringssl/crypto/x509/a_sign.c', + 'third_party/boringssl/crypto/x509/a_strex.c', + 'third_party/boringssl/crypto/x509/a_verify.c', + 'third_party/boringssl/crypto/x509/algorithm.c', + 'third_party/boringssl/crypto/x509/asn1_gen.c', + 'third_party/boringssl/crypto/x509/by_dir.c', + 'third_party/boringssl/crypto/x509/by_file.c', + 'third_party/boringssl/crypto/x509/i2d_pr.c', + 'third_party/boringssl/crypto/x509/pkcs7.c', + 'third_party/boringssl/crypto/x509/rsa_pss.c', + 'third_party/boringssl/crypto/x509/t_crl.c', + 'third_party/boringssl/crypto/x509/t_req.c', + 'third_party/boringssl/crypto/x509/t_x509.c', + 'third_party/boringssl/crypto/x509/t_x509a.c', + 'third_party/boringssl/crypto/x509/x509.c', + 'third_party/boringssl/crypto/x509/x509_att.c', + 'third_party/boringssl/crypto/x509/x509_cmp.c', + 'third_party/boringssl/crypto/x509/x509_d2.c', + 'third_party/boringssl/crypto/x509/x509_def.c', + 'third_party/boringssl/crypto/x509/x509_ext.c', + 'third_party/boringssl/crypto/x509/x509_lu.c', + 'third_party/boringssl/crypto/x509/x509_obj.c', + 'third_party/boringssl/crypto/x509/x509_r2x.c', + 'third_party/boringssl/crypto/x509/x509_req.c', + 'third_party/boringssl/crypto/x509/x509_set.c', + 'third_party/boringssl/crypto/x509/x509_trs.c', + 'third_party/boringssl/crypto/x509/x509_txt.c', + 'third_party/boringssl/crypto/x509/x509_v3.c', + 'third_party/boringssl/crypto/x509/x509_vfy.c', + 'third_party/boringssl/crypto/x509/x509_vpm.c', + 'third_party/boringssl/crypto/x509/x509cset.c', + 'third_party/boringssl/crypto/x509/x509name.c', + 'third_party/boringssl/crypto/x509/x509rset.c', + 'third_party/boringssl/crypto/x509/x509spki.c', + 'third_party/boringssl/crypto/x509/x509type.c', + 'third_party/boringssl/crypto/x509/x_algor.c', + 'third_party/boringssl/crypto/x509/x_all.c', + 'third_party/boringssl/crypto/x509/x_attrib.c', + 'third_party/boringssl/crypto/x509/x_crl.c', + 'third_party/boringssl/crypto/x509/x_exten.c', + 'third_party/boringssl/crypto/x509/x_info.c', + 'third_party/boringssl/crypto/x509/x_name.c', + 'third_party/boringssl/crypto/x509/x_pkey.c', + 'third_party/boringssl/crypto/x509/x_pubkey.c', + 'third_party/boringssl/crypto/x509/x_req.c', + 'third_party/boringssl/crypto/x509/x_sig.c', + 'third_party/boringssl/crypto/x509/x_spki.c', + 'third_party/boringssl/crypto/x509/x_val.c', + 'third_party/boringssl/crypto/x509/x_x509.c', + 'third_party/boringssl/crypto/x509/x_x509a.c', + 'third_party/boringssl/crypto/x509v3/pcy_cache.c', + 'third_party/boringssl/crypto/x509v3/pcy_data.c', + 'third_party/boringssl/crypto/x509v3/pcy_lib.c', + 'third_party/boringssl/crypto/x509v3/pcy_map.c', + 'third_party/boringssl/crypto/x509v3/pcy_node.c', + 'third_party/boringssl/crypto/x509v3/pcy_tree.c', + 'third_party/boringssl/crypto/x509v3/v3_akey.c', + 'third_party/boringssl/crypto/x509v3/v3_akeya.c', + 'third_party/boringssl/crypto/x509v3/v3_alt.c', + 'third_party/boringssl/crypto/x509v3/v3_bcons.c', + 'third_party/boringssl/crypto/x509v3/v3_bitst.c', + 'third_party/boringssl/crypto/x509v3/v3_conf.c', + 'third_party/boringssl/crypto/x509v3/v3_cpols.c', + 'third_party/boringssl/crypto/x509v3/v3_crld.c', + 'third_party/boringssl/crypto/x509v3/v3_enum.c', + 'third_party/boringssl/crypto/x509v3/v3_extku.c', + 'third_party/boringssl/crypto/x509v3/v3_genn.c', + 'third_party/boringssl/crypto/x509v3/v3_ia5.c', + 'third_party/boringssl/crypto/x509v3/v3_info.c', + 'third_party/boringssl/crypto/x509v3/v3_int.c', + 'third_party/boringssl/crypto/x509v3/v3_lib.c', + 'third_party/boringssl/crypto/x509v3/v3_ncons.c', + 'third_party/boringssl/crypto/x509v3/v3_pci.c', + 'third_party/boringssl/crypto/x509v3/v3_pcia.c', + 'third_party/boringssl/crypto/x509v3/v3_pcons.c', + 'third_party/boringssl/crypto/x509v3/v3_pku.c', + 'third_party/boringssl/crypto/x509v3/v3_pmaps.c', + 'third_party/boringssl/crypto/x509v3/v3_prn.c', + 'third_party/boringssl/crypto/x509v3/v3_purp.c', + 'third_party/boringssl/crypto/x509v3/v3_skey.c', + 'third_party/boringssl/crypto/x509v3/v3_sxnet.c', + 'third_party/boringssl/crypto/x509v3/v3_utl.c', + 'third_party/boringssl/ssl/bio_ssl.c', + 'third_party/boringssl/ssl/custom_extensions.c', + 'third_party/boringssl/ssl/d1_both.c', + 'third_party/boringssl/ssl/d1_lib.c', + 'third_party/boringssl/ssl/d1_pkt.c', + 'third_party/boringssl/ssl/d1_srtp.c', + 'third_party/boringssl/ssl/dtls_method.c', + 'third_party/boringssl/ssl/dtls_record.c', + 'third_party/boringssl/ssl/handshake_client.c', + 'third_party/boringssl/ssl/handshake_server.c', + 'third_party/boringssl/ssl/s3_both.c', + 'third_party/boringssl/ssl/s3_lib.c', + 'third_party/boringssl/ssl/s3_pkt.c', + 'third_party/boringssl/ssl/ssl_aead_ctx.c', + 'third_party/boringssl/ssl/ssl_asn1.c', + 'third_party/boringssl/ssl/ssl_buffer.c', + 'third_party/boringssl/ssl/ssl_cert.c', + 'third_party/boringssl/ssl/ssl_cipher.c', + 'third_party/boringssl/ssl/ssl_ecdh.c', + 'third_party/boringssl/ssl/ssl_file.c', + 'third_party/boringssl/ssl/ssl_lib.c', + 'third_party/boringssl/ssl/ssl_privkey.c', + 'third_party/boringssl/ssl/ssl_privkey_cc.cc', + 'third_party/boringssl/ssl/ssl_session.c', + 'third_party/boringssl/ssl/ssl_stat.c', + 'third_party/boringssl/ssl/ssl_transcript.c', + 'third_party/boringssl/ssl/ssl_x509.c', + 'third_party/boringssl/ssl/t1_enc.c', + 'third_party/boringssl/ssl/t1_lib.c', + 'third_party/boringssl/ssl/tls13_both.c', + 'third_party/boringssl/ssl/tls13_client.c', + 'third_party/boringssl/ssl/tls13_enc.c', + 'third_party/boringssl/ssl/tls13_server.c', + 'third_party/boringssl/ssl/tls_method.c', + 'third_party/boringssl/ssl/tls_record.c', + 'third_party/zlib/adler32.c', + 'third_party/zlib/compress.c', + 'third_party/zlib/crc32.c', + 'third_party/zlib/deflate.c', + 'third_party/zlib/gzclose.c', + 'third_party/zlib/gzlib.c', + 'third_party/zlib/gzread.c', + 'third_party/zlib/gzwrite.c', + 'third_party/zlib/infback.c', + 'third_party/zlib/inffast.c', + 'third_party/zlib/inflate.c', + 'third_party/zlib/inftrees.c', + 'third_party/zlib/trees.c', + 'third_party/zlib/uncompr.c', + 'third_party/zlib/zutil.c', + 'third_party/cares/cares/ares__close_sockets.c', + 'third_party/cares/cares/ares__get_hostent.c', + 'third_party/cares/cares/ares__read_line.c', + 'third_party/cares/cares/ares__timeval.c', + 'third_party/cares/cares/ares_cancel.c', + 'third_party/cares/cares/ares_create_query.c', + 'third_party/cares/cares/ares_data.c', + 'third_party/cares/cares/ares_destroy.c', + 'third_party/cares/cares/ares_expand_name.c', + 'third_party/cares/cares/ares_expand_string.c', + 'third_party/cares/cares/ares_fds.c', + 'third_party/cares/cares/ares_free_hostent.c', + 'third_party/cares/cares/ares_free_string.c', + 'third_party/cares/cares/ares_getenv.c', + 'third_party/cares/cares/ares_gethostbyaddr.c', + 'third_party/cares/cares/ares_gethostbyname.c', + 'third_party/cares/cares/ares_getnameinfo.c', + 'third_party/cares/cares/ares_getopt.c', + 'third_party/cares/cares/ares_getsock.c', + 'third_party/cares/cares/ares_init.c', + 'third_party/cares/cares/ares_library_init.c', + 'third_party/cares/cares/ares_llist.c', + 'third_party/cares/cares/ares_mkquery.c', + 'third_party/cares/cares/ares_nowarn.c', + 'third_party/cares/cares/ares_options.c', + 'third_party/cares/cares/ares_parse_a_reply.c', + 'third_party/cares/cares/ares_parse_aaaa_reply.c', + 'third_party/cares/cares/ares_parse_mx_reply.c', + 'third_party/cares/cares/ares_parse_naptr_reply.c', + 'third_party/cares/cares/ares_parse_ns_reply.c', + 'third_party/cares/cares/ares_parse_ptr_reply.c', + 'third_party/cares/cares/ares_parse_soa_reply.c', + 'third_party/cares/cares/ares_parse_srv_reply.c', + 'third_party/cares/cares/ares_parse_txt_reply.c', + 'third_party/cares/cares/ares_platform.c', + 'third_party/cares/cares/ares_process.c', + 'third_party/cares/cares/ares_query.c', + 'third_party/cares/cares/ares_search.c', + 'third_party/cares/cares/ares_send.c', + 'third_party/cares/cares/ares_strcasecmp.c', + 'third_party/cares/cares/ares_strdup.c', + 'third_party/cares/cares/ares_strerror.c', + 'third_party/cares/cares/ares_timeout.c', + 'third_party/cares/cares/ares_version.c', + 'third_party/cares/cares/ares_writev.c', + 'third_party/cares/cares/bitncmp.c', + 'third_party/cares/cares/inet_net_pton.c', + 'third_party/cares/cares/inet_ntop.c', + 'third_party/cares/cares/windows_port.c', ] diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 8f07f3b30b..1fac57b03a 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION='1.9.0.dev0' +VERSION = '1.9.0.dev0' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 0987d57261..5b7e5859bc 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION='1.9.0.dev0' +VERSION = '1.9.0.dev0' diff --git a/src/python/grpcio_reflection/grpc_reflection/v1alpha/reflection.py b/src/python/grpcio_reflection/grpc_reflection/v1alpha/reflection.py index c598ea96df..26a7ba8685 100644 --- a/src/python/grpcio_reflection/grpc_reflection/v1alpha/reflection.py +++ b/src/python/grpcio_reflection/grpc_reflection/v1alpha/reflection.py @@ -70,7 +70,8 @@ class ReflectionServicer(reflection_pb2_grpc.ServerReflectionServicer): def _file_containing_extension(self, containing_type, extension_number): try: - message_descriptor = self._pool.FindMessageTypeByName(containing_type) + message_descriptor = self._pool.FindMessageTypeByName( + containing_type) extension_descriptor = self._pool.FindExtensionByNumber( message_descriptor, extension_number) descriptor = self._pool.FindFileContainingSymbol( @@ -82,10 +83,13 @@ class ReflectionServicer(reflection_pb2_grpc.ServerReflectionServicer): def _all_extension_numbers_of_type(self, containing_type): try: - message_descriptor = self._pool.FindMessageTypeByName(containing_type) - extension_numbers = tuple(sorted( - extension.number - for extension in self._pool.FindAllExtensions(message_descriptor))) + message_descriptor = self._pool.FindMessageTypeByName( + containing_type) + extension_numbers = tuple( + sorted( + extension.number + for extension in self._pool.FindAllExtensions( + message_descriptor))) except KeyError: return _not_found_error() else: diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 95d2ff143a..0ad9621154 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION='1.9.0.dev0' +VERSION = '1.9.0.dev0' diff --git a/src/python/grpcio_testing/grpc_testing/__init__.py b/src/python/grpcio_testing/grpc_testing/__init__.py index 994274500c..e87d0ffc96 100644 --- a/src/python/grpcio_testing/grpc_testing/__init__.py +++ b/src/python/grpcio_testing/grpc_testing/__init__.py @@ -495,8 +495,8 @@ class Server(six.with_metaclass(abc.ABCMeta)): """A server with which to test a system that services RPCs.""" @abc.abstractmethod - def invoke_unary_unary( - self, method_descriptor, invocation_metadata, request, timeout): + def invoke_unary_unary(self, method_descriptor, invocation_metadata, + request, timeout): """Invokes an RPC to be serviced by the system under test. Args: @@ -513,8 +513,8 @@ class Server(six.with_metaclass(abc.ABCMeta)): raise NotImplementedError() @abc.abstractmethod - def invoke_unary_stream( - self, method_descriptor, invocation_metadata, request, timeout): + def invoke_unary_stream(self, method_descriptor, invocation_metadata, + request, timeout): """Invokes an RPC to be serviced by the system under test. Args: @@ -531,8 +531,8 @@ class Server(six.with_metaclass(abc.ABCMeta)): raise NotImplementedError() @abc.abstractmethod - def invoke_stream_unary( - self, method_descriptor, invocation_metadata, timeout): + def invoke_stream_unary(self, method_descriptor, invocation_metadata, + timeout): """Invokes an RPC to be serviced by the system under test. Args: @@ -548,8 +548,8 @@ class Server(six.with_metaclass(abc.ABCMeta)): raise NotImplementedError() @abc.abstractmethod - def invoke_stream_stream( - self, method_descriptor, invocation_metadata, timeout): + def invoke_stream_stream(self, method_descriptor, invocation_metadata, + timeout): """Invokes an RPC to be serviced by the system under test. Args: diff --git a/src/python/grpcio_testing/grpc_testing/_channel/__init__.py b/src/python/grpcio_testing/grpc_testing/_channel/__init__.py index 8011975d0a..7a64cda889 100644 --- a/src/python/grpcio_testing/grpc_testing/_channel/__init__.py +++ b/src/python/grpcio_testing/grpc_testing/_channel/__init__.py @@ -20,4 +20,6 @@ from grpc_testing._channel import _channel_state # pylint: disable=unused-argument def testing_channel(descriptors, time): return _channel.TestingChannel(time, _channel_state.State()) + + # pylint: enable=unused-argument diff --git a/src/python/grpcio_testing/grpc_testing/_channel/_channel.py b/src/python/grpcio_testing/grpc_testing/_channel/_channel.py index fbd064db88..b015b8d738 100644 --- a/src/python/grpcio_testing/grpc_testing/_channel/_channel.py +++ b/src/python/grpcio_testing/grpc_testing/_channel/_channel.py @@ -32,20 +32,28 @@ class TestingChannel(grpc_testing.Channel): def unsubscribe(self, callback): raise NotImplementedError() - def unary_unary( - self, method, request_serializer=None, response_deserializer=None): + def unary_unary(self, + method, + request_serializer=None, + response_deserializer=None): return _multi_callable.UnaryUnary(method, self._state) - def unary_stream( - self, method, request_serializer=None, response_deserializer=None): + def unary_stream(self, + method, + request_serializer=None, + response_deserializer=None): return _multi_callable.UnaryStream(method, self._state) - def stream_unary( - self, method, request_serializer=None, response_deserializer=None): + def stream_unary(self, + method, + request_serializer=None, + response_deserializer=None): return _multi_callable.StreamUnary(method, self._state) - def stream_stream( - self, method, request_serializer=None, response_deserializer=None): + def stream_stream(self, + method, + request_serializer=None, + response_deserializer=None): return _multi_callable.StreamStream(method, self._state) def take_unary_unary(self, method_descriptor): @@ -59,4 +67,6 @@ class TestingChannel(grpc_testing.Channel): def take_stream_stream(self, method_descriptor): return _channel_rpc.stream_stream(self._state, method_descriptor) + + # pylint: enable=unused-argument diff --git a/src/python/grpcio_testing/grpc_testing/_channel/_channel_rpc.py b/src/python/grpcio_testing/grpc_testing/_channel/_channel_rpc.py index 762b6a035b..54499b3b55 100644 --- a/src/python/grpcio_testing/grpc_testing/_channel/_channel_rpc.py +++ b/src/python/grpcio_testing/grpc_testing/_channel/_channel_rpc.py @@ -27,8 +27,8 @@ class _UnaryUnary(grpc_testing.UnaryUnaryChannelRpc): self._rpc_state.cancelled() def terminate(self, response, trailing_metadata, code, details): - self._rpc_state.terminate_with_response( - response, trailing_metadata, code, details) + self._rpc_state.terminate_with_response(response, trailing_metadata, + code, details) class _UnaryStream(grpc_testing.UnaryStreamChannelRpc): @@ -67,8 +67,8 @@ class _StreamUnary(grpc_testing.StreamUnaryChannelRpc): self._rpc_state.cancelled() def terminate(self, response, trailing_metadata, code, details): - self._rpc_state.terminate_with_response( - response, trailing_metadata, code, details) + self._rpc_state.terminate_with_response(response, trailing_metadata, + code, details) class _StreamStream(grpc_testing.StreamStreamChannelRpc): diff --git a/src/python/grpcio_testing/grpc_testing/_channel/_channel_state.py b/src/python/grpcio_testing/grpc_testing/_channel/_channel_state.py index 569c41d79d..779d59e59a 100644 --- a/src/python/grpcio_testing/grpc_testing/_channel/_channel_state.py +++ b/src/python/grpcio_testing/grpc_testing/_channel/_channel_state.py @@ -25,11 +25,10 @@ class State(_common.ChannelHandler): self._condition = threading.Condition() self._rpc_states = collections.defaultdict(list) - def invoke_rpc( - self, method_full_rpc_name, invocation_metadata, requests, - requests_closed, timeout): - rpc_state = _rpc_state.State( - invocation_metadata, requests, requests_closed) + def invoke_rpc(self, method_full_rpc_name, invocation_metadata, requests, + requests_closed, timeout): + rpc_state = _rpc_state.State(invocation_metadata, requests, + requests_closed) with self._condition: self._rpc_states[method_full_rpc_name].append(rpc_state) self._condition.notify_all() diff --git a/src/python/grpcio_testing/grpc_testing/_channel/_multi_callable.py b/src/python/grpcio_testing/grpc_testing/_channel/_multi_callable.py index fe69257f5b..32b2f361d3 100644 --- a/src/python/grpcio_testing/grpc_testing/_channel/_multi_callable.py +++ b/src/python/grpcio_testing/grpc_testing/_channel/_multi_callable.py @@ -16,6 +16,7 @@ import grpc from grpc_testing import _common from grpc_testing._channel import _invocation + # All per-call credentials parameters are unused by this test infrastructure. # pylint: disable=unused-argument class UnaryUnary(grpc.UnaryUnaryMultiCallable): @@ -26,20 +27,20 @@ class UnaryUnary(grpc.UnaryUnaryMultiCallable): def __call__(self, request, timeout=None, metadata=None, credentials=None): rpc_handler = self._channel_handler.invoke_rpc( - self._method_full_rpc_name, _common.fuss_with_metadata(metadata), - [request], True, timeout) + self._method_full_rpc_name, + _common.fuss_with_metadata(metadata), [request], True, timeout) return _invocation.blocking_unary_response(rpc_handler) def with_call(self, request, timeout=None, metadata=None, credentials=None): rpc_handler = self._channel_handler.invoke_rpc( - self._method_full_rpc_name, _common.fuss_with_metadata(metadata), - [request], True, timeout) + self._method_full_rpc_name, + _common.fuss_with_metadata(metadata), [request], True, timeout) return _invocation.blocking_unary_response_with_call(rpc_handler) def future(self, request, timeout=None, metadata=None, credentials=None): rpc_handler = self._channel_handler.invoke_rpc( - self._method_full_rpc_name, _common.fuss_with_metadata(metadata), - [request], True, timeout) + self._method_full_rpc_name, + _common.fuss_with_metadata(metadata), [request], True, timeout) return _invocation.future_call(rpc_handler) @@ -112,4 +113,6 @@ class StreamStream(grpc.StreamStreamMultiCallable): _common.fuss_with_metadata(metadata), [], False, timeout) _invocation.consume_requests(request_iterator, rpc_handler) return _invocation.ResponseIteratorCall(rpc_handler) + + # pylint: enable=unused-argument diff --git a/src/python/grpcio_testing/grpc_testing/_channel/_rpc_state.py b/src/python/grpcio_testing/grpc_testing/_channel/_rpc_state.py index e1fa49a2a8..ee0233002d 100644 --- a/src/python/grpcio_testing/grpc_testing/_channel/_rpc_state.py +++ b/src/python/grpcio_testing/grpc_testing/_channel/_rpc_state.py @@ -63,23 +63,22 @@ class State(_common.ChannelRpcHandler): if self._code is grpc.StatusCode.OK: if self._responses: response = self._responses.pop(0) - return _common.ChannelRpcRead( - response, None, None, None) + return _common.ChannelRpcRead(response, None, None, + None) else: return _common.ChannelRpcRead( - None, self._trailing_metadata, - grpc.StatusCode.OK, self._details) + None, self._trailing_metadata, grpc.StatusCode.OK, + self._details) elif self._code is None: if self._responses: response = self._responses.pop(0) - return _common.ChannelRpcRead( - response, None, None, None) + return _common.ChannelRpcRead(response, None, None, + None) else: self._condition.wait() else: - return _common.ChannelRpcRead( - None, self._trailing_metadata, self._code, - self._details) + return _common.ChannelRpcRead(None, self._trailing_metadata, + self._code, self._details) def termination(self): with self._condition: @@ -150,8 +149,8 @@ class State(_common.ChannelRpcHandler): self._responses.append(response) self._condition.notify_all() - def terminate_with_response( - self, response, trailing_metadata, code, details): + def terminate_with_response(self, response, trailing_metadata, code, + details): with self._condition: if self._initial_metadata is None: self._initial_metadata = _common.FUSSED_EMPTY_METADATA diff --git a/src/python/grpcio_testing/grpc_testing/_common.py b/src/python/grpcio_testing/grpc_testing/_common.py index 1517434ca7..05327b0ac2 100644 --- a/src/python/grpcio_testing/grpc_testing/_common.py +++ b/src/python/grpcio_testing/grpc_testing/_common.py @@ -21,11 +21,9 @@ import six def _fuss(tuplified_metadata): return tuplified_metadata + ( - ( - 'grpc.metadata_added_by_runtime', - 'gRPC is allowed to add metadata in transmission and does so.', - ), - ) + ('grpc.metadata_added_by_runtime', + 'gRPC is allowed to add metadata in transmission and does so.',),) + FUSSED_EMPTY_METADATA = _fuss(()) @@ -41,8 +39,8 @@ def rpc_names(service_descriptors): rpc_names_to_descriptors = {} for service_descriptor in service_descriptors: for method_descriptor in service_descriptor.methods_by_name.values(): - rpc_name = '/{}/{}'.format( - service_descriptor.full_name, method_descriptor.name) + rpc_name = '/{}/{}'.format(service_descriptor.full_name, + method_descriptor.name) rpc_names_to_descriptors[rpc_name] = method_descriptor return rpc_names_to_descriptors @@ -96,9 +94,8 @@ class ChannelRpcHandler(six.with_metaclass(abc.ABCMeta)): class ChannelHandler(six.with_metaclass(abc.ABCMeta)): @abc.abstractmethod - def invoke_rpc( - self, method_full_rpc_name, invocation_metadata, requests, - requests_closed, timeout): + def invoke_rpc(self, method_full_rpc_name, invocation_metadata, requests, + requests_closed, timeout): raise NotImplementedError() @@ -138,23 +135,21 @@ class ServerRpcHandler(six.with_metaclass(abc.ABCMeta)): class Serverish(six.with_metaclass(abc.ABCMeta)): @abc.abstractmethod - def invoke_unary_unary( - self, method_descriptor, handler, invocation_metadata, request, - deadline): + def invoke_unary_unary(self, method_descriptor, handler, + invocation_metadata, request, deadline): raise NotImplementedError() @abc.abstractmethod - def invoke_unary_stream( - self, method_descriptor, handler, invocation_metadata, request, - deadline): + def invoke_unary_stream(self, method_descriptor, handler, + invocation_metadata, request, deadline): raise NotImplementedError() @abc.abstractmethod - def invoke_stream_unary( - self, method_descriptor, handler, invocation_metadata, deadline): + def invoke_stream_unary(self, method_descriptor, handler, + invocation_metadata, deadline): raise NotImplementedError() @abc.abstractmethod - def invoke_stream_stream( - self, method_descriptor, handler, invocation_metadata, deadline): + def invoke_stream_stream(self, method_descriptor, handler, + invocation_metadata, deadline): raise NotImplementedError() diff --git a/src/python/grpcio_testing/grpc_testing/_server/__init__.py b/src/python/grpcio_testing/grpc_testing/_server/__init__.py index 759512949a..5f035a91ca 100644 --- a/src/python/grpcio_testing/grpc_testing/_server/__init__.py +++ b/src/python/grpcio_testing/grpc_testing/_server/__init__.py @@ -16,5 +16,5 @@ from grpc_testing._server import _server def server_from_dictionary(descriptors_to_servicers, time): - return _server.server_from_descriptor_to_servicers( - descriptors_to_servicers, time) + return _server.server_from_descriptor_to_servicers(descriptors_to_servicers, + time) diff --git a/src/python/grpcio_testing/grpc_testing/_server/_handler.py b/src/python/grpcio_testing/grpc_testing/_server/_handler.py index b47e04c718..5e4730e087 100644 --- a/src/python/grpcio_testing/grpc_testing/_server/_handler.py +++ b/src/python/grpcio_testing/grpc_testing/_server/_handler.py @@ -170,10 +170,8 @@ class _Handler(Handler): if self._unary_response is None: if self._responses: self._unary_response = self._responses.pop(0) - return ( - self._unary_response, self._trailing_metadata, - self._code, self._details,) - + return (self._unary_response, self._trailing_metadata, + self._code, self._details,) def stream_response_termination(self): with self._condition: diff --git a/src/python/grpcio_testing/grpc_testing/_server/_rpc.py b/src/python/grpcio_testing/grpc_testing/_server/_rpc.py index f81876f4b2..2060e8daff 100644 --- a/src/python/grpcio_testing/grpc_testing/_server/_rpc.py +++ b/src/python/grpcio_testing/grpc_testing/_server/_rpc.py @@ -80,9 +80,8 @@ class Rpc(object): def application_cancel(self): with self._condition: - self._abort( - grpc.StatusCode.CANCELLED, - 'Cancelled by server-side application!') + self._abort(grpc.StatusCode.CANCELLED, + 'Cancelled by server-side application!') def application_exception_abort(self, exception): with self._condition: diff --git a/src/python/grpcio_testing/grpc_testing/_server/_server.py b/src/python/grpcio_testing/grpc_testing/_server/_server.py index 66bcfc13c0..3e358e50a9 100644 --- a/src/python/grpcio_testing/grpc_testing/_server/_server.py +++ b/src/python/grpcio_testing/grpc_testing/_server/_server.py @@ -29,28 +29,34 @@ def _implementation(descriptors_to_servicers, method_descriptor): def _unary_unary_service(request): + def service(implementation, rpc, servicer_context): - _service.unary_unary( - implementation, rpc, request, servicer_context) + _service.unary_unary(implementation, rpc, request, servicer_context) + return service def _unary_stream_service(request): + def service(implementation, rpc, servicer_context): - _service.unary_stream( - implementation, rpc, request, servicer_context) + _service.unary_stream(implementation, rpc, request, servicer_context) + return service def _stream_unary_service(handler): + def service(implementation, rpc, servicer_context): _service.stream_unary(implementation, rpc, handler, servicer_context) + return service def _stream_stream_service(handler): + def service(implementation, rpc, servicer_context): _service.stream_stream(implementation, rpc, handler, servicer_context) + return service @@ -60,11 +66,10 @@ class _Serverish(_common.Serverish): self._descriptors_to_servicers = descriptors_to_servicers self._time = time - def _invoke( - self, service_behavior, method_descriptor, handler, - invocation_metadata, deadline): - implementation = _implementation( - self._descriptors_to_servicers, method_descriptor) + def _invoke(self, service_behavior, method_descriptor, handler, + invocation_metadata, deadline): + implementation = _implementation(self._descriptors_to_servicers, + method_descriptor) rpc = _rpc.Rpc(handler, invocation_metadata) if handler.add_termination_callback(rpc.extrinsic_abort): servicer_context = _servicer_context.ServicerContext( @@ -74,28 +79,26 @@ class _Serverish(_common.Serverish): args=(implementation, rpc, servicer_context,)) service_thread.start() - def invoke_unary_unary( - self, method_descriptor, handler, invocation_metadata, request, - deadline): + def invoke_unary_unary(self, method_descriptor, handler, + invocation_metadata, request, deadline): self._invoke( _unary_unary_service(request), method_descriptor, handler, invocation_metadata, deadline) - def invoke_unary_stream( - self, method_descriptor, handler, invocation_metadata, request, - deadline): + def invoke_unary_stream(self, method_descriptor, handler, + invocation_metadata, request, deadline): self._invoke( _unary_stream_service(request), method_descriptor, handler, invocation_metadata, deadline) - def invoke_stream_unary( - self, method_descriptor, handler, invocation_metadata, deadline): + def invoke_stream_unary(self, method_descriptor, handler, + invocation_metadata, deadline): self._invoke( _stream_unary_service(handler), method_descriptor, handler, invocation_metadata, deadline) - def invoke_stream_stream( - self, method_descriptor, handler, invocation_metadata, deadline): + def invoke_stream_stream(self, method_descriptor, handler, + invocation_metadata, deadline): self._invoke( _stream_stream_service(handler), method_descriptor, handler, invocation_metadata, deadline) @@ -106,7 +109,8 @@ def _deadline_and_handler(requests_closed, time, timeout): return None, _handler.handler_without_deadline(requests_closed) else: deadline = time.time() + timeout - handler = _handler.handler_with_deadline(requests_closed, time, deadline) + handler = _handler.handler_with_deadline(requests_closed, time, + deadline) return deadline, handler @@ -116,32 +120,32 @@ class _Server(grpc_testing.Server): self._serverish = serverish self._time = time - def invoke_unary_unary( - self, method_descriptor, invocation_metadata, request, timeout): + def invoke_unary_unary(self, method_descriptor, invocation_metadata, + request, timeout): deadline, handler = _deadline_and_handler(True, self._time, timeout) self._serverish.invoke_unary_unary( method_descriptor, handler, invocation_metadata, request, deadline) return _server_rpc.UnaryUnaryServerRpc(handler) - def invoke_unary_stream( - self, method_descriptor, invocation_metadata, request, timeout): + def invoke_unary_stream(self, method_descriptor, invocation_metadata, + request, timeout): deadline, handler = _deadline_and_handler(True, self._time, timeout) self._serverish.invoke_unary_stream( method_descriptor, handler, invocation_metadata, request, deadline) return _server_rpc.UnaryStreamServerRpc(handler) - def invoke_stream_unary( - self, method_descriptor, invocation_metadata, timeout): + def invoke_stream_unary(self, method_descriptor, invocation_metadata, + timeout): deadline, handler = _deadline_and_handler(False, self._time, timeout) - self._serverish.invoke_stream_unary( - method_descriptor, handler, invocation_metadata, deadline) + self._serverish.invoke_stream_unary(method_descriptor, handler, + invocation_metadata, deadline) return _server_rpc.StreamUnaryServerRpc(handler) - def invoke_stream_stream( - self, method_descriptor, invocation_metadata, timeout): + def invoke_stream_stream(self, method_descriptor, invocation_metadata, + timeout): deadline, handler = _deadline_and_handler(False, self._time, timeout) - self._serverish.invoke_stream_stream( - method_descriptor, handler, invocation_metadata, deadline) + self._serverish.invoke_stream_stream(method_descriptor, handler, + invocation_metadata, deadline) return _server_rpc.StreamStreamServerRpc(handler) diff --git a/src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py b/src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py index 496689ded0..90eeb130d3 100644 --- a/src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py +++ b/src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py @@ -67,6 +67,9 @@ class ServicerContext(grpc.ServicerContext): self._rpc.set_trailing_metadata( _common.fuss_with_metadata(trailing_metadata)) + def abort(self, code, details): + raise NotImplementedError() + def set_code(self, code): self._rpc.set_code(code) diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index afc6dd83f2..0eb5fbf94d 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION='1.9.0.dev0' +VERSION = '1.9.0.dev0' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 99ca3fd82d..b1b4d7e0c2 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION='1.9.0.dev0' +VERSION = '1.9.0.dev0' diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json index 34cbade92c..3bf5308749 100644 --- a/src/python/grpcio_tests/tests/tests.json +++ b/src/python/grpcio_tests/tests/tests.json @@ -39,6 +39,7 @@ "unit._cython.cygrpc_test.TypeSmokeTest", "unit._empty_message_test.EmptyMessageTest", "unit._exit_test.ExitTest", + "unit._interceptor_test.InterceptorTest", "unit._invalid_metadata_test.InvalidMetadataTest", "unit._invocation_defects_test.InvocationDefectsTest", "unit._metadata_code_details_test.MetadataCodeDetailsTest", diff --git a/src/python/grpcio_tests/tests/unit/_api_test.py b/src/python/grpcio_tests/tests/unit/_api_test.py index b14e8d5c75..d6f4447532 100644 --- a/src/python/grpcio_tests/tests/unit/_api_test.py +++ b/src/python/grpcio_tests/tests/unit/_api_test.py @@ -33,18 +33,21 @@ class AllTest(unittest.TestCase): 'AuthMetadataPlugin', 'ServerCertificateConfiguration', 'ServerCredentials', 'UnaryUnaryMultiCallable', 'UnaryStreamMultiCallable', 'StreamUnaryMultiCallable', - 'StreamStreamMultiCallable', 'Channel', 'ServicerContext', + 'StreamStreamMultiCallable', 'UnaryUnaryClientInterceptor', + 'UnaryStreamClientInterceptor', 'StreamUnaryClientInterceptor', + 'StreamStreamClientInterceptor', 'Channel', 'ServicerContext', 'RpcMethodHandler', 'HandlerCallDetails', 'GenericRpcHandler', - 'ServiceRpcHandler', 'Server', 'unary_unary_rpc_method_handler', - 'unary_stream_rpc_method_handler', - 'stream_unary_rpc_method_handler', + 'ServiceRpcHandler', 'Server', 'ServerInterceptor', + 'unary_unary_rpc_method_handler', 'unary_stream_rpc_method_handler', + 'stream_unary_rpc_method_handler', 'ClientCallDetails', 'stream_stream_rpc_method_handler', 'method_handlers_generic_handler', 'ssl_channel_credentials', 'metadata_call_credentials', 'access_token_call_credentials', 'composite_call_credentials', 'composite_channel_credentials', 'ssl_server_credentials', 'ssl_server_certificate_configuration', 'dynamic_ssl_server_credentials', 'channel_ready_future', - 'insecure_channel', 'secure_channel', 'server',) + 'insecure_channel', 'secure_channel', 'intercept_channel', + 'server',) six.assertCountEqual(self, expected_grpc_code_elements, _from_grpc_import_star.GRPC_ELEMENTS) diff --git a/src/python/grpcio_tests/tests/unit/_cython/_cancel_many_calls_test.py b/src/python/grpcio_tests/tests/unit/_cython/_cancel_many_calls_test.py index 5b97b7b542..a8a7175cc7 100644 --- a/src/python/grpcio_tests/tests/unit/_cython/_cancel_many_calls_test.py +++ b/src/python/grpcio_tests/tests/unit/_cython/_cancel_many_calls_test.py @@ -22,7 +22,7 @@ from tests.unit.framework.common import test_constants _INFINITE_FUTURE = cygrpc.Timespec(float('+inf')) _EMPTY_FLAGS = 0 -_EMPTY_METADATA = cygrpc.Metadata(()) +_EMPTY_METADATA = () _SERVER_SHUTDOWN_TAG = 'server_shutdown' _REQUEST_CALL_TAG = 'request_call' @@ -65,12 +65,10 @@ class _Handler(object): with self._lock: self._call.start_server_batch( - cygrpc.Operations( - (cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),)), + (cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),), _RECEIVE_CLOSE_ON_SERVER_TAG) self._call.start_server_batch( - cygrpc.Operations( - (cygrpc.operation_receive_message(_EMPTY_FLAGS),)), + (cygrpc.operation_receive_message(_EMPTY_FLAGS),), _RECEIVE_MESSAGE_TAG) first_event = self._completion_queue.poll() if _is_cancellation_event(first_event): @@ -84,8 +82,8 @@ class _Handler(object): cygrpc.operation_send_status_from_server( _EMPTY_METADATA, cygrpc.StatusCode.ok, b'test details!', _EMPTY_FLAGS),) - self._call.start_server_batch( - cygrpc.Operations(operations), _SERVER_COMPLETE_CALL_TAG) + self._call.start_server_batch(operations, + _SERVER_COMPLETE_CALL_TAG) self._completion_queue.poll() self._completion_queue.poll() @@ -179,8 +177,7 @@ class CancelManyCallsTest(unittest.TestCase): cygrpc.operation_receive_message(_EMPTY_FLAGS), cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),) tag = 'client_complete_call_{0:04d}_tag'.format(index) - client_call.start_client_batch( - cygrpc.Operations(operations), tag) + client_call.start_client_batch(operations, tag) client_due.add(tag) client_calls.append(client_call) diff --git a/src/python/grpcio_tests/tests/unit/_cython/_common.py b/src/python/grpcio_tests/tests/unit/_cython/_common.py index ac66d1db3d..96f0f1589b 100644 --- a/src/python/grpcio_tests/tests/unit/_cython/_common.py +++ b/src/python/grpcio_tests/tests/unit/_cython/_common.py @@ -23,17 +23,14 @@ RPC_COUNT = 4000 INFINITE_FUTURE = cygrpc.Timespec(float('+inf')) EMPTY_FLAGS = 0 -INVOCATION_METADATA = cygrpc.Metadata( - (cygrpc.Metadatum(b'client-md-key', b'client-md-key'), - cygrpc.Metadatum(b'client-md-key-bin', b'\x00\x01' * 3000),)) +INVOCATION_METADATA = (('client-md-key', 'client-md-key'), + ('client-md-key-bin', b'\x00\x01' * 3000),) -INITIAL_METADATA = cygrpc.Metadata( - (cygrpc.Metadatum(b'server-initial-md-key', b'server-initial-md-value'), - cygrpc.Metadatum(b'server-initial-md-key-bin', b'\x00\x02' * 3000),)) +INITIAL_METADATA = (('server-initial-md-key', 'server-initial-md-value'), + ('server-initial-md-key-bin', b'\x00\x02' * 3000),) -TRAILING_METADATA = cygrpc.Metadata( - (cygrpc.Metadatum(b'server-trailing-md-key', b'server-trailing-md-value'), - cygrpc.Metadatum(b'server-trailing-md-key-bin', b'\x00\x03' * 3000),)) +TRAILING_METADATA = (('server-trailing-md-key', 'server-trailing-md-value'), + ('server-trailing-md-key-bin', b'\x00\x03' * 3000),) class QueueDriver(object): diff --git a/src/python/grpcio_tests/tests/unit/_cython/_no_messages_server_completion_queue_per_call_test.py b/src/python/grpcio_tests/tests/unit/_cython/_no_messages_server_completion_queue_per_call_test.py index 14cc66675c..d08003af44 100644 --- a/src/python/grpcio_tests/tests/unit/_cython/_no_messages_server_completion_queue_per_call_test.py +++ b/src/python/grpcio_tests/tests/unit/_cython/_no_messages_server_completion_queue_per_call_test.py @@ -48,20 +48,19 @@ class Test(_common.RpcTest, unittest.TestCase): client_complete_rpc_tag = 'client_complete_rpc_tag' with self.client_condition: client_receive_initial_metadata_start_batch_result = ( - client_call.start_client_batch( - cygrpc.Operations([ - cygrpc.operation_receive_initial_metadata( - _common.EMPTY_FLAGS), - ]), client_receive_initial_metadata_tag)) + client_call.start_client_batch([ + cygrpc.operation_receive_initial_metadata( + _common.EMPTY_FLAGS), + ], client_receive_initial_metadata_tag)) client_complete_rpc_start_batch_result = client_call.start_client_batch( - cygrpc.Operations([ + [ cygrpc.operation_send_initial_metadata( _common.INVOCATION_METADATA, _common.EMPTY_FLAGS), cygrpc.operation_send_close_from_client( _common.EMPTY_FLAGS), cygrpc.operation_receive_status_on_client( _common.EMPTY_FLAGS), - ]), client_complete_rpc_tag) + ], client_complete_rpc_tag) self.client_driver.add_due({ client_receive_initial_metadata_tag, client_complete_rpc_tag, diff --git a/src/python/grpcio_tests/tests/unit/_cython/_no_messages_single_server_completion_queue_test.py b/src/python/grpcio_tests/tests/unit/_cython/_no_messages_single_server_completion_queue_test.py index 1e44bcc4dc..d0166a2b29 100644 --- a/src/python/grpcio_tests/tests/unit/_cython/_no_messages_single_server_completion_queue_test.py +++ b/src/python/grpcio_tests/tests/unit/_cython/_no_messages_single_server_completion_queue_test.py @@ -43,20 +43,19 @@ class Test(_common.RpcTest, unittest.TestCase): client_complete_rpc_tag = 'client_complete_rpc_tag' with self.client_condition: client_receive_initial_metadata_start_batch_result = ( - client_call.start_client_batch( - cygrpc.Operations([ - cygrpc.operation_receive_initial_metadata( - _common.EMPTY_FLAGS), - ]), client_receive_initial_metadata_tag)) + client_call.start_client_batch([ + cygrpc.operation_receive_initial_metadata( + _common.EMPTY_FLAGS), + ], client_receive_initial_metadata_tag)) client_complete_rpc_start_batch_result = client_call.start_client_batch( - cygrpc.Operations([ + [ cygrpc.operation_send_initial_metadata( _common.INVOCATION_METADATA, _common.EMPTY_FLAGS), cygrpc.operation_send_close_from_client( _common.EMPTY_FLAGS), cygrpc.operation_receive_status_on_client( _common.EMPTY_FLAGS), - ]), client_complete_rpc_tag) + ], client_complete_rpc_tag) self.client_driver.add_due({ client_receive_initial_metadata_tag, client_complete_rpc_tag, diff --git a/src/python/grpcio_tests/tests/unit/_cython/_read_some_but_not_all_responses_test.py b/src/python/grpcio_tests/tests/unit/_cython/_read_some_but_not_all_responses_test.py index 0105612b47..1deb15ba03 100644 --- a/src/python/grpcio_tests/tests/unit/_cython/_read_some_but_not_all_responses_test.py +++ b/src/python/grpcio_tests/tests/unit/_cython/_read_some_but_not_all_responses_test.py @@ -20,7 +20,7 @@ from grpc._cython import cygrpc _INFINITE_FUTURE = cygrpc.Timespec(float('+inf')) _EMPTY_FLAGS = 0 -_EMPTY_METADATA = cygrpc.Metadata(()) +_EMPTY_METADATA = () class _ServerDriver(object): @@ -157,19 +157,17 @@ class ReadSomeButNotAllResponsesTest(unittest.TestCase): client_complete_rpc_tag = 'client_complete_rpc_tag' with client_condition: client_receive_initial_metadata_start_batch_result = ( - client_call.start_client_batch( - cygrpc.Operations([ - cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS), - ]), client_receive_initial_metadata_tag)) + client_call.start_client_batch([ + cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS), + ], client_receive_initial_metadata_tag)) client_due.add(client_receive_initial_metadata_tag) client_complete_rpc_start_batch_result = ( - client_call.start_client_batch( - cygrpc.Operations([ - cygrpc.operation_send_initial_metadata(_EMPTY_METADATA, - _EMPTY_FLAGS), - cygrpc.operation_send_close_from_client(_EMPTY_FLAGS), - cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS), - ]), client_complete_rpc_tag)) + client_call.start_client_batch([ + cygrpc.operation_send_initial_metadata(_EMPTY_METADATA, + _EMPTY_FLAGS), + cygrpc.operation_send_close_from_client(_EMPTY_FLAGS), + cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS), + ], client_complete_rpc_tag)) client_due.add(client_complete_rpc_tag) server_rpc_event = server_driver.first_event() @@ -197,8 +195,8 @@ class ReadSomeButNotAllResponsesTest(unittest.TestCase): server_rpc_event.operation_call.start_server_batch([ cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS), cygrpc.operation_send_status_from_server( - cygrpc.Metadata(()), cygrpc.StatusCode.ok, - b'test details', _EMPTY_FLAGS), + (), cygrpc.StatusCode.ok, b'test details', + _EMPTY_FLAGS), ], server_complete_rpc_tag)) server_send_second_message_event = server_call_driver.event_with_tag( server_send_second_message_tag) @@ -209,10 +207,9 @@ class ReadSomeButNotAllResponsesTest(unittest.TestCase): with client_condition: client_receive_first_message_tag = 'client_receive_first_message_tag' client_receive_first_message_start_batch_result = ( - client_call.start_client_batch( - cygrpc.Operations([ - cygrpc.operation_receive_message(_EMPTY_FLAGS), - ]), client_receive_first_message_tag)) + client_call.start_client_batch([ + cygrpc.operation_receive_message(_EMPTY_FLAGS), + ], client_receive_first_message_tag)) client_due.add(client_receive_first_message_tag) client_receive_first_message_event = client_driver.event_with_tag( client_receive_first_message_tag) diff --git a/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py b/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py index da94cf8028..4eda685486 100644 --- a/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py +++ b/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py @@ -29,50 +29,12 @@ _EMPTY_FLAGS = 0 def _metadata_plugin(context, callback): - callback( - cygrpc.Metadata([ - cygrpc.Metadatum(_CALL_CREDENTIALS_METADATA_KEY, - _CALL_CREDENTIALS_METADATA_VALUE) - ]), cygrpc.StatusCode.ok, b'') + callback(((_CALL_CREDENTIALS_METADATA_KEY, + _CALL_CREDENTIALS_METADATA_VALUE,),), cygrpc.StatusCode.ok, b'') class TypeSmokeTest(unittest.TestCase): - def testStringsInUtilitiesUpDown(self): - self.assertEqual(0, cygrpc.StatusCode.ok) - metadatum = cygrpc.Metadatum(b'a', b'b') - self.assertEqual(b'a', metadatum.key) - self.assertEqual(b'b', metadatum.value) - metadata = cygrpc.Metadata([metadatum]) - self.assertEqual(1, len(metadata)) - self.assertEqual(metadatum.key, metadata[0].key) - - def testMetadataIteration(self): - metadata = cygrpc.Metadata( - [cygrpc.Metadatum(b'a', b'b'), cygrpc.Metadatum(b'c', b'd')]) - iterator = iter(metadata) - metadatum = next(iterator) - self.assertIsInstance(metadatum, cygrpc.Metadatum) - self.assertEqual(metadatum.key, b'a') - self.assertEqual(metadatum.value, b'b') - metadatum = next(iterator) - self.assertIsInstance(metadatum, cygrpc.Metadatum) - self.assertEqual(metadatum.key, b'c') - self.assertEqual(metadatum.value, b'd') - with self.assertRaises(StopIteration): - next(iterator) - - def testOperationsIteration(self): - operations = cygrpc.Operations( - [cygrpc.operation_send_message(b'asdf', _EMPTY_FLAGS)]) - iterator = iter(operations) - operation = next(iterator) - self.assertIsInstance(operation, cygrpc.Operation) - # `Operation`s are write-only structures; can't directly debug anything out - # of them. Just check that we stop iterating. - with self.assertRaises(StopIteration): - next(iterator) - def testOperationFlags(self): operation = cygrpc.operation_send_message(b'asdf', cygrpc.WriteFlag.no_compress) @@ -182,8 +144,7 @@ class ServerClientMixin(object): def performer(): tag = object() try: - call_result = call.start_client_batch( - cygrpc.Operations(operations), tag) + call_result = call.start_client_batch(operations, tag) self.assertEqual(cygrpc.CallError.ok, call_result) event = queue.poll(deadline) self.assertEqual(cygrpc.CompletionType.operation_complete, @@ -200,14 +161,14 @@ class ServerClientMixin(object): def test_echo(self): DEADLINE = time.time() + 5 DEADLINE_TOLERANCE = 0.25 - CLIENT_METADATA_ASCII_KEY = b'key' - CLIENT_METADATA_ASCII_VALUE = b'val' - CLIENT_METADATA_BIN_KEY = b'key-bin' + CLIENT_METADATA_ASCII_KEY = 'key' + CLIENT_METADATA_ASCII_VALUE = 'val' + CLIENT_METADATA_BIN_KEY = 'key-bin' CLIENT_METADATA_BIN_VALUE = b'\0' * 1000 - SERVER_INITIAL_METADATA_KEY = b'init_me_me_me' - SERVER_INITIAL_METADATA_VALUE = b'whodawha?' - SERVER_TRAILING_METADATA_KEY = b'california_is_in_a_drought' - SERVER_TRAILING_METADATA_VALUE = b'zomg it is' + SERVER_INITIAL_METADATA_KEY = 'init_me_me_me' + SERVER_INITIAL_METADATA_VALUE = 'whodawha?' + SERVER_TRAILING_METADATA_KEY = 'california_is_in_a_drought' + SERVER_TRAILING_METADATA_VALUE = 'zomg it is' SERVER_STATUS_CODE = cygrpc.StatusCode.ok SERVER_STATUS_DETAILS = b'our work is never over' REQUEST = b'in death a member of project mayhem has a name' @@ -227,11 +188,9 @@ class ServerClientMixin(object): client_call = self.client_channel.create_call( None, 0, self.client_completion_queue, METHOD, self.host_argument, cygrpc_deadline) - client_initial_metadata = cygrpc.Metadata([ - cygrpc.Metadatum(CLIENT_METADATA_ASCII_KEY, - CLIENT_METADATA_ASCII_VALUE), - cygrpc.Metadatum(CLIENT_METADATA_BIN_KEY, CLIENT_METADATA_BIN_VALUE) - ]) + client_initial_metadata = ( + (CLIENT_METADATA_ASCII_KEY, CLIENT_METADATA_ASCII_VALUE,), + (CLIENT_METADATA_BIN_KEY, CLIENT_METADATA_BIN_VALUE,),) client_start_batch_result = client_call.start_client_batch([ cygrpc.operation_send_initial_metadata(client_initial_metadata, _EMPTY_FLAGS), @@ -263,14 +222,10 @@ class ServerClientMixin(object): server_call_tag = object() server_call = request_event.operation_call - server_initial_metadata = cygrpc.Metadata([ - cygrpc.Metadatum(SERVER_INITIAL_METADATA_KEY, - SERVER_INITIAL_METADATA_VALUE) - ]) - server_trailing_metadata = cygrpc.Metadata([ - cygrpc.Metadatum(SERVER_TRAILING_METADATA_KEY, - SERVER_TRAILING_METADATA_VALUE) - ]) + server_initial_metadata = ( + (SERVER_INITIAL_METADATA_KEY, SERVER_INITIAL_METADATA_VALUE,),) + server_trailing_metadata = ( + (SERVER_TRAILING_METADATA_KEY, SERVER_TRAILING_METADATA_VALUE,),) server_start_batch_result = server_call.start_server_batch([ cygrpc.operation_send_initial_metadata( server_initial_metadata, @@ -347,7 +302,7 @@ class ServerClientMixin(object): METHOD = b'twinkies' cygrpc_deadline = cygrpc.Timespec(DEADLINE) - empty_metadata = cygrpc.Metadata([]) + empty_metadata = () server_request_tag = object() self.server.request_call(self.server_completion_queue, diff --git a/src/python/grpcio_tests/tests/unit/_interceptor_test.py b/src/python/grpcio_tests/tests/unit/_interceptor_test.py new file mode 100644 index 0000000000..cf875ed7da --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_interceptor_test.py @@ -0,0 +1,571 @@ +# Copyright 2017 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Test of gRPC Python interceptors.""" + +import collections +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 + + +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 _ClientCallDetails( + collections.namedtuple('_ClientCallDetails', + ('method', 'timeout', 'metadata', + 'credentials')), grpc.ClientCallDetails): + pass + + +class _GenericClientInterceptor( + grpc.UnaryUnaryClientInterceptor, grpc.UnaryStreamClientInterceptor, + grpc.StreamUnaryClientInterceptor, grpc.StreamStreamClientInterceptor): + + def __init__(self, interceptor_function): + self._fn = interceptor_function + + def intercept_unary_unary(self, continuation, client_call_details, request): + new_details, new_request_iterator, postprocess = self._fn( + client_call_details, iter((request,)), False, False) + response = continuation(new_details, next(new_request_iterator)) + return postprocess(response) if postprocess else response + + def intercept_unary_stream(self, continuation, client_call_details, + request): + new_details, new_request_iterator, postprocess = self._fn( + client_call_details, iter((request,)), False, True) + response_it = continuation(new_details, new_request_iterator) + return postprocess(response_it) if postprocess else response_it + + def intercept_stream_unary(self, continuation, client_call_details, + request_iterator): + new_details, new_request_iterator, postprocess = self._fn( + client_call_details, request_iterator, True, False) + response = continuation(new_details, next(new_request_iterator)) + return postprocess(response) if postprocess else response + + def intercept_stream_stream(self, continuation, client_call_details, + request_iterator): + new_details, new_request_iterator, postprocess = self._fn( + client_call_details, request_iterator, True, True) + response_it = continuation(new_details, new_request_iterator) + return postprocess(response_it) if postprocess else response_it + + +class _LoggingInterceptor( + grpc.ServerInterceptor, grpc.UnaryUnaryClientInterceptor, + grpc.UnaryStreamClientInterceptor, grpc.StreamUnaryClientInterceptor, + grpc.StreamStreamClientInterceptor): + + def __init__(self, tag, record): + self.tag = tag + self.record = record + + def intercept_service(self, continuation, handler_call_details): + self.record.append(self.tag + ':intercept_service') + return continuation(handler_call_details) + + def intercept_unary_unary(self, continuation, client_call_details, request): + self.record.append(self.tag + ':intercept_unary_unary') + return continuation(client_call_details, request) + + def intercept_unary_stream(self, continuation, client_call_details, + request): + self.record.append(self.tag + ':intercept_unary_stream') + return continuation(client_call_details, request) + + def intercept_stream_unary(self, continuation, client_call_details, + request_iterator): + self.record.append(self.tag + ':intercept_stream_unary') + return continuation(client_call_details, request_iterator) + + def intercept_stream_stream(self, continuation, client_call_details, + request_iterator): + self.record.append(self.tag + ':intercept_stream_stream') + return continuation(client_call_details, request_iterator) + + +class _DefectiveClientInterceptor(grpc.UnaryUnaryClientInterceptor): + + def intercept_unary_unary(self, ignored_continuation, + ignored_client_call_details, ignored_request): + raise test_control.Defect() + + +def _wrap_request_iterator_stream_interceptor(wrapper): + + def intercept_call(client_call_details, request_iterator, request_streaming, + ignored_response_streaming): + if request_streaming: + return client_call_details, wrapper(request_iterator), None + else: + return client_call_details, request_iterator, None + + return _GenericClientInterceptor(intercept_call) + + +def _append_request_header_interceptor(header, value): + + def intercept_call(client_call_details, request_iterator, + ignored_request_streaming, ignored_response_streaming): + metadata = [] + if client_call_details.metadata: + metadata = list(client_call_details.metadata) + metadata.append((header, value,)) + client_call_details = _ClientCallDetails( + client_call_details.method, client_call_details.timeout, metadata, + client_call_details.credentials) + return client_call_details, request_iterator, None + + return _GenericClientInterceptor(intercept_call) + + +class _GenericServerInterceptor(grpc.ServerInterceptor): + + def __init__(self, fn): + self._fn = fn + + def intercept_service(self, continuation, handler_call_details): + return self._fn(continuation, handler_call_details) + + +def _filter_server_interceptor(condition, interceptor): + + def intercept_service(continuation, handler_call_details): + if condition(handler_call_details): + return interceptor.intercept_service(continuation, + handler_call_details) + return continuation(handler_call_details) + + return _GenericServerInterceptor(intercept_service) + + +class InterceptorTest(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._record = [] + conditional_interceptor = _filter_server_interceptor( + lambda x: ('secret', '42') in x.invocation_metadata, + _LoggingInterceptor('s3', self._record)) + + self._server = grpc.server( + self._server_pool, + interceptors=(_LoggingInterceptor('s1', self._record), + conditional_interceptor, + _LoggingInterceptor('s2', self._record),)) + 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(None) + self._server_pool.shutdown(wait=True) + + def testTripleRequestMessagesClientInterceptor(self): + + def triple(request_iterator): + while True: + try: + item = next(request_iterator) + yield item + yield item + yield item + except StopIteration: + break + + interceptor = _wrap_request_iterator_stream_interceptor(triple) + channel = grpc.intercept_channel(self._channel, interceptor) + requests = tuple(b'\x07\x08' + for _ in range(test_constants.STREAM_LENGTH)) + + multi_callable = _stream_stream_multi_callable(channel) + response_iterator = multi_callable( + iter(requests), + metadata=( + ('test', + 'InterceptedStreamRequestBlockingUnaryResponseWithCall'),)) + + responses = tuple(response_iterator) + self.assertEqual(len(responses), 3 * test_constants.STREAM_LENGTH) + + multi_callable = _stream_stream_multi_callable(self._channel) + response_iterator = multi_callable( + iter(requests), + metadata=( + ('test', + 'InterceptedStreamRequestBlockingUnaryResponseWithCall'),)) + + responses = tuple(response_iterator) + self.assertEqual(len(responses), test_constants.STREAM_LENGTH) + + def testDefectiveClientInterceptor(self): + interceptor = _DefectiveClientInterceptor() + defective_channel = grpc.intercept_channel(self._channel, interceptor) + + request = b'\x07\x08' + + multi_callable = _unary_unary_multi_callable(defective_channel) + call_future = multi_callable.future( + request, + metadata=( + ('test', 'InterceptedUnaryRequestBlockingUnaryResponse'),)) + + self.assertIsNotNone(call_future.exception()) + self.assertEqual(call_future.code(), grpc.StatusCode.INTERNAL) + + def testInterceptedHeaderManipulationWithServerSideVerification(self): + request = b'\x07\x08' + + channel = grpc.intercept_channel( + self._channel, _append_request_header_interceptor('secret', '42')) + channel = grpc.intercept_channel( + channel, + _LoggingInterceptor('c1', self._record), + _LoggingInterceptor('c2', self._record)) + + self._record[:] = [] + + multi_callable = _unary_unary_multi_callable(channel) + multi_callable.with_call( + request, + metadata=( + ('test', + 'InterceptedUnaryRequestBlockingUnaryResponseWithCall'),)) + + self.assertSequenceEqual(self._record, [ + 'c1:intercept_unary_unary', 'c2:intercept_unary_unary', + 's1:intercept_service', 's3:intercept_service', + 's2:intercept_service' + ]) + + def testInterceptedUnaryRequestBlockingUnaryResponse(self): + request = b'\x07\x08' + + self._record[:] = [] + + channel = grpc.intercept_channel( + self._channel, + _LoggingInterceptor('c1', self._record), + _LoggingInterceptor('c2', self._record)) + + multi_callable = _unary_unary_multi_callable(channel) + multi_callable( + request, + metadata=( + ('test', 'InterceptedUnaryRequestBlockingUnaryResponse'),)) + + self.assertSequenceEqual(self._record, [ + 'c1:intercept_unary_unary', 'c2:intercept_unary_unary', + 's1:intercept_service', 's2:intercept_service' + ]) + + def testInterceptedUnaryRequestBlockingUnaryResponseWithCall(self): + request = b'\x07\x08' + + channel = grpc.intercept_channel( + self._channel, + _LoggingInterceptor('c1', self._record), + _LoggingInterceptor('c2', self._record)) + + self._record[:] = [] + + multi_callable = _unary_unary_multi_callable(channel) + multi_callable.with_call( + request, + metadata=( + ('test', + 'InterceptedUnaryRequestBlockingUnaryResponseWithCall'),)) + + self.assertSequenceEqual(self._record, [ + 'c1:intercept_unary_unary', 'c2:intercept_unary_unary', + 's1:intercept_service', 's2:intercept_service' + ]) + + def testInterceptedUnaryRequestFutureUnaryResponse(self): + request = b'\x07\x08' + + self._record[:] = [] + channel = grpc.intercept_channel( + self._channel, + _LoggingInterceptor('c1', self._record), + _LoggingInterceptor('c2', self._record)) + + multi_callable = _unary_unary_multi_callable(channel) + response_future = multi_callable.future( + request, + metadata=(('test', 'InterceptedUnaryRequestFutureUnaryResponse'),)) + response_future.result() + + self.assertSequenceEqual(self._record, [ + 'c1:intercept_unary_unary', 'c2:intercept_unary_unary', + 's1:intercept_service', 's2:intercept_service' + ]) + + def testInterceptedUnaryRequestStreamResponse(self): + request = b'\x37\x58' + + self._record[:] = [] + channel = grpc.intercept_channel( + self._channel, + _LoggingInterceptor('c1', self._record), + _LoggingInterceptor('c2', self._record)) + + multi_callable = _unary_stream_multi_callable(channel) + response_iterator = multi_callable( + request, + metadata=(('test', 'InterceptedUnaryRequestStreamResponse'),)) + tuple(response_iterator) + + self.assertSequenceEqual(self._record, [ + 'c1:intercept_unary_stream', 'c2:intercept_unary_stream', + 's1:intercept_service', 's2:intercept_service' + ]) + + def testInterceptedStreamRequestBlockingUnaryResponse(self): + requests = tuple(b'\x07\x08' + for _ in range(test_constants.STREAM_LENGTH)) + request_iterator = iter(requests) + + self._record[:] = [] + channel = grpc.intercept_channel( + self._channel, + _LoggingInterceptor('c1', self._record), + _LoggingInterceptor('c2', self._record)) + + multi_callable = _stream_unary_multi_callable(channel) + multi_callable( + request_iterator, + metadata=( + ('test', 'InterceptedStreamRequestBlockingUnaryResponse'),)) + + self.assertSequenceEqual(self._record, [ + 'c1:intercept_stream_unary', 'c2:intercept_stream_unary', + 's1:intercept_service', 's2:intercept_service' + ]) + + def testInterceptedStreamRequestBlockingUnaryResponseWithCall(self): + requests = tuple(b'\x07\x08' + for _ in range(test_constants.STREAM_LENGTH)) + request_iterator = iter(requests) + + self._record[:] = [] + channel = grpc.intercept_channel( + self._channel, + _LoggingInterceptor('c1', self._record), + _LoggingInterceptor('c2', self._record)) + + multi_callable = _stream_unary_multi_callable(channel) + multi_callable.with_call( + request_iterator, + metadata=( + ('test', + 'InterceptedStreamRequestBlockingUnaryResponseWithCall'),)) + + self.assertSequenceEqual(self._record, [ + 'c1:intercept_stream_unary', 'c2:intercept_stream_unary', + 's1:intercept_service', 's2:intercept_service' + ]) + + def testInterceptedStreamRequestFutureUnaryResponse(self): + requests = tuple(b'\x07\x08' + for _ in range(test_constants.STREAM_LENGTH)) + request_iterator = iter(requests) + + self._record[:] = [] + channel = grpc.intercept_channel( + self._channel, + _LoggingInterceptor('c1', self._record), + _LoggingInterceptor('c2', self._record)) + + multi_callable = _stream_unary_multi_callable(channel) + response_future = multi_callable.future( + request_iterator, + metadata=(('test', 'InterceptedStreamRequestFutureUnaryResponse'),)) + response_future.result() + + self.assertSequenceEqual(self._record, [ + 'c1:intercept_stream_unary', 'c2:intercept_stream_unary', + 's1:intercept_service', 's2:intercept_service' + ]) + + def testInterceptedStreamRequestStreamResponse(self): + requests = tuple(b'\x77\x58' + for _ in range(test_constants.STREAM_LENGTH)) + request_iterator = iter(requests) + + self._record[:] = [] + channel = grpc.intercept_channel( + self._channel, + _LoggingInterceptor('c1', self._record), + _LoggingInterceptor('c2', self._record)) + + multi_callable = _stream_stream_multi_callable(channel) + response_iterator = multi_callable( + request_iterator, + metadata=(('test', 'InterceptedStreamRequestStreamResponse'),)) + tuple(response_iterator) + + self.assertSequenceEqual(self._record, [ + 'c1:intercept_stream_stream', 'c2:intercept_stream_stream', + 's1:intercept_service', 's2:intercept_service' + ]) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py b/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py index 6faab94be6..cb59cd3769 100644 --- a/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py +++ b/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py @@ -56,6 +56,7 @@ class _Servicer(object): def __init__(self): self._lock = threading.Lock() + self._abort_call = False self._code = None self._details = None self._exception = False @@ -67,10 +68,13 @@ class _Servicer(object): self._received_client_metadata = context.invocation_metadata() context.send_initial_metadata(_SERVER_INITIAL_METADATA) context.set_trailing_metadata(_SERVER_TRAILING_METADATA) - if self._code is not None: - context.set_code(self._code) - if self._details is not None: - context.set_details(self._details) + if self._abort_call: + context.abort(self._code, self._details) + else: + if self._code is not None: + context.set_code(self._code) + if self._details is not None: + context.set_details(self._details) if self._exception: raise test_control.Defect() else: @@ -81,10 +85,13 @@ class _Servicer(object): self._received_client_metadata = context.invocation_metadata() context.send_initial_metadata(_SERVER_INITIAL_METADATA) context.set_trailing_metadata(_SERVER_TRAILING_METADATA) - if self._code is not None: - context.set_code(self._code) - if self._details is not None: - context.set_details(self._details) + if self._abort_call: + context.abort(self._code, self._details) + else: + if self._code is not None: + context.set_code(self._code) + if self._details is not None: + context.set_details(self._details) for _ in range(test_constants.STREAM_LENGTH // 2): yield _SERIALIZED_RESPONSE if self._exception: @@ -95,14 +102,16 @@ class _Servicer(object): self._received_client_metadata = context.invocation_metadata() context.send_initial_metadata(_SERVER_INITIAL_METADATA) context.set_trailing_metadata(_SERVER_TRAILING_METADATA) - if self._code is not None: - context.set_code(self._code) - if self._details is not None: - context.set_details(self._details) # TODO(https://github.com/grpc/grpc/issues/6891): just ignore the # request iterator. - for ignored_request in request_iterator: - pass + list(request_iterator) + if self._abort_call: + context.abort(self._code, self._details) + else: + if self._code is not None: + context.set_code(self._code) + if self._details is not None: + context.set_details(self._details) if self._exception: raise test_control.Defect() else: @@ -113,19 +122,25 @@ class _Servicer(object): self._received_client_metadata = context.invocation_metadata() context.send_initial_metadata(_SERVER_INITIAL_METADATA) context.set_trailing_metadata(_SERVER_TRAILING_METADATA) - if self._code is not None: - context.set_code(self._code) - if self._details is not None: - context.set_details(self._details) # TODO(https://github.com/grpc/grpc/issues/6891): just ignore the # request iterator. - for ignored_request in request_iterator: - pass + list(request_iterator) + if self._abort_call: + context.abort(self._code, self._details) + else: + if self._code is not None: + context.set_code(self._code) + if self._details is not None: + context.set_details(self._details) for _ in range(test_constants.STREAM_LENGTH // 3): yield object() if self._exception: raise test_control.Defect() + def set_abort_call(self): + with self._lock: + self._abort_call = True + def set_code(self, code): with self._lock: self._code = code @@ -212,11 +227,10 @@ class MetadataCodeDetailsTest(unittest.TestCase): def testSuccessfulUnaryStream(self): self._servicer.set_details(_DETAILS) - call = self._unary_stream( + response_iterator_call = self._unary_stream( _SERIALIZED_REQUEST, metadata=_CLIENT_METADATA) - received_initial_metadata = call.initial_metadata() - for _ in call: - pass + received_initial_metadata = response_iterator_call.initial_metadata() + list(response_iterator_call) self.assertTrue( test_common.metadata_transmitted( @@ -225,10 +239,11 @@ class MetadataCodeDetailsTest(unittest.TestCase): test_common.metadata_transmitted(_SERVER_INITIAL_METADATA, received_initial_metadata)) self.assertTrue( - test_common.metadata_transmitted(_SERVER_TRAILING_METADATA, - call.trailing_metadata())) - self.assertIs(grpc.StatusCode.OK, call.code()) - self.assertEqual(_DETAILS, call.details()) + test_common.metadata_transmitted( + _SERVER_TRAILING_METADATA, + response_iterator_call.trailing_metadata())) + self.assertIs(grpc.StatusCode.OK, response_iterator_call.code()) + self.assertEqual(_DETAILS, response_iterator_call.details()) def testSuccessfulStreamUnary(self): self._servicer.set_details(_DETAILS) @@ -252,12 +267,11 @@ class MetadataCodeDetailsTest(unittest.TestCase): def testSuccessfulStreamStream(self): self._servicer.set_details(_DETAILS) - call = self._stream_stream( + response_iterator_call = self._stream_stream( iter([object()] * test_constants.STREAM_LENGTH), metadata=_CLIENT_METADATA) - received_initial_metadata = call.initial_metadata() - for _ in call: - pass + received_initial_metadata = response_iterator_call.initial_metadata() + list(response_iterator_call) self.assertTrue( test_common.metadata_transmitted( @@ -266,10 +280,106 @@ class MetadataCodeDetailsTest(unittest.TestCase): test_common.metadata_transmitted(_SERVER_INITIAL_METADATA, received_initial_metadata)) self.assertTrue( - test_common.metadata_transmitted(_SERVER_TRAILING_METADATA, - call.trailing_metadata())) - self.assertIs(grpc.StatusCode.OK, call.code()) - self.assertEqual(_DETAILS, call.details()) + test_common.metadata_transmitted( + _SERVER_TRAILING_METADATA, + response_iterator_call.trailing_metadata())) + self.assertIs(grpc.StatusCode.OK, response_iterator_call.code()) + self.assertEqual(_DETAILS, response_iterator_call.details()) + + def testAbortedUnaryUnary(self): + self._servicer.set_code(_NON_OK_CODE) + self._servicer.set_details(_DETAILS) + self._servicer.set_abort_call() + + with self.assertRaises(grpc.RpcError) as exception_context: + self._unary_unary.with_call(object(), metadata=_CLIENT_METADATA) + + self.assertTrue( + test_common.metadata_transmitted( + _CLIENT_METADATA, self._servicer.received_client_metadata())) + self.assertTrue( + test_common.metadata_transmitted( + _SERVER_INITIAL_METADATA, + exception_context.exception.initial_metadata())) + self.assertTrue( + test_common.metadata_transmitted( + _SERVER_TRAILING_METADATA, + exception_context.exception.trailing_metadata())) + self.assertIs(_NON_OK_CODE, exception_context.exception.code()) + self.assertEqual(_DETAILS, exception_context.exception.details()) + + def testAbortedUnaryStream(self): + self._servicer.set_code(_NON_OK_CODE) + self._servicer.set_details(_DETAILS) + self._servicer.set_abort_call() + + response_iterator_call = self._unary_stream( + _SERIALIZED_REQUEST, metadata=_CLIENT_METADATA) + received_initial_metadata = response_iterator_call.initial_metadata() + with self.assertRaises(grpc.RpcError): + self.assertEqual(len(list(response_iterator_call)), 0) + + self.assertTrue( + test_common.metadata_transmitted( + _CLIENT_METADATA, self._servicer.received_client_metadata())) + self.assertTrue( + test_common.metadata_transmitted(_SERVER_INITIAL_METADATA, + received_initial_metadata)) + self.assertTrue( + test_common.metadata_transmitted( + _SERVER_TRAILING_METADATA, + response_iterator_call.trailing_metadata())) + self.assertIs(_NON_OK_CODE, response_iterator_call.code()) + self.assertEqual(_DETAILS, response_iterator_call.details()) + + def testAbortedStreamUnary(self): + self._servicer.set_code(_NON_OK_CODE) + self._servicer.set_details(_DETAILS) + self._servicer.set_abort_call() + + with self.assertRaises(grpc.RpcError) as exception_context: + self._stream_unary.with_call( + iter([_SERIALIZED_REQUEST] * test_constants.STREAM_LENGTH), + metadata=_CLIENT_METADATA) + + self.assertTrue( + test_common.metadata_transmitted( + _CLIENT_METADATA, self._servicer.received_client_metadata())) + self.assertTrue( + test_common.metadata_transmitted( + _SERVER_INITIAL_METADATA, + exception_context.exception.initial_metadata())) + self.assertTrue( + test_common.metadata_transmitted( + _SERVER_TRAILING_METADATA, + exception_context.exception.trailing_metadata())) + self.assertIs(_NON_OK_CODE, exception_context.exception.code()) + self.assertEqual(_DETAILS, exception_context.exception.details()) + + def testAbortedStreamStream(self): + self._servicer.set_code(_NON_OK_CODE) + self._servicer.set_details(_DETAILS) + self._servicer.set_abort_call() + + response_iterator_call = self._stream_stream( + iter([object()] * test_constants.STREAM_LENGTH), + metadata=_CLIENT_METADATA) + received_initial_metadata = response_iterator_call.initial_metadata() + with self.assertRaises(grpc.RpcError): + self.assertEqual(len(list(response_iterator_call)), 0) + + self.assertTrue( + test_common.metadata_transmitted( + _CLIENT_METADATA, self._servicer.received_client_metadata())) + self.assertTrue( + test_common.metadata_transmitted(_SERVER_INITIAL_METADATA, + received_initial_metadata)) + self.assertTrue( + test_common.metadata_transmitted( + _SERVER_TRAILING_METADATA, + response_iterator_call.trailing_metadata())) + self.assertIs(_NON_OK_CODE, response_iterator_call.code()) + self.assertEqual(_DETAILS, response_iterator_call.details()) def testCustomCodeUnaryUnary(self): self._servicer.set_code(_NON_OK_CODE) @@ -296,12 +406,11 @@ class MetadataCodeDetailsTest(unittest.TestCase): self._servicer.set_code(_NON_OK_CODE) self._servicer.set_details(_DETAILS) - call = self._unary_stream( + response_iterator_call = self._unary_stream( _SERIALIZED_REQUEST, metadata=_CLIENT_METADATA) - received_initial_metadata = call.initial_metadata() + received_initial_metadata = response_iterator_call.initial_metadata() with self.assertRaises(grpc.RpcError): - for _ in call: - pass + list(response_iterator_call) self.assertTrue( test_common.metadata_transmitted( @@ -310,10 +419,11 @@ class MetadataCodeDetailsTest(unittest.TestCase): test_common.metadata_transmitted(_SERVER_INITIAL_METADATA, received_initial_metadata)) self.assertTrue( - test_common.metadata_transmitted(_SERVER_TRAILING_METADATA, - call.trailing_metadata())) - self.assertIs(_NON_OK_CODE, call.code()) - self.assertEqual(_DETAILS, call.details()) + test_common.metadata_transmitted( + _SERVER_TRAILING_METADATA, + response_iterator_call.trailing_metadata())) + self.assertIs(_NON_OK_CODE, response_iterator_call.code()) + self.assertEqual(_DETAILS, response_iterator_call.details()) def testCustomCodeStreamUnary(self): self._servicer.set_code(_NON_OK_CODE) @@ -342,13 +452,12 @@ class MetadataCodeDetailsTest(unittest.TestCase): self._servicer.set_code(_NON_OK_CODE) self._servicer.set_details(_DETAILS) - call = self._stream_stream( + response_iterator_call = self._stream_stream( iter([object()] * test_constants.STREAM_LENGTH), metadata=_CLIENT_METADATA) - received_initial_metadata = call.initial_metadata() + received_initial_metadata = response_iterator_call.initial_metadata() with self.assertRaises(grpc.RpcError) as exception_context: - for _ in call: - pass + list(response_iterator_call) self.assertTrue( test_common.metadata_transmitted( @@ -390,12 +499,11 @@ class MetadataCodeDetailsTest(unittest.TestCase): self._servicer.set_details(_DETAILS) self._servicer.set_exception() - call = self._unary_stream( + response_iterator_call = self._unary_stream( _SERIALIZED_REQUEST, metadata=_CLIENT_METADATA) - received_initial_metadata = call.initial_metadata() + received_initial_metadata = response_iterator_call.initial_metadata() with self.assertRaises(grpc.RpcError): - for _ in call: - pass + list(response_iterator_call) self.assertTrue( test_common.metadata_transmitted( @@ -404,10 +512,11 @@ class MetadataCodeDetailsTest(unittest.TestCase): test_common.metadata_transmitted(_SERVER_INITIAL_METADATA, received_initial_metadata)) self.assertTrue( - test_common.metadata_transmitted(_SERVER_TRAILING_METADATA, - call.trailing_metadata())) - self.assertIs(_NON_OK_CODE, call.code()) - self.assertEqual(_DETAILS, call.details()) + test_common.metadata_transmitted( + _SERVER_TRAILING_METADATA, + response_iterator_call.trailing_metadata())) + self.assertIs(_NON_OK_CODE, response_iterator_call.code()) + self.assertEqual(_DETAILS, response_iterator_call.details()) def testCustomCodeExceptionStreamUnary(self): self._servicer.set_code(_NON_OK_CODE) @@ -438,13 +547,12 @@ class MetadataCodeDetailsTest(unittest.TestCase): self._servicer.set_details(_DETAILS) self._servicer.set_exception() - call = self._stream_stream( + response_iterator_call = self._stream_stream( iter([object()] * test_constants.STREAM_LENGTH), metadata=_CLIENT_METADATA) - received_initial_metadata = call.initial_metadata() + received_initial_metadata = response_iterator_call.initial_metadata() with self.assertRaises(grpc.RpcError): - for _ in call: - pass + list(response_iterator_call) self.assertTrue( test_common.metadata_transmitted( @@ -453,10 +561,11 @@ class MetadataCodeDetailsTest(unittest.TestCase): test_common.metadata_transmitted(_SERVER_INITIAL_METADATA, received_initial_metadata)) self.assertTrue( - test_common.metadata_transmitted(_SERVER_TRAILING_METADATA, - call.trailing_metadata())) - self.assertIs(_NON_OK_CODE, call.code()) - self.assertEqual(_DETAILS, call.details()) + test_common.metadata_transmitted( + _SERVER_TRAILING_METADATA, + response_iterator_call.trailing_metadata())) + self.assertIs(_NON_OK_CODE, response_iterator_call.code()) + self.assertEqual(_DETAILS, response_iterator_call.details()) def testCustomCodeReturnNoneUnaryUnary(self): self._servicer.set_code(_NON_OK_CODE) diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb index 9d2cf2a08a..c1a0c56841 100644 --- a/src/ruby/ext/grpc/extconf.rb +++ b/src/ruby/ext/grpc/extconf.rb @@ -61,7 +61,7 @@ ENV['EMBED_ZLIB'] = 'true' ENV['EMBED_CARES'] = 'true' ENV['ARCH_FLAGS'] = RbConfig::CONFIG['ARCH_FLAG'] ENV['ARCH_FLAGS'] = '-arch i386 -arch x86_64' if RUBY_PLATFORM =~ /darwin/ -ENV['CFLAGS'] = '-DGPR_BACKWARDS_COMPATIBILITY_MODE' +ENV['CPPFLAGS'] = '-DGPR_BACKWARDS_COMPATIBILITY_MODE' output_dir = File.expand_path(RbConfig::CONFIG['topdir']) grpc_lib_dir = File.join(output_dir, 'libs', grpc_config) |