basic pooling of requestcallcontext

pull/13521/head
Jan Tattermusch 7 years ago
parent ba89ad4065
commit e8b331305c
  1. 8
      src/csharp/Grpc.Core/Internal/CompletionRegistry.cs
  2. 2
      src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
  3. 3
      src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
  4. 1
      src/csharp/Grpc.Core/Server.cs
  5. 4
      src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs
  6. 2
      src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs

@ -37,14 +37,16 @@ namespace Grpc.Core.Internal
readonly GrpcEnvironment environment; readonly GrpcEnvironment environment;
readonly Func<BatchContextSafeHandle> batchContextFactory; readonly Func<BatchContextSafeHandle> batchContextFactory;
readonly Func<RequestCallContextSafeHandle> requestCallContextFactory;
readonly Dictionary<IntPtr, IOpCompletionCallback> dict = new Dictionary<IntPtr, IOpCompletionCallback>(new IntPtrComparer()); readonly Dictionary<IntPtr, IOpCompletionCallback> dict = new Dictionary<IntPtr, IOpCompletionCallback>(new IntPtrComparer());
SpinLock spinLock = new SpinLock(Debugger.IsAttached); SpinLock spinLock = new SpinLock(Debugger.IsAttached);
IntPtr lastRegisteredKey; // only for testing IntPtr lastRegisteredKey; // only for testing
public CompletionRegistry(GrpcEnvironment environment, Func<BatchContextSafeHandle> batchContextFactory) public CompletionRegistry(GrpcEnvironment environment, Func<BatchContextSafeHandle> batchContextFactory, Func<RequestCallContextSafeHandle> requestCallContextFactory)
{ {
this.environment = GrpcPreconditions.CheckNotNull(environment); this.environment = GrpcPreconditions.CheckNotNull(environment);
this.batchContextFactory = GrpcPreconditions.CheckNotNull(batchContextFactory); this.batchContextFactory = GrpcPreconditions.CheckNotNull(batchContextFactory);
this.requestCallContextFactory = GrpcPreconditions.CheckNotNull(requestCallContextFactory);
} }
public void Register(IntPtr key, IOpCompletionCallback callback) public void Register(IntPtr key, IOpCompletionCallback callback)
@ -73,10 +75,12 @@ namespace Grpc.Core.Internal
return ctx; return ctx;
} }
public void RegisterRequestCallCompletion(RequestCallContextSafeHandle ctx, RequestCallCompletionDelegate callback) public RequestCallContextSafeHandle RegisterRequestCallCompletion(RequestCallCompletionDelegate callback)
{ {
var ctx = requestCallContextFactory();
ctx.CompletionCallback = callback; ctx.CompletionCallback = callback;
Register(ctx.Handle, ctx); Register(ctx.Handle, ctx);
return ctx;
} }
public IOpCompletionCallback Extract(IntPtr key) public IOpCompletionCallback Extract(IntPtr key)

@ -219,7 +219,7 @@ namespace Grpc.Core.Internal
var list = new List<CompletionQueueSafeHandle>(); var list = new List<CompletionQueueSafeHandle>();
for (int i = 0; i < completionQueueCount; i++) for (int i = 0; i < completionQueueCount; i++)
{ {
var completionRegistry = new CompletionRegistry(environment, () => environment.BatchContextPool.Lease()); var completionRegistry = new CompletionRegistry(environment, () => environment.BatchContextPool.Lease(), () => RequestCallContextSafeHandle.Create());
list.Add(CompletionQueueSafeHandle.CreateAsync(completionRegistry)); list.Add(CompletionQueueSafeHandle.CreateAsync(completionRegistry));
} }
return list.AsReadOnly(); return list.AsReadOnly();

@ -75,8 +75,7 @@ namespace Grpc.Core.Internal
{ {
using (completionQueue.NewScope()) using (completionQueue.NewScope())
{ {
var ctx = RequestCallContextSafeHandle.Create(); var ctx = completionQueue.CompletionRegistry.RegisterRequestCallCompletion(callback);
completionQueue.CompletionRegistry.RegisterRequestCallCompletion(ctx, callback);
Native.grpcsharp_server_request_call(this, completionQueue, ctx).CheckOk(); Native.grpcsharp_server_request_call(this, completionQueue, ctx).CheckOk();
} }
} }

@ -300,6 +300,7 @@ namespace Grpc.Core
{ {
if (!shutdownRequested) if (!shutdownRequested)
{ {
// TODO(jtattermusch): avoid unnecessary delegate allocation
handle.RequestCall((success, ctx) => HandleNewServerRpc(success, ctx, cq), cq); handle.RequestCall((success, ctx) => HandleNewServerRpc(success, ctx, cq), cq);
} }
} }

@ -43,7 +43,7 @@ namespace Grpc.Microbenchmarks
public void Run(int threadCount, int iterations, bool useSharedRegistry) public void Run(int threadCount, int iterations, bool useSharedRegistry)
{ {
Console.WriteLine(string.Format("CompletionRegistryBenchmark: threads={0}, iterations={1}, useSharedRegistry={2}", threadCount, iterations, useSharedRegistry)); Console.WriteLine(string.Format("CompletionRegistryBenchmark: threads={0}, iterations={1}, useSharedRegistry={2}", threadCount, iterations, useSharedRegistry));
CompletionRegistry sharedRegistry = useSharedRegistry ? new CompletionRegistry(environment, () => BatchContextSafeHandle.Create()) : null; CompletionRegistry sharedRegistry = useSharedRegistry ? new CompletionRegistry(environment, () => BatchContextSafeHandle.Create(), () => RequestCallContextSafeHandle.Create()) : null;
var threadedBenchmark = new ThreadedBenchmark(threadCount, () => ThreadBody(iterations, sharedRegistry)); var threadedBenchmark = new ThreadedBenchmark(threadCount, () => ThreadBody(iterations, sharedRegistry));
threadedBenchmark.Run(); threadedBenchmark.Run();
// TODO: parametrize by number of pending completions // TODO: parametrize by number of pending completions
@ -51,7 +51,7 @@ namespace Grpc.Microbenchmarks
private void ThreadBody(int iterations, CompletionRegistry optionalSharedRegistry) private void ThreadBody(int iterations, CompletionRegistry optionalSharedRegistry)
{ {
var completionRegistry = optionalSharedRegistry ?? new CompletionRegistry(environment, () => BatchContextSafeHandle.Create()); var completionRegistry = optionalSharedRegistry ?? new CompletionRegistry(environment, () => BatchContextSafeHandle.Create(), () => RequestCallContextSafeHandle.Create());
var ctx = BatchContextSafeHandle.Create(); var ctx = BatchContextSafeHandle.Create();
var stopwatch = Stopwatch.StartNew(); var stopwatch = Stopwatch.StartNew();

@ -52,7 +52,7 @@ namespace Grpc.Microbenchmarks
private void ThreadBody(int iterations, int payloadSize) private void ThreadBody(int iterations, int payloadSize)
{ {
var completionRegistry = new CompletionRegistry(environment, () => environment.BatchContextPool.Lease()); var completionRegistry = new CompletionRegistry(environment, () => environment.BatchContextPool.Lease(), () => RequestCallContextSafeHandle.Create());
var cq = CompletionQueueSafeHandle.CreateAsync(completionRegistry); var cq = CompletionQueueSafeHandle.CreateAsync(completionRegistry);
var call = CreateFakeCall(cq); var call = CreateFakeCall(cq);

Loading…
Cancel
Save