mirror of https://github.com/grpc/grpc.git
commit
f666adef90
59 changed files with 1898 additions and 656 deletions
@ -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,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 |
Loading…
Reference in new issue