mirror of https://github.com/grpc/grpc.git
commit
4f1a75f0aa
77 changed files with 2628 additions and 692 deletions
@ -0,0 +1,44 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_INTERNAL_CORE_CHANNEL_CONTEXT_H |
||||
#define GRPC_INTERNAL_CORE_CHANNEL_CONTEXT_H |
||||
|
||||
/* Call object context pointers */ |
||||
typedef enum { |
||||
GRPC_CONTEXT_SECURITY = 0, |
||||
GRPC_CONTEXT_TRACING, |
||||
GRPC_CONTEXT_COUNT |
||||
} grpc_context_index; |
||||
|
||||
#endif |
@ -0,0 +1,101 @@ |
||||
#region Copyright notice and license |
||||
|
||||
// Copyright 2015, Google Inc. |
||||
// All rights reserved. |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
#endregion |
||||
|
||||
using System; |
||||
using System.Runtime.CompilerServices; |
||||
using System.Threading.Tasks; |
||||
|
||||
namespace Grpc.Core |
||||
{ |
||||
/// <summary> |
||||
/// Return type for bidirectional streaming calls. |
||||
/// </summary> |
||||
public struct AsyncDuplexStreamingCall<TRequest, TResponse> |
||||
{ |
||||
readonly IClientStreamWriter<TRequest> requestStream; |
||||
readonly IAsyncStreamReader<TResponse> responseStream; |
||||
|
||||
public AsyncDuplexStreamingCall(IClientStreamWriter<TRequest> requestStream, IAsyncStreamReader<TResponse> responseStream) |
||||
{ |
||||
this.requestStream = requestStream; |
||||
this.responseStream = responseStream; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Writes a request to RequestStream. |
||||
/// </summary> |
||||
public Task Write(TRequest message) |
||||
{ |
||||
return requestStream.Write(message); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Closes the RequestStream. |
||||
/// </summary> |
||||
public Task Close() |
||||
{ |
||||
return requestStream.Close(); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Reads a response from ResponseStream. |
||||
/// </summary> |
||||
/// <returns></returns> |
||||
public Task<TResponse> ReadNext() |
||||
{ |
||||
return responseStream.ReadNext(); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Async stream to read streaming responses. |
||||
/// </summary> |
||||
public IAsyncStreamReader<TResponse> ResponseStream |
||||
{ |
||||
get |
||||
{ |
||||
return responseStream; |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Async stream to send streaming requests. |
||||
/// </summary> |
||||
public IClientStreamWriter<TRequest> RequestStream |
||||
{ |
||||
get |
||||
{ |
||||
return requestStream; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,45 @@ |
||||
#region Copyright notice and license |
||||
|
||||
// Copyright 2015, Google Inc. |
||||
// All rights reserved. |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
#endregion |
||||
|
||||
using System; |
||||
using System.Threading; |
||||
|
||||
namespace Grpc.Core.Internal |
||||
{ |
||||
internal static class DebugStats |
||||
{ |
||||
public static readonly AtomicCounter ActiveClientCalls = new AtomicCounter(); |
||||
|
||||
public static readonly AtomicCounter ActiveServerCalls = new AtomicCounter(); |
||||
} |
||||
} |
@ -0,0 +1,63 @@ |
||||
#region Copyright notice and license |
||||
|
||||
// Copyright 2015, Google Inc. |
||||
// All rights reserved. |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
#endregion |
||||
|
||||
using System; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using Grpc.Core; |
||||
|
||||
namespace Grpc.Core.Internal |
||||
{ |
||||
internal static class ServerCalls |
||||
{ |
||||
public static IServerCallHandler UnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, UnaryServerMethod<TRequest, TResponse> handler) |
||||
{ |
||||
return new UnaryServerCallHandler<TRequest, TResponse>(method, handler); |
||||
} |
||||
|
||||
public static IServerCallHandler ClientStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, ClientStreamingServerMethod<TRequest, TResponse> handler) |
||||
{ |
||||
return new ClientStreamingServerCallHandler<TRequest, TResponse>(method, handler); |
||||
} |
||||
|
||||
public static IServerCallHandler ServerStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, ServerStreamingServerMethod<TRequest, TResponse> handler) |
||||
{ |
||||
return new ServerStreamingServerCallHandler<TRequest, TResponse>(method, handler); |
||||
} |
||||
|
||||
public static IServerCallHandler DuplexStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, DuplexStreamingServerMethod<TRequest, TResponse> handler) |
||||
{ |
||||
return new DuplexStreamingServerCallHandler<TRequest, TResponse>(method, handler); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,56 @@ |
||||
#region Copyright notice and license |
||||
|
||||
// Copyright 2015, Google Inc. |
||||
// All rights reserved. |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
#endregion |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Threading.Tasks; |
||||
|
||||
namespace Grpc.Core.Internal |
||||
{ |
||||
internal class ServerRequestStream<TRequest, TResponse> : IAsyncStreamReader<TRequest> |
||||
{ |
||||
readonly AsyncCallServer<TRequest, TResponse> call; |
||||
|
||||
public ServerRequestStream(AsyncCallServer<TRequest, TResponse> call) |
||||
{ |
||||
this.call = call; |
||||
} |
||||
|
||||
public Task<TRequest> ReadNext() |
||||
{ |
||||
var taskSource = new AsyncCompletionTaskSource<TRequest>(); |
||||
call.StartReadMessage(taskSource.CompletionDelegate); |
||||
return taskSource.Task; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,61 @@ |
||||
#region Copyright notice and license |
||||
|
||||
// Copyright 2015, Google Inc. |
||||
// All rights reserved. |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
#endregion |
||||
|
||||
using System; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
|
||||
using Grpc.Core.Internal; |
||||
|
||||
namespace Grpc.Core |
||||
{ |
||||
/// <summary> |
||||
/// Server-side handler for unary call. |
||||
/// </summary> |
||||
public delegate Task<TResponse> UnaryServerMethod<TRequest, TResponse>(TRequest request); |
||||
|
||||
/// <summary> |
||||
/// Server-side handler for client streaming call. |
||||
/// </summary> |
||||
public delegate Task<TResponse> ClientStreamingServerMethod<TRequest, TResponse>(IAsyncStreamReader<TRequest> requestStream); |
||||
|
||||
/// <summary> |
||||
/// Server-side handler for server streaming call. |
||||
/// </summary> |
||||
public delegate Task ServerStreamingServerMethod<TRequest, TResponse>(TRequest request, IServerStreamWriter<TResponse> responseStream); |
||||
|
||||
/// <summary> |
||||
/// Server-side handler for bidi streaming call. |
||||
/// </summary> |
||||
public delegate Task DuplexStreamingServerMethod<TRequest, TResponse>(IAsyncStreamReader<TRequest> requestStream, IServerStreamWriter<TResponse> responseStream); |
||||
} |
@ -0,0 +1,111 @@ |
||||
#region Copyright notice and license |
||||
|
||||
// Copyright 2015, Google Inc. |
||||
// All rights reserved. |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
#endregion |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Threading.Tasks; |
||||
|
||||
namespace Grpc.Core.Utils |
||||
{ |
||||
/// <summary> |
||||
/// Extension methods that simplify work with gRPC streaming calls. |
||||
/// </summary> |
||||
public static class AsyncStreamExtensions |
||||
{ |
||||
/// <summary> |
||||
/// Reads the entire stream and executes an async action for each element. |
||||
/// </summary> |
||||
public static async Task ForEach<T>(this IAsyncStreamReader<T> streamReader, Func<T, Task> asyncAction) |
||||
where T : class
|
||||
{ |
||||
while (true) |
||||
{ |
||||
var elem = await streamReader.ReadNext(); |
||||
if (elem == null) |
||||
{ |
||||
break; |
||||
} |
||||
await asyncAction(elem); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Reads the entire stream and creates a list containing all the elements read. |
||||
/// </summary> |
||||
public static async Task<List<T>> ToList<T>(this IAsyncStreamReader<T> streamReader) |
||||
where T : class
|
||||
{ |
||||
var result = new List<T>(); |
||||
while (true) |
||||
{ |
||||
var elem = await streamReader.ReadNext(); |
||||
if (elem == null) |
||||
{ |
||||
break; |
||||
} |
||||
result.Add(elem); |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Writes all elements from given enumerable to the stream. |
||||
/// Closes the stream afterwards unless close = false. |
||||
/// </summary> |
||||
public static async Task WriteAll<T>(this IClientStreamWriter<T> streamWriter, IEnumerable<T> elements, bool close = true) |
||||
where T : class
|
||||
{ |
||||
foreach (var element in elements) |
||||
{ |
||||
await streamWriter.Write(element); |
||||
} |
||||
if (close) |
||||
{ |
||||
await streamWriter.Close(); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Writes all elements from given enumerable to the stream. |
||||
/// </summary> |
||||
public static async Task WriteAll<T>(this IServerStreamWriter<T> streamWriter, IEnumerable<T> elements) |
||||
where T : class
|
||||
{ |
||||
foreach (var element in elements) |
||||
{ |
||||
await streamWriter.Write(element); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,210 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#include "test/core/end2end/end2end_tests.h" |
||||
|
||||
#include <stdio.h> |
||||
#include <string.h> |
||||
#include <unistd.h> |
||||
|
||||
#include <grpc/byte_buffer.h> |
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/log.h> |
||||
#include <grpc/support/time.h> |
||||
#include <grpc/support/useful.h> |
||||
#include "test/core/end2end/cq_verifier.h" |
||||
|
||||
enum { TIMEOUT = 200000 }; |
||||
|
||||
static void *tag(gpr_intptr t) { return (void *)t; } |
||||
|
||||
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, |
||||
const char *test_name, |
||||
grpc_channel_args *client_args, |
||||
grpc_channel_args *server_args) { |
||||
grpc_end2end_test_fixture f; |
||||
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); |
||||
f = config.create_fixture(client_args, server_args); |
||||
config.init_client(&f, client_args); |
||||
config.init_server(&f, server_args); |
||||
return f; |
||||
} |
||||
|
||||
static gpr_timespec n_seconds_time(int n) { |
||||
return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); |
||||
} |
||||
|
||||
static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } |
||||
|
||||
static void drain_cq(grpc_completion_queue *cq) { |
||||
grpc_event *ev; |
||||
grpc_completion_type type; |
||||
do { |
||||
ev = grpc_completion_queue_next(cq, five_seconds_time()); |
||||
GPR_ASSERT(ev); |
||||
type = ev->type; |
||||
grpc_event_finish(ev); |
||||
} while (type != GRPC_QUEUE_SHUTDOWN); |
||||
} |
||||
|
||||
static void shutdown_server(grpc_end2end_test_fixture *f) { |
||||
if (!f->server) return; |
||||
grpc_server_shutdown(f->server); |
||||
grpc_server_destroy(f->server); |
||||
f->server = NULL; |
||||
} |
||||
|
||||
static void shutdown_client(grpc_end2end_test_fixture *f) { |
||||
if (!f->client) return; |
||||
grpc_channel_destroy(f->client); |
||||
f->client = NULL; |
||||
} |
||||
|
||||
static void end_test(grpc_end2end_test_fixture *f) { |
||||
shutdown_server(f); |
||||
shutdown_client(f); |
||||
|
||||
grpc_completion_queue_shutdown(f->server_cq); |
||||
drain_cq(f->server_cq); |
||||
grpc_completion_queue_destroy(f->server_cq); |
||||
grpc_completion_queue_shutdown(f->client_cq); |
||||
drain_cq(f->client_cq); |
||||
grpc_completion_queue_destroy(f->client_cq); |
||||
} |
||||
|
||||
static void test_max_message_length(grpc_end2end_test_config config) { |
||||
grpc_end2end_test_fixture f; |
||||
grpc_arg server_arg; |
||||
grpc_channel_args server_args; |
||||
grpc_call *c; |
||||
grpc_call *s; |
||||
cq_verifier *v_client; |
||||
cq_verifier *v_server; |
||||
grpc_op ops[6]; |
||||
grpc_op *op; |
||||
gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world"); |
||||
grpc_byte_buffer *request_payload = |
||||
grpc_byte_buffer_create(&request_payload_slice, 1); |
||||
grpc_metadata_array initial_metadata_recv; |
||||
grpc_metadata_array trailing_metadata_recv; |
||||
grpc_metadata_array request_metadata_recv; |
||||
grpc_call_details call_details; |
||||
grpc_status_code status; |
||||
char *details = NULL; |
||||
size_t details_capacity = 0; |
||||
int was_cancelled = 2; |
||||
|
||||
server_arg.key = GRPC_ARG_MAX_MESSAGE_LENGTH; |
||||
server_arg.type = GRPC_ARG_INTEGER; |
||||
server_arg.value.integer = 5; |
||||
|
||||
server_args.num_args = 1; |
||||
server_args.args = &server_arg; |
||||
|
||||
f = begin_test(config, __FUNCTION__, NULL, &server_args); |
||||
v_client = cq_verifier_create(f.client_cq); |
||||
v_server = cq_verifier_create(f.server_cq); |
||||
|
||||
c = grpc_channel_create_call(f.client, f.client_cq, "/foo", |
||||
"foo.test.google.fr:1234", gpr_inf_future); |
||||
GPR_ASSERT(c); |
||||
|
||||
grpc_metadata_array_init(&initial_metadata_recv); |
||||
grpc_metadata_array_init(&trailing_metadata_recv); |
||||
grpc_metadata_array_init(&request_metadata_recv); |
||||
grpc_call_details_init(&call_details); |
||||
|
||||
op = ops; |
||||
op->op = GRPC_OP_SEND_INITIAL_METADATA; |
||||
op->data.send_initial_metadata.count = 0; |
||||
op++; |
||||
op->op = GRPC_OP_SEND_MESSAGE; |
||||
op->data.send_message = request_payload; |
||||
op++; |
||||
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; |
||||
op++; |
||||
op->op = GRPC_OP_RECV_INITIAL_METADATA; |
||||
op->data.recv_initial_metadata = &initial_metadata_recv; |
||||
op++; |
||||
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; |
||||
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; |
||||
op->data.recv_status_on_client.status = &status; |
||||
op->data.recv_status_on_client.status_details = &details; |
||||
op->data.recv_status_on_client.status_details_capacity = &details_capacity; |
||||
op++; |
||||
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, op - ops, tag(1))); |
||||
|
||||
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s, |
||||
&call_details, |
||||
&request_metadata_recv, |
||||
f.server_cq, tag(101))); |
||||
cq_expect_completion(v_server, tag(101), GRPC_OP_OK); |
||||
cq_verify(v_server); |
||||
|
||||
op = ops; |
||||
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; |
||||
op->data.recv_close_on_server.cancelled = &was_cancelled; |
||||
op++; |
||||
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102))); |
||||
|
||||
cq_expect_completion(v_server, tag(102), GRPC_OP_OK); |
||||
cq_verify(v_server); |
||||
|
||||
cq_expect_completion(v_client, tag(1), GRPC_OP_OK); |
||||
cq_verify(v_client); |
||||
|
||||
GPR_ASSERT(status == GRPC_STATUS_CANCELLED); |
||||
GPR_ASSERT(0 == strcmp(details, "Cancelled")); |
||||
GPR_ASSERT(0 == strcmp(call_details.method, "/foo")); |
||||
GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr:1234")); |
||||
GPR_ASSERT(was_cancelled == 1); |
||||
|
||||
gpr_free(details); |
||||
grpc_metadata_array_destroy(&initial_metadata_recv); |
||||
grpc_metadata_array_destroy(&trailing_metadata_recv); |
||||
grpc_metadata_array_destroy(&request_metadata_recv); |
||||
grpc_call_details_destroy(&call_details); |
||||
|
||||
grpc_call_destroy(c); |
||||
grpc_call_destroy(s); |
||||
|
||||
cq_verifier_destroy(v_client); |
||||
cq_verifier_destroy(v_server); |
||||
|
||||
end_test(&f); |
||||
config.tear_down_data(&f); |
||||
} |
||||
|
||||
void grpc_end2end_tests(grpc_end2end_test_config config) { |
||||
test_max_message_length(config); |
||||
} |
@ -0,0 +1,87 @@ |
||||
#!/usr/bin/env python |
||||
# Copyright 2015, Google Inc. |
||||
# All rights reserved. |
||||
# |
||||
# Redistribution and use in source and binary forms, with or without |
||||
# modification, are permitted provided that the following conditions are |
||||
# met: |
||||
# |
||||
# * Redistributions of source code must retain the above copyright |
||||
# notice, this list of conditions and the following disclaimer. |
||||
# * Redistributions in binary form must reproduce the above |
||||
# copyright notice, this list of conditions and the following disclaimer |
||||
# in the documentation and/or other materials provided with the |
||||
# distribution. |
||||
# * Neither the name of Google Inc. nor the names of its |
||||
# contributors may be used to endorse or promote products derived from |
||||
# this software without specific prior written permission. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
""" |
||||
Read GRPC basic profiles, analyze the data. |
||||
|
||||
Usage: |
||||
bins/basicprof/qps_smoke_test > log |
||||
cat log | tools/profile_analyzer/profile_analyzer.py |
||||
""" |
||||
|
||||
|
||||
import collections |
||||
import re |
||||
import sys |
||||
|
||||
# Create a regex to parse output of the C core basic profiler, |
||||
# as defined in src/core/profiling/basic_timers.c. |
||||
_RE_LINE = re.compile(r'GRPC_LAT_PROF ' + |
||||
r'([0-9]+\.[0-9]+) 0x([0-9a-f]+) ([{}.]) ([0-9]+) ' + |
||||
r'([^ ]+) ([^ ]+) ([0-9]+)') |
||||
|
||||
Entry = collections.namedtuple( |
||||
'Entry', |
||||
['time', 'thread', 'type', 'tag', 'id', 'file', 'line']) |
||||
|
||||
def entries(): |
||||
for line in sys.stdin: |
||||
m = _RE_LINE.match(line) |
||||
if not m: continue |
||||
yield Entry(time=float(m.group(1)), |
||||
thread=m.group(2), |
||||
type=m.group(3), |
||||
tag=int(m.group(4)), |
||||
id=m.group(5), |
||||
file=m.group(6), |
||||
line=m.group(7)) |
||||
|
||||
threads = collections.defaultdict(lambda: collections.defaultdict(list)) |
||||
times = collections.defaultdict(list) |
||||
|
||||
for entry in entries(): |
||||
thread = threads[entry.thread] |
||||
if entry.type == '{': |
||||
thread[entry.tag].append(entry) |
||||
elif entry.type == '}': |
||||
last = thread[entry.tag].pop() |
||||
times[entry.tag].append(entry.time - last.time) |
||||
|
||||
def percentile(vals, pct): |
||||
return sorted(vals)[int(len(vals) * pct / 100.0)] |
||||
|
||||
print 'tag 50%/90%/95%/99% us' |
||||
for tag in sorted(times.keys()): |
||||
vals = times[tag] |
||||
print '%d %.2f/%.2f/%.2f/%.2f' % (tag, |
||||
percentile(vals, 50), |
||||
percentile(vals, 90), |
||||
percentile(vals, 95), |
||||
percentile(vals, 99)) |
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue