Added pooling to locking to reduce memory allocations; ConfigureAwait(false) (#542)

This commit is contained in:
Mark Cilia Vincenti 2024-07-05 21:39:01 +02:00 коммит произвёл GitHub
Родитель 15419b3b93
Коммит fac43d09bd
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
22 изменённых файлов: 57 добавлений и 42 удалений

Просмотреть файл

@ -80,7 +80,7 @@ file sealed class TryParseApiNameHandler(ManagementServiceDirectory serviceDirec
/// </summary>
file sealed class ApiSemaphore : IDisposable
{
private readonly AsyncKeyedLocker<ApiName> locker = new();
private readonly AsyncKeyedLocker<ApiName> locker = new(LockOptions.Default);
private ImmutableHashSet<ApiName> processedNames = [];
/// <summary>
@ -89,7 +89,7 @@ file sealed class ApiSemaphore : IDisposable
public async ValueTask Run(ApiName name, Func<ApiName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync(name, cancellationToken);
using var _ = await locker.LockAsync(name, cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains(name))

Просмотреть файл

@ -56,7 +56,7 @@ file sealed class TryParseApiOperationPolicyNameHandler(ManagementServiceDirecto
/// </summary>
file sealed class ApiOperationPolicySemaphore : IDisposable
{
private readonly AsyncKeyedLocker<(ApiOperationPolicyName, ApiOperationName, ApiName)> locker = new();
private readonly AsyncKeyedLocker<(ApiOperationPolicyName, ApiOperationName, ApiName)> locker = new(LockOptions.Default);
private ImmutableHashSet<(ApiOperationPolicyName, ApiOperationName, ApiName)> processedNames = [];
/// <summary>
@ -65,7 +65,7 @@ file sealed class ApiOperationPolicySemaphore : IDisposable
public async ValueTask Run(ApiOperationPolicyName name, ApiOperationName apiOperationName, ApiName apiName, Func<ApiOperationPolicyName, ApiOperationName, ApiName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync((name, apiOperationName, apiName), cancellationToken);
using var _ = await locker.LockAsync((name, apiOperationName, apiName), cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains((name, apiOperationName, apiName)))

Просмотреть файл

@ -56,7 +56,7 @@ file sealed class TryParseApiPolicyNameHandler(ManagementServiceDirectory servic
/// </summary>
file sealed class ApiPolicySemaphore : IDisposable
{
private readonly AsyncKeyedLocker<(ApiPolicyName, ApiName)> locker = new();
private readonly AsyncKeyedLocker<(ApiPolicyName, ApiName)> locker = new(LockOptions.Default);
private ImmutableHashSet<(ApiPolicyName, ApiName)> processedNames = [];
/// <summary>
@ -65,7 +65,7 @@ file sealed class ApiPolicySemaphore : IDisposable
public async ValueTask Run(ApiPolicyName name, ApiName apiName, Func<ApiPolicyName, ApiName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync((name, apiName), cancellationToken);
using var _ = await locker.LockAsync((name, apiName), cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains((name, apiName)))

Просмотреть файл

@ -56,7 +56,7 @@ file sealed class TryParseTagNameHandler(ManagementServiceDirectory serviceDirec
/// </summary>
file sealed class ApiTagSemaphore : IDisposable
{
private readonly AsyncKeyedLocker<(TagName, ApiName)> locker = new();
private readonly AsyncKeyedLocker<(TagName, ApiName)> locker = new(LockOptions.Default);
private ImmutableHashSet<(TagName, ApiName)> processedNames = [];
/// <summary>
@ -65,7 +65,7 @@ file sealed class ApiTagSemaphore : IDisposable
public async ValueTask Run(TagName name, ApiName apiName, Func<TagName, ApiName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync((name, apiName), cancellationToken);
using var _ = await locker.LockAsync((name, apiName), cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains((name, apiName)))

Просмотреть файл

@ -82,7 +82,7 @@ file sealed class TryParseBackendNameHandler(ManagementServiceDirectory serviceD
/// </summary>
file sealed class BackendSemaphore : IDisposable
{
private readonly AsyncKeyedLocker<BackendName> locker = new();
private readonly AsyncKeyedLocker<BackendName> locker = new(LockOptions.Default);
private ImmutableHashSet<BackendName> processedNames = [];
/// <summary>
@ -91,7 +91,7 @@ file sealed class BackendSemaphore : IDisposable
public async ValueTask Run(BackendName name, Func<BackendName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync(name, cancellationToken);
using var _ = await locker.LockAsync(name, cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains(name))

Просмотреть файл

@ -61,7 +61,7 @@ file sealed class TryParseDiagnosticNameHandler(ManagementServiceDirectory servi
/// </summary>
file sealed class DiagnosticSemaphore : IDisposable
{
private readonly AsyncKeyedLocker<DiagnosticName> locker = new();
private readonly AsyncKeyedLocker<DiagnosticName> locker = new(LockOptions.Default);
private ImmutableHashSet<DiagnosticName> processedNames = [];
/// <summary>
@ -70,7 +70,7 @@ file sealed class DiagnosticSemaphore : IDisposable
public async ValueTask Run(DiagnosticName name, Func<DiagnosticName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync(name, cancellationToken);
using var _ = await locker.LockAsync(name, cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains(name))

Просмотреть файл

@ -59,7 +59,7 @@ file sealed class TryParseGatewayNameHandler(ManagementServiceDirectory serviceD
/// </summary>
file sealed class GatewaySemaphore : IDisposable
{
private readonly AsyncKeyedLocker<GatewayName> locker = new();
private readonly AsyncKeyedLocker<GatewayName> locker = new(LockOptions.Default);
private ImmutableHashSet<GatewayName> processedNames = [];
/// <summary>
@ -68,7 +68,7 @@ file sealed class GatewaySemaphore : IDisposable
public async ValueTask Run(GatewayName name, Func<GatewayName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync(name, cancellationToken);
using var _ = await locker.LockAsync(name, cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains(name))

Просмотреть файл

@ -56,7 +56,7 @@ file sealed class TryParseApiNameHandler(ManagementServiceDirectory serviceDirec
/// </summary>
file sealed class GatewayApiSemaphore : IDisposable
{
private readonly AsyncKeyedLocker<(ApiName, GatewayName)> locker = new();
private readonly AsyncKeyedLocker<(ApiName, GatewayName)> locker = new(LockOptions.Default);
private ImmutableHashSet<(ApiName, GatewayName)> processedNames = [];
/// <summary>
@ -65,7 +65,7 @@ file sealed class GatewayApiSemaphore : IDisposable
public async ValueTask Run(ApiName name, GatewayName gatewayName, Func<ApiName, GatewayName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync((name, gatewayName), cancellationToken);
using var _ = await locker.LockAsync((name, gatewayName), cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains((name, gatewayName)))

Просмотреть файл

@ -59,7 +59,7 @@ file sealed class TryParseGroupNameHandler(ManagementServiceDirectory serviceDir
/// </summary>
file sealed class GroupSemaphore : IDisposable
{
private readonly AsyncKeyedLocker<GroupName> locker = new();
private readonly AsyncKeyedLocker<GroupName> locker = new(LockOptions.Default);
private ImmutableHashSet<GroupName> processedNames = [];
/// <summary>
@ -68,7 +68,7 @@ file sealed class GroupSemaphore : IDisposable
public async ValueTask Run(GroupName name, Func<GroupName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync(name, cancellationToken);
using var _ = await locker.LockAsync(name, cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains(name))

Просмотреть файл

@ -0,0 +1,15 @@
using AsyncKeyedLock;
namespace publisher
{
internal static class LockOptions
{
private readonly static AsyncKeyedLockOptions defaultOptions = new()
{
PoolSize = 20,
PoolInitialFill = 1
};
internal static AsyncKeyedLockOptions Default => defaultOptions;
}
}

Просмотреть файл

@ -59,7 +59,7 @@ file sealed class TryParseLoggerNameHandler(ManagementServiceDirectory serviceDi
/// </summary>
file sealed class LoggerSemaphore : IDisposable
{
private readonly AsyncKeyedLocker<LoggerName> locker = new();
private readonly AsyncKeyedLocker<LoggerName> locker = new(LockOptions.Default);
private ImmutableHashSet<LoggerName> processedNames = [];
/// <summary>
@ -68,7 +68,7 @@ file sealed class LoggerSemaphore : IDisposable
public async ValueTask Run(LoggerName name, Func<LoggerName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync(name, cancellationToken);
using var _ = await locker.LockAsync(name, cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains(name))

Просмотреть файл

@ -104,7 +104,7 @@ file sealed class PutNamedValueHandler(FindNamedValueDto findDto, PutNamedValueI
/// </summary>
file sealed class NamedValueSemaphore : IDisposable
{
private readonly AsyncKeyedLocker<NamedValueName> locker = new();
private readonly AsyncKeyedLocker<NamedValueName> locker = new(LockOptions.Default);
private ImmutableHashSet<NamedValueName> processedNames = [];
/// <summary>
@ -113,7 +113,7 @@ file sealed class NamedValueSemaphore : IDisposable
public async ValueTask Run(NamedValueName name, Func<NamedValueName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync(name, cancellationToken);
using var _ = await locker.LockAsync(name, cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains(name))

Просмотреть файл

@ -92,7 +92,7 @@ file sealed class TryParsePolicyFragmentNameHandler(ManagementServiceDirectory s
/// </summary>
file sealed class PolicyFragmentSemaphore : IDisposable
{
private readonly AsyncKeyedLocker<PolicyFragmentName> locker = new();
private readonly AsyncKeyedLocker<PolicyFragmentName> locker = new(LockOptions.Default);
private ImmutableHashSet<PolicyFragmentName> processedNames = [];
/// <summary>
@ -101,7 +101,7 @@ file sealed class PolicyFragmentSemaphore : IDisposable
public async ValueTask Run(PolicyFragmentName name, Func<PolicyFragmentName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync(name, cancellationToken);
using var _ = await locker.LockAsync(name, cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains(name))

Просмотреть файл

@ -60,7 +60,7 @@ file sealed class TryParseProductNameHandler(ManagementServiceDirectory serviceD
/// </summary>
file sealed class ProductSemaphore : IDisposable
{
private readonly AsyncKeyedLocker<ProductName> locker = new();
private readonly AsyncKeyedLocker<ProductName> locker = new(LockOptions.Default);
private ImmutableHashSet<ProductName> processedNames = [];
/// <summary>
@ -69,7 +69,7 @@ file sealed class ProductSemaphore : IDisposable
public async ValueTask Run(ProductName name, Func<ProductName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync(name, cancellationToken);
using var _ = await locker.LockAsync(name, cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains(name))

Просмотреть файл

@ -56,7 +56,7 @@ file sealed class TryParseApiNameHandler(ManagementServiceDirectory serviceDirec
/// </summary>
file sealed class ProductApiSemaphore : IDisposable
{
private readonly AsyncKeyedLocker<(ApiName, ProductName)> locker = new();
private readonly AsyncKeyedLocker<(ApiName, ProductName)> locker = new(LockOptions.Default);
private ImmutableHashSet<(ApiName, ProductName)> processedNames = [];
/// <summary>
@ -65,7 +65,7 @@ file sealed class ProductApiSemaphore : IDisposable
public async ValueTask Run(ApiName name, ProductName productName, Func<ApiName, ProductName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync((name, productName), cancellationToken);
using var _ = await locker.LockAsync((name, productName), cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains((name, productName)))

Просмотреть файл

@ -56,7 +56,7 @@ file sealed class TryParseGroupNameHandler(ManagementServiceDirectory serviceDir
/// </summary>
file sealed class ProductGroupSemaphore : IDisposable
{
private readonly AsyncKeyedLocker<(GroupName, ProductName)> locker = new();
private readonly AsyncKeyedLocker<(GroupName, ProductName)> locker = new(LockOptions.Default);
private ImmutableHashSet<(GroupName, ProductName)> processedNames = [];
/// <summary>
@ -65,7 +65,7 @@ file sealed class ProductGroupSemaphore : IDisposable
public async ValueTask Run(GroupName name, ProductName productName, Func<GroupName, ProductName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync((name, productName), cancellationToken);
using var _ = await locker.LockAsync((name, productName), cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains((name, productName)))

Просмотреть файл

@ -56,7 +56,7 @@ file sealed class TryParseProductPolicyNameHandler(ManagementServiceDirectory se
/// </summary>
file sealed class ProductPolicySemaphore : IDisposable
{
private readonly AsyncKeyedLocker<(ProductPolicyName, ProductName)> locker = new();
private readonly AsyncKeyedLocker<(ProductPolicyName, ProductName)> locker = new(LockOptions.Default);
private ImmutableHashSet<(ProductPolicyName, ProductName)> processedNames = [];
/// <summary>
@ -65,7 +65,7 @@ file sealed class ProductPolicySemaphore : IDisposable
public async ValueTask Run(ProductPolicyName name, ProductName productName, Func<ProductPolicyName, ProductName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync((name, productName), cancellationToken);
using var _ = await locker.LockAsync((name, productName), cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains((name, productName)))

Просмотреть файл

@ -56,7 +56,7 @@ file sealed class TryParseTagNameHandler(ManagementServiceDirectory serviceDirec
/// </summary>
file sealed class ProductTagSemaphore : IDisposable
{
private readonly AsyncKeyedLocker<(TagName, ProductName)> locker = new();
private readonly AsyncKeyedLocker<(TagName, ProductName)> locker = new(LockOptions.Default);
private ImmutableHashSet<(TagName, ProductName)> processedNames = [];
/// <summary>
@ -65,7 +65,7 @@ file sealed class ProductTagSemaphore : IDisposable
public async ValueTask Run(TagName name, ProductName productName, Func<TagName, ProductName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync((name, productName), cancellationToken);
using var _ = await locker.LockAsync((name, productName), cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains((name, productName)))

Просмотреть файл

@ -56,7 +56,7 @@ file sealed class TryParseServicePolicyNameHandler(ManagementServiceDirectory se
/// </summary>
file sealed class ServicePolicySemaphore : IDisposable
{
private readonly AsyncKeyedLocker<ServicePolicyName> locker = new();
private readonly AsyncKeyedLocker<ServicePolicyName> locker = new(LockOptions.Default);
private ImmutableHashSet<ServicePolicyName> processedNames = [];
/// <summary>
@ -65,7 +65,7 @@ file sealed class ServicePolicySemaphore : IDisposable
public async ValueTask Run(ServicePolicyName name, Func<ServicePolicyName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync(name, cancellationToken);
using var _ = await locker.LockAsync(name, cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains(name))

Просмотреть файл

@ -61,7 +61,7 @@ file sealed class TryParseSubscriptionNameHandler(ManagementServiceDirectory ser
/// </summary>
file sealed class SubscriptionSemaphore : IDisposable
{
private readonly AsyncKeyedLocker<SubscriptionName> locker = new();
private readonly AsyncKeyedLocker<SubscriptionName> locker = new(LockOptions.Default);
private ImmutableHashSet<SubscriptionName> processedNames = [];
/// <summary>
@ -70,7 +70,7 @@ file sealed class SubscriptionSemaphore : IDisposable
public async ValueTask Run(SubscriptionName name, Func<SubscriptionName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync(name, cancellationToken);
using var _ = await locker.LockAsync(name, cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains(name))

Просмотреть файл

@ -59,7 +59,7 @@ file sealed class TryParseTagNameHandler(ManagementServiceDirectory serviceDirec
/// </summary>
file sealed class TagSemaphore : IDisposable
{
private readonly AsyncKeyedLocker<TagName> locker = new();
private readonly AsyncKeyedLocker<TagName> locker = new(LockOptions.Default);
private ImmutableHashSet<TagName> processedNames = [];
/// <summary>
@ -68,7 +68,7 @@ file sealed class TagSemaphore : IDisposable
public async ValueTask Run(TagName name, Func<TagName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync(name, cancellationToken);
using var _ = await locker.LockAsync(name, cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains(name))

Просмотреть файл

@ -59,7 +59,7 @@ file sealed class TryParseVersionSetNameHandler(ManagementServiceDirectory servi
/// </summary>
file sealed class VersionSetSemaphore : IDisposable
{
private readonly AsyncKeyedLocker<VersionSetName> locker = new();
private readonly AsyncKeyedLocker<VersionSetName> locker = new(LockOptions.Default);
private ImmutableHashSet<VersionSetName> processedNames = [];
/// <summary>
@ -68,7 +68,7 @@ file sealed class VersionSetSemaphore : IDisposable
public async ValueTask Run(VersionSetName name, Func<VersionSetName, CancellationToken, ValueTask> action, CancellationToken cancellationToken)
{
// Do not process the same name simultaneously
using var _ = await locker.LockAsync(name, cancellationToken);
using var _ = await locker.LockAsync(name, cancellationToken).ConfigureAwait(false);
// Only process each name once
if (processedNames.Contains(name))