enable requestCallContext pooling

pull/13521/head
Jan Tattermusch 7 years ago
parent fb6d01a30c
commit 36dfd7d363
  1. 28
      src/csharp/Grpc.Core/GrpcEnvironment.cs
  2. 2
      src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs

@ -35,6 +35,8 @@ namespace Grpc.Core
const int MinDefaultThreadPoolSize = 4;
const int DefaultBatchContextPoolSharedCapacity = 10000;
const int DefaultBatchContextPoolThreadLocalCapacity = 64;
const int DefaultRequestCallContextPoolSharedCapacity = 10000;
const int DefaultRequestCallContextPoolThreadLocalCapacity = 64;
static object staticLock = new object();
static GrpcEnvironment instance;
@ -44,12 +46,15 @@ namespace Grpc.Core
static bool inlineHandlers;
static int batchContextPoolSharedCapacity = DefaultBatchContextPoolSharedCapacity;
static int batchContextPoolThreadLocalCapacity = DefaultBatchContextPoolThreadLocalCapacity;
static int requestCallContextPoolSharedCapacity = DefaultRequestCallContextPoolSharedCapacity;
static int requestCallContextPoolThreadLocalCapacity = DefaultRequestCallContextPoolThreadLocalCapacity;
static readonly HashSet<Channel> registeredChannels = new HashSet<Channel>();
static readonly HashSet<Server> registeredServers = new HashSet<Server>();
static ILogger logger = new LogLevelFilterLogger(new ConsoleLogger(), LogLevel.Off, true);
readonly IObjectPool<BatchContextSafeHandle> batchContextPool;
readonly IObjectPool<RequestCallContextSafeHandle> requestCallContextPool;
readonly GrpcThreadPool threadPool;
readonly DebugStats debugStats = new DebugStats();
readonly AtomicCounter cqPickerCounter = new AtomicCounter();
@ -262,6 +267,26 @@ namespace Grpc.Core
}
}
/// <summary>
/// Sets the parameters for a pool that caches request call context instances. Reusing request call context instances
/// instead of creating a new one for every requested call in C core helps reducing the GC pressure.
/// Can be only invoked before the <c>GrpcEnviroment</c> is started and cannot be changed afterwards.
/// This is an advanced setting and you should only use it if you know what you are doing.
/// Most users should rely on the default value provided by gRPC library.
/// Note: this method is part of an experimental API that can change or be removed without any prior notice.
/// </summary>
public static void SetRequestCallContextPoolParams(int sharedCapacity, int threadLocalCapacity)
{
lock (staticLock)
{
GrpcPreconditions.CheckState(instance == null, "Can only be set before GrpcEnvironment is initialized");
GrpcPreconditions.CheckArgument(sharedCapacity >= 0, "Shared capacity needs to be a non-negative number");
GrpcPreconditions.CheckArgument(threadLocalCapacity >= 0, "Thread local capacity needs to be a non-negative number");
requestCallContextPoolSharedCapacity = sharedCapacity;
requestCallContextPoolThreadLocalCapacity = threadLocalCapacity;
}
}
/// <summary>
/// Occurs when <c>GrpcEnvironment</c> is about the start the shutdown logic.
/// If <c>GrpcEnvironment</c> is later initialized and shutdown, the event will be fired again (unless unregistered first).
@ -275,6 +300,7 @@ namespace Grpc.Core
{
GrpcNativeInit();
batchContextPool = new DefaultObjectPool<BatchContextSafeHandle>(() => BatchContextSafeHandle.Create(this.batchContextPool), batchContextPoolSharedCapacity, batchContextPoolThreadLocalCapacity);
requestCallContextPool = new DefaultObjectPool<RequestCallContextSafeHandle>(() => RequestCallContextSafeHandle.Create(this.requestCallContextPool), requestCallContextPoolSharedCapacity, requestCallContextPoolThreadLocalCapacity);
threadPool = new GrpcThreadPool(this, GetThreadPoolSizeOrDefault(), GetCompletionQueueCountOrDefault(), inlineHandlers);
threadPool.Start();
}
@ -292,6 +318,8 @@ namespace Grpc.Core
internal IObjectPool<BatchContextSafeHandle> BatchContextPool => batchContextPool;
internal IObjectPool<RequestCallContextSafeHandle> RequestCallContextPool => requestCallContextPool;
internal bool IsAlive
{
get

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

Loading…
Cancel
Save