mirror of https://github.com/grpc/grpc.git
commit
4251aad3eb
82 changed files with 2515 additions and 1031 deletions
@ -0,0 +1,103 @@ |
||||
#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 client streaming calls. |
||||
/// </summary> |
||||
public sealed class AsyncClientStreamingCall<TRequest, TResponse> |
||||
where TRequest : class
|
||||
where TResponse : class
|
||||
{ |
||||
readonly IClientStreamWriter<TRequest> requestStream; |
||||
readonly Task<TResponse> result; |
||||
|
||||
public AsyncClientStreamingCall(IClientStreamWriter<TRequest> requestStream, Task<TResponse> result) |
||||
{ |
||||
this.requestStream = requestStream; |
||||
this.result = result; |
||||
} |
||||
|
||||
/// <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> |
||||
/// Asynchronous call result. |
||||
/// </summary> |
||||
public Task<TResponse> Result |
||||
{ |
||||
get |
||||
{ |
||||
return this.result; |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Async stream to send streaming requests. |
||||
/// </summary> |
||||
public IClientStreamWriter<TRequest> RequestStream |
||||
{ |
||||
get |
||||
{ |
||||
return requestStream; |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Allows awaiting this object directly. |
||||
/// </summary> |
||||
/// <returns></returns> |
||||
public TaskAwaiter<TResponse> GetAwaiter() |
||||
{ |
||||
return result.GetAwaiter(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,103 @@ |
||||
#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 sealed class AsyncDuplexStreamingCall<TRequest, TResponse> |
||||
where TRequest : class
|
||||
where TResponse : class
|
||||
{ |
||||
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,71 @@ |
||||
#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) |
||||
where TRequest : class
|
||||
where TResponse : class
|
||||
{ |
||||
return new UnaryServerCallHandler<TRequest, TResponse>(method, handler); |
||||
} |
||||
|
||||
public static IServerCallHandler ClientStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, ClientStreamingServerMethod<TRequest, TResponse> handler) |
||||
where TRequest : class
|
||||
where TResponse : class
|
||||
{ |
||||
return new ClientStreamingServerCallHandler<TRequest, TResponse>(method, handler); |
||||
} |
||||
|
||||
public static IServerCallHandler ServerStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, ServerStreamingServerMethod<TRequest, TResponse> handler) |
||||
where TRequest : class
|
||||
where TResponse : class
|
||||
{ |
||||
return new ServerStreamingServerCallHandler<TRequest, TResponse>(method, handler); |
||||
} |
||||
|
||||
public static IServerCallHandler DuplexStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, DuplexStreamingServerMethod<TRequest, TResponse> handler) |
||||
where TRequest : class
|
||||
where TResponse : class
|
||||
{ |
||||
return new DuplexStreamingServerCallHandler<TRequest, TResponse>(method, handler); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,58 @@ |
||||
#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> |
||||
where TRequest : class
|
||||
where TResponse : class
|
||||
{ |
||||
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,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.Runtime.CompilerServices; |
||||
using System.Threading.Tasks; |
||||
|
||||
namespace Grpc.Core |
||||
{ |
||||
/// <summary> |
||||
/// Context for a server-side call. |
||||
/// </summary> |
||||
public sealed class ServerCallContext |
||||
{ |
||||
|
||||
// TODO(jtattermusch): add cancellationToken |
||||
|
||||
// TODO(jtattermusch): add deadline info |
||||
|
||||
// TODO(jtattermusch): expose initial metadata sent by client for reading |
||||
|
||||
// TODO(jtattermusch): expose method to send initial metadata back to client |
||||
|
||||
// TODO(jtattermusch): allow setting status and trailing metadata to send after handler completes. |
||||
} |
||||
} |
@ -0,0 +1,69 @@ |
||||
#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>(ServerCallContext context, TRequest request) |
||||
where TRequest : class
|
||||
where TResponse : class; |
||||
|
||||
/// <summary> |
||||
/// Server-side handler for client streaming call. |
||||
/// </summary> |
||||
public delegate Task<TResponse> ClientStreamingServerMethod<TRequest, TResponse>(ServerCallContext context, IAsyncStreamReader<TRequest> requestStream) |
||||
where TRequest : class
|
||||
where TResponse : class; |
||||
|
||||
/// <summary> |
||||
/// Server-side handler for server streaming call. |
||||
/// </summary> |
||||
public delegate Task ServerStreamingServerMethod<TRequest, TResponse>(ServerCallContext context, TRequest request, IServerStreamWriter<TResponse> responseStream) |
||||
where TRequest : class
|
||||
where TResponse : class; |
||||
|
||||
/// <summary> |
||||
/// Server-side handler for bidi streaming call. |
||||
/// </summary> |
||||
public delegate Task DuplexStreamingServerMethod<TRequest, TResponse>(ServerCallContext context, IAsyncStreamReader<TRequest> requestStream, IServerStreamWriter<TResponse> responseStream) |
||||
where TRequest : class
|
||||
where TResponse : class; |
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,315 +0,0 @@ |
||||
{ |
||||
"_readme": [ |
||||
"This file locks the dependencies of your project to a known state", |
||||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", |
||||
"This file is @generated automatically" |
||||
], |
||||
"hash": "bb81ea5f72ddea2f594a172ff0f3b44d", |
||||
"packages": [ |
||||
{ |
||||
"name": "firebase/php-jwt", |
||||
"version": "2.0.0", |
||||
"target-dir": "Firebase/PHP-JWT", |
||||
"source": { |
||||
"type": "git", |
||||
"url": "https://github.com/firebase/php-jwt.git", |
||||
"reference": "ffcfd888ce1e4f2d70cac2dc9b7301038332fe57" |
||||
}, |
||||
"dist": { |
||||
"type": "zip", |
||||
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/ffcfd888ce1e4f2d70cac2dc9b7301038332fe57", |
||||
"reference": "ffcfd888ce1e4f2d70cac2dc9b7301038332fe57", |
||||
"shasum": "" |
||||
}, |
||||
"require": { |
||||
"php": ">=5.2.0" |
||||
}, |
||||
"type": "library", |
||||
"autoload": { |
||||
"classmap": [ |
||||
"Authentication/", |
||||
"Exceptions/" |
||||
] |
||||
}, |
||||
"notification-url": "https://packagist.org/downloads/", |
||||
"license": [ |
||||
"BSD-3-Clause" |
||||
], |
||||
"authors": [ |
||||
{ |
||||
"name": "Neuman Vong", |
||||
"email": "neuman+pear@twilio.com", |
||||
"role": "Developer" |
||||
}, |
||||
{ |
||||
"name": "Anant Narayanan", |
||||
"email": "anant@php.net", |
||||
"role": "Developer" |
||||
} |
||||
], |
||||
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", |
||||
"homepage": "https://github.com/firebase/php-jwt", |
||||
"time": "2015-04-01 18:46:38" |
||||
}, |
||||
{ |
||||
"name": "google/auth", |
||||
"version": "dev-master", |
||||
"source": { |
||||
"type": "git", |
||||
"url": "https://github.com/google/google-auth-library-php.git", |
||||
"reference": "35f87159b327fa6416266948c1747c585a4ae3ad" |
||||
}, |
||||
"dist": { |
||||
"type": "zip", |
||||
"url": "https://api.github.com/repos/google/google-auth-library-php/zipball/35f87159b327fa6416266948c1747c585a4ae3ad", |
||||
"reference": "35f87159b327fa6416266948c1747c585a4ae3ad", |
||||
"shasum": "" |
||||
}, |
||||
"require": { |
||||
"firebase/php-jwt": "2.0.0", |
||||
"guzzlehttp/guzzle": "5.2.*", |
||||
"php": ">=5.4" |
||||
}, |
||||
"require-dev": { |
||||
"phplint/phplint": "0.0.1", |
||||
"phpunit/phpunit": "3.7.*" |
||||
}, |
||||
"type": "library", |
||||
"autoload": { |
||||
"classmap": [ |
||||
"src/" |
||||
], |
||||
"psr-4": { |
||||
"Google\\Auth\\": "src" |
||||
} |
||||
}, |
||||
"notification-url": "https://packagist.org/downloads/", |
||||
"license": [ |
||||
"Apache-2.0" |
||||
], |
||||
"description": "Google Auth Library for PHP", |
||||
"homepage": "http://github.com/google/google-auth-library-php", |
||||
"keywords": [ |
||||
"Authentication", |
||||
"google", |
||||
"oauth2" |
||||
], |
||||
"time": "2015-04-30 11:57:19" |
||||
}, |
||||
{ |
||||
"name": "guzzlehttp/guzzle", |
||||
"version": "5.2.0", |
||||
"source": { |
||||
"type": "git", |
||||
"url": "https://github.com/guzzle/guzzle.git", |
||||
"reference": "475b29ccd411f2fa8a408e64576418728c032cfa" |
||||
}, |
||||
"dist": { |
||||
"type": "zip", |
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/475b29ccd411f2fa8a408e64576418728c032cfa", |
||||
"reference": "475b29ccd411f2fa8a408e64576418728c032cfa", |
||||
"shasum": "" |
||||
}, |
||||
"require": { |
||||
"guzzlehttp/ringphp": "~1.0", |
||||
"php": ">=5.4.0" |
||||
}, |
||||
"require-dev": { |
||||
"ext-curl": "*", |
||||
"phpunit/phpunit": "~4.0", |
||||
"psr/log": "~1.0" |
||||
}, |
||||
"type": "library", |
||||
"extra": { |
||||
"branch-alias": { |
||||
"dev-master": "5.0-dev" |
||||
} |
||||
}, |
||||
"autoload": { |
||||
"psr-4": { |
||||
"GuzzleHttp\\": "src/" |
||||
} |
||||
}, |
||||
"notification-url": "https://packagist.org/downloads/", |
||||
"license": [ |
||||
"MIT" |
||||
], |
||||
"authors": [ |
||||
{ |
||||
"name": "Michael Dowling", |
||||
"email": "mtdowling@gmail.com", |
||||
"homepage": "https://github.com/mtdowling" |
||||
} |
||||
], |
||||
"description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", |
||||
"homepage": "http://guzzlephp.org/", |
||||
"keywords": [ |
||||
"client", |
||||
"curl", |
||||
"framework", |
||||
"http", |
||||
"http client", |
||||
"rest", |
||||
"web service" |
||||
], |
||||
"time": "2015-01-28 01:03:29" |
||||
}, |
||||
{ |
||||
"name": "guzzlehttp/ringphp", |
||||
"version": "1.0.7", |
||||
"source": { |
||||
"type": "git", |
||||
"url": "https://github.com/guzzle/RingPHP.git", |
||||
"reference": "52d868f13570a9a56e5fce6614e0ec75d0f13ac2" |
||||
}, |
||||
"dist": { |
||||
"type": "zip", |
||||
"url": "https://api.github.com/repos/guzzle/RingPHP/zipball/52d868f13570a9a56e5fce6614e0ec75d0f13ac2", |
||||
"reference": "52d868f13570a9a56e5fce6614e0ec75d0f13ac2", |
||||
"shasum": "" |
||||
}, |
||||
"require": { |
||||
"guzzlehttp/streams": "~3.0", |
||||
"php": ">=5.4.0", |
||||
"react/promise": "~2.0" |
||||
}, |
||||
"require-dev": { |
||||
"ext-curl": "*", |
||||
"phpunit/phpunit": "~4.0" |
||||
}, |
||||
"suggest": { |
||||
"ext-curl": "Guzzle will use specific adapters if cURL is present" |
||||
}, |
||||
"type": "library", |
||||
"extra": { |
||||
"branch-alias": { |
||||
"dev-master": "1.0-dev" |
||||
} |
||||
}, |
||||
"autoload": { |
||||
"psr-4": { |
||||
"GuzzleHttp\\Ring\\": "src/" |
||||
} |
||||
}, |
||||
"notification-url": "https://packagist.org/downloads/", |
||||
"license": [ |
||||
"MIT" |
||||
], |
||||
"authors": [ |
||||
{ |
||||
"name": "Michael Dowling", |
||||
"email": "mtdowling@gmail.com", |
||||
"homepage": "https://github.com/mtdowling" |
||||
} |
||||
], |
||||
"description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.", |
||||
"time": "2015-03-30 01:43:20" |
||||
}, |
||||
{ |
||||
"name": "guzzlehttp/streams", |
||||
"version": "3.0.0", |
||||
"source": { |
||||
"type": "git", |
||||
"url": "https://github.com/guzzle/streams.git", |
||||
"reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5" |
||||
}, |
||||
"dist": { |
||||
"type": "zip", |
||||
"url": "https://api.github.com/repos/guzzle/streams/zipball/47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", |
||||
"reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", |
||||
"shasum": "" |
||||
}, |
||||
"require": { |
||||
"php": ">=5.4.0" |
||||
}, |
||||
"require-dev": { |
||||
"phpunit/phpunit": "~4.0" |
||||
}, |
||||
"type": "library", |
||||
"extra": { |
||||
"branch-alias": { |
||||
"dev-master": "3.0-dev" |
||||
} |
||||
}, |
||||
"autoload": { |
||||
"psr-4": { |
||||
"GuzzleHttp\\Stream\\": "src/" |
||||
} |
||||
}, |
||||
"notification-url": "https://packagist.org/downloads/", |
||||
"license": [ |
||||
"MIT" |
||||
], |
||||
"authors": [ |
||||
{ |
||||
"name": "Michael Dowling", |
||||
"email": "mtdowling@gmail.com", |
||||
"homepage": "https://github.com/mtdowling" |
||||
} |
||||
], |
||||
"description": "Provides a simple abstraction over streams of data", |
||||
"homepage": "http://guzzlephp.org/", |
||||
"keywords": [ |
||||
"Guzzle", |
||||
"stream" |
||||
], |
||||
"time": "2014-10-12 19:18:40" |
||||
}, |
||||
{ |
||||
"name": "react/promise", |
||||
"version": "v2.2.0", |
||||
"source": { |
||||
"type": "git", |
||||
"url": "https://github.com/reactphp/promise.git", |
||||
"reference": "365fcee430dfa4ace1fbc75737ca60ceea7eeeef" |
||||
}, |
||||
"dist": { |
||||
"type": "zip", |
||||
"url": "https://api.github.com/repos/reactphp/promise/zipball/365fcee430dfa4ace1fbc75737ca60ceea7eeeef", |
||||
"reference": "365fcee430dfa4ace1fbc75737ca60ceea7eeeef", |
||||
"shasum": "" |
||||
}, |
||||
"require": { |
||||
"php": ">=5.4.0" |
||||
}, |
||||
"type": "library", |
||||
"extra": { |
||||
"branch-alias": { |
||||
"dev-master": "2.0-dev" |
||||
} |
||||
}, |
||||
"autoload": { |
||||
"psr-4": { |
||||
"React\\Promise\\": "src/" |
||||
}, |
||||
"files": [ |
||||
"src/functions_include.php" |
||||
] |
||||
}, |
||||
"notification-url": "https://packagist.org/downloads/", |
||||
"license": [ |
||||
"MIT" |
||||
], |
||||
"authors": [ |
||||
{ |
||||
"name": "Jan Sorgalla", |
||||
"email": "jsorgalla@googlemail.com" |
||||
} |
||||
], |
||||
"description": "A lightweight implementation of CommonJS Promises/A for PHP", |
||||
"time": "2014-12-30 13:32:42" |
||||
} |
||||
], |
||||
"packages-dev": [], |
||||
"aliases": [], |
||||
"minimum-stability": "stable", |
||||
"stability-flags": { |
||||
"google/auth": 20 |
||||
}, |
||||
"prefer-stable": false, |
||||
"prefer-lowest": false, |
||||
"platform": { |
||||
"php": ">=5.5.0" |
||||
}, |
||||
"platform-dev": [] |
||||
} |
@ -0,0 +1,139 @@ |
||||
#!/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 itertools |
||||
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']) |
||||
|
||||
|
||||
class ImportantMark(object): |
||||
def __init__(self, entry, stack): |
||||
self._entry = entry |
||||
self._pre_stack = stack |
||||
self._post_stack = list() |
||||
self._n = len(stack) # we'll also compute times to that many closing }s |
||||
|
||||
@property |
||||
def entry(self): |
||||
return self._entry |
||||
|
||||
def append_post_entry(self, entry): |
||||
if self._n > 0: |
||||
self._post_stack.append(entry) |
||||
self._n -= 1 |
||||
|
||||
def get_deltas(self): |
||||
pre_and_post_stacks = itertools.chain(self._pre_stack, self._post_stack) |
||||
return collections.OrderedDict((stack_entry, |
||||
(self._entry.time - stack_entry.time)) |
||||
for stack_entry in pre_and_post_stacks) |
||||
|
||||
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) |
||||
|
||||
# Indexed by the mark's tag. Items in the value list correspond to the mark in |
||||
# different stack situations. |
||||
important_marks = collections.defaultdict(list) |
||||
|
||||
for entry in entries(): |
||||
thread = threads[entry.thread] |
||||
if entry.type == '{': |
||||
thread[entry.tag].append(entry) |
||||
if entry.type == '!': |
||||
# Save a snapshot of the current stack inside a new ImportantMark instance. |
||||
# Get all entries with type '{' from "thread". |
||||
stack = [e for entries_for_tag in thread.values() |
||||
for e in entries_for_tag if e.type == '{'] |
||||
important_marks[entry.tag].append(ImportantMark(entry, stack)) |
||||
elif entry.type == '}': |
||||
last = thread[entry.tag].pop() |
||||
times[entry.tag].append(entry.time - last.time) |
||||
# Update accounting for important marks. |
||||
for imarks_for_tag in important_marks.itervalues(): |
||||
for imark in imarks_for_tag: |
||||
imark.append_post_entry(entry) |
||||
|
||||
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)) |
||||
|
||||
print |
||||
print 'Important marks:' |
||||
print '================' |
||||
for tag, imark_for_tag in important_marks.iteritems(): |
||||
for imark in imarks_for_tag: |
||||
deltas = imark.get_deltas() |
||||
print '{tag} @ {file}:{line}'.format(**imark.entry._asdict()) |
||||
for entry, time_delta_us in deltas.iteritems(): |
||||
format_dict = entry._asdict() |
||||
format_dict['time_delta_us'] = time_delta_us |
||||
print '{tag} {type} ({file}:{line}): {time_delta_us:12.3f} us'.format( |
||||
**format_dict) |
||||
print |
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue