Renaming for clarification / project conformity
This commit is contained in:
parent
8a9e00d92d
commit
3fa7a06310
|
|
@ -38,7 +38,7 @@ services
|
|||
identity.UseConfigurationBasedRoleProvider(options => identitySection.Bind(options));
|
||||
})
|
||||
.UseDefaultAuthentication()
|
||||
.UseInstanceManagement(x => x.HeartbeatSettings = settings => heartbeatSection.Bind(settings));
|
||||
.UseInstanceManagement(x => x.HeartbeatOptions = settings => heartbeatSection.Bind(settings))
|
||||
.UseWorkflowManagement(management => management.UseEntityFrameworkCore(ef => ef.UseSqlite(sqliteConnectionString)))
|
||||
.UseWorkflowRuntime(runtime =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -63,10 +63,10 @@
|
|||
},
|
||||
"Heartbeat": {
|
||||
"InstanceHeartbeatRhythm": "00:00:01:00",
|
||||
"InstanceDeactivatedPeriod": "00:00:05:00",
|
||||
"HeartbeatTimeoutPeriod": "00:00:05:00",
|
||||
},
|
||||
"MassTransit": {
|
||||
"ShortTermQueueLifetime": "00:00:05:00"
|
||||
"TemporaryQueueTtl": "00:00:05:00"
|
||||
},
|
||||
"Smtp": {
|
||||
"Host": "localhost",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
namespace Elsa.Hosting.Management.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// Provides a name of the current application instance.
|
||||
/// </summary>
|
||||
public interface IApplicationInstanceNameProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns a name for the instance.
|
||||
/// </summary>
|
||||
public string GetName();
|
||||
}
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
using Elsa.Features.Abstractions;
|
||||
using Elsa.Features.Services;
|
||||
using Elsa.Hosting.Management.Contracts;
|
||||
using Elsa.Hosting.Management.HostedServices;
|
||||
using Elsa.Hosting.Management.Options;
|
||||
using Elsa.Hosting.Management.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Elsa.Hosting.Management.Features;
|
||||
|
|
@ -15,17 +17,29 @@ public class InstanceManagementFeature : FeatureBase
|
|||
public InstanceManagementFeature(IModule module) : base(module)
|
||||
{
|
||||
}
|
||||
|
||||
public Action<HeartbeatSettings> HeartbeatSettings { get; set; } = _ => { };
|
||||
|
||||
/// <summary>
|
||||
/// A factory that instantiates an <see cref="IApplicationInstanceNameProvider"/>.
|
||||
/// </summary>
|
||||
public Func<IServiceProvider, IApplicationInstanceNameProvider> InstanceNameProvider { get; set; } = sp =>
|
||||
ActivatorUtilities.CreateInstance<RandomApplicationInstanceNameProvider>(sp);
|
||||
|
||||
/// <summary>
|
||||
/// Represents the options for heartbeat feature.
|
||||
/// </summary>
|
||||
public Action<HeartbeatOptions> HeartbeatOptions { get; set; } = _ => { };
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void ConfigureHostedServices()
|
||||
{
|
||||
Module.ConfigureHostedService<InstanceHeartbeatService>();
|
||||
Module.ConfigureHostedService<InstanceHeartbeatMonitorService>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Apply()
|
||||
{
|
||||
Services.Configure(HeartbeatSettings);
|
||||
Services.Configure(HeartbeatOptions)
|
||||
.AddSingleton(InstanceNameProvider);
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ using Elsa.Workflows.Runtime.Models;
|
|||
using Medallion.Threading;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Internal;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Elsa.Hosting.Management.HostedServices;
|
||||
|
|
@ -16,21 +17,24 @@ namespace Elsa.Hosting.Management.HostedServices;
|
|||
public class InstanceHeartbeatMonitorService : IHostedService, IDisposable
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly HeartbeatSettings _heartbeatSettings;
|
||||
private readonly ISystemClock _systemClock;
|
||||
private readonly HeartbeatOptions _heartbeatOptions;
|
||||
private Timer? _timer;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="InstanceHeartbeatService"/>
|
||||
/// Creates a new instance of the <see cref="InstanceHeartbeatMonitorService"/>
|
||||
/// </summary>
|
||||
public InstanceHeartbeatMonitorService(IServiceProvider serviceProvider, IOptions<HeartbeatSettings> heartbeatSettings)
|
||||
public InstanceHeartbeatMonitorService(IServiceProvider serviceProvider, ISystemClock systemClock,
|
||||
IOptions<HeartbeatOptions> heartbeatOptions)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
_heartbeatSettings = heartbeatSettings.Value;
|
||||
_systemClock = systemClock;
|
||||
_heartbeatOptions = heartbeatOptions.Value;
|
||||
}
|
||||
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_timer = new Timer(MonitorHeartbeats, null, TimeSpan.Zero, _heartbeatSettings.InstanceHeartbeatRhythm);
|
||||
_timer = new Timer(MonitorHeartbeats, null, TimeSpan.Zero, _heartbeatOptions.InstanceHeartbeatRhythm);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
|
@ -49,32 +53,36 @@ public class InstanceHeartbeatMonitorService : IHostedService, IDisposable
|
|||
{
|
||||
_ = Task.Run(async () => await MonitorHeartbeatsAsync());
|
||||
}
|
||||
|
||||
|
||||
private async Task MonitorHeartbeatsAsync()
|
||||
{
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
|
||||
|
||||
var lockProvider = scope.ServiceProvider.GetRequiredService<IDistributedLockProvider>();
|
||||
var store = scope.ServiceProvider.GetRequiredService<IKeyValueStore>();
|
||||
var notificationSender = scope.ServiceProvider.GetRequiredService<INotificationSender>();
|
||||
|
||||
|
||||
var lockKey = "InstanceHeartbeatMonitorService";
|
||||
await using var monitorLock = await lockProvider.TryAcquireLockAsync(lockKey, TimeSpan.Zero);
|
||||
if (monitorLock == null)
|
||||
return;
|
||||
|
||||
var filter = new KeyValueFilter { StartsWith = true, Key = InstanceHeartbeatService.HeartbeatKeyPrefix };
|
||||
|
||||
var filter = new KeyValueFilter
|
||||
{
|
||||
StartsWith = true,
|
||||
Key = InstanceHeartbeatService.HeartbeatKeyPrefix
|
||||
};
|
||||
var heartbeats = await store.FindManyAsync(filter, default);
|
||||
|
||||
foreach (var heartbeat in heartbeats)
|
||||
{
|
||||
var lastHeartbeat = DateTimeOffset.Parse(heartbeat.SerializedValue).UtcDateTime;
|
||||
|
||||
if (DateTime.UtcNow - lastHeartbeat <= _heartbeatSettings.InstanceDeactivatedPeriod)
|
||||
if (_systemClock.UtcNow - lastHeartbeat <= _heartbeatOptions.HeartbeatTimeoutPeriod)
|
||||
continue;
|
||||
|
||||
var instanceName = heartbeat.Key.Substring(InstanceHeartbeatService.HeartbeatKeyPrefix.Length);
|
||||
await notificationSender.SendAsync(new InstanceDeactivated(instanceName));
|
||||
await notificationSender.SendAsync(new HeartbeatTimedOut(instanceName));
|
||||
|
||||
await store.DeleteAsync(heartbeat.Key, default);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using Elsa.Hosting.Management.Contracts;
|
||||
using Elsa.Hosting.Management.Options;
|
||||
using Elsa.Workflows.Contracts;
|
||||
using Elsa.Workflows.Runtime.Contracts;
|
||||
using Elsa.Workflows.Runtime.Entities;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
|
@ -14,22 +14,23 @@ namespace Elsa.Hosting.Management.HostedServices;
|
|||
public class InstanceHeartbeatService : IHostedService, IDisposable
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly HeartbeatSettings _heartbeatSettings;
|
||||
private readonly HeartbeatOptions _heartbeatOptions;
|
||||
private Timer? _timer;
|
||||
|
||||
internal static string HeartbeatKeyPrefix = "Heartbeat_";
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="InstanceHeartbeatService"/>
|
||||
/// </summary>
|
||||
public InstanceHeartbeatService(IServiceProvider serviceProvider, IOptions<HeartbeatSettings> heartbeatSettings)
|
||||
public InstanceHeartbeatService(IServiceProvider serviceProvider, IOptions<HeartbeatOptions> heartbeatOptions)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
_heartbeatSettings = heartbeatSettings.Value;
|
||||
_heartbeatOptions = heartbeatOptions.Value;
|
||||
}
|
||||
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_timer = new Timer(WriteHeartbeat, null, TimeSpan.Zero, _heartbeatSettings.InstanceHeartbeatRhythm);
|
||||
_timer = new Timer(WriteHeartbeat, null, TimeSpan.Zero, _heartbeatOptions.InstanceHeartbeatRhythm);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
|
@ -48,17 +49,17 @@ public class InstanceHeartbeatService : IHostedService, IDisposable
|
|||
{
|
||||
_ = Task.Run(async () => await WriteHeartbeatAsync());
|
||||
}
|
||||
|
||||
|
||||
private async Task WriteHeartbeatAsync()
|
||||
{
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
|
||||
var instanceNameRetriever = scope.ServiceProvider.GetRequiredService<IInstanceNameRetriever>();
|
||||
|
||||
var instanceNameProvider = scope.ServiceProvider.GetRequiredService<IApplicationInstanceNameProvider>();
|
||||
var store = scope.ServiceProvider.GetRequiredService<IKeyValueStore>();
|
||||
|
||||
|
||||
await store.SaveAsync(new SerializedKeyValuePair
|
||||
{
|
||||
Key = $"{HeartbeatKeyPrefix}{instanceNameRetriever.GetName()}",
|
||||
Key = $"{HeartbeatKeyPrefix}{instanceNameProvider.GetName()}",
|
||||
SerializedValue = DateTime.UtcNow.ToString("o")
|
||||
},
|
||||
default);
|
||||
|
|
|
|||
|
|
@ -2,4 +2,4 @@ using Elsa.Mediator.Contracts;
|
|||
|
||||
namespace Elsa.Hosting.Management.Notifications;
|
||||
|
||||
public record InstanceDeactivated(string InstanceName) : INotification;
|
||||
public record HeartbeatTimedOut(string InstanceName) : INotification;
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
namespace Elsa.Hosting.Management.Options;
|
||||
|
||||
public class HeartbeatSettings
|
||||
public class HeartbeatOptions
|
||||
{
|
||||
public TimeSpan InstanceHeartbeatRhythm { get; set; } = TimeSpan.FromMinutes(1);
|
||||
public TimeSpan InstanceDeactivatedPeriod { get; set; } = TimeSpan.FromHours(1);
|
||||
public TimeSpan HeartbeatTimeoutPeriod { get; set; } = TimeSpan.FromHours(1);
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
using Elsa.Hosting.Management.Contracts;
|
||||
using Elsa.Workflows.Services;
|
||||
|
||||
namespace Elsa.Hosting.Management.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Returns a randomly generated instance name.
|
||||
/// </summary>
|
||||
public class RandomApplicationInstanceNameProvider : IApplicationInstanceNameProvider
|
||||
{
|
||||
private readonly string _instanceName;
|
||||
|
||||
public RandomApplicationInstanceNameProvider(RandomLongIdentityGenerator identityGenerator)
|
||||
{
|
||||
_instanceName = identityGenerator.GenerateId();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetName() => _instanceName;
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ using Elsa.Extensions;
|
|||
using Elsa.Features.Abstractions;
|
||||
using Elsa.Features.Attributes;
|
||||
using Elsa.Features.Services;
|
||||
using Elsa.Hosting.Management.Contracts;
|
||||
using Elsa.MassTransit.AzureServiceBus.Handlers;
|
||||
using Elsa.MassTransit.AzureServiceBus.Models;
|
||||
using Elsa.MassTransit.AzureServiceBus.Options;
|
||||
|
|
@ -10,7 +11,6 @@ using Elsa.MassTransit.AzureServiceBus.Services;
|
|||
using Elsa.MassTransit.Features;
|
||||
using Elsa.MassTransit.Models;
|
||||
using Elsa.MassTransit.Options;
|
||||
using Elsa.Workflows.Contracts;
|
||||
using MassTransit;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
|
@ -54,29 +54,29 @@ public class AzureServiceBusFeature : FeatureBase
|
|||
massTransitFeature.BusConfigurator = configure =>
|
||||
{
|
||||
var consumers = massTransitFeature.GetConsumers().ToList();
|
||||
var shortLivedConsumers = consumers
|
||||
.Where(c => c.IsShortLived)
|
||||
var temporaryConsumers = consumers
|
||||
.Where(c => c.IsTemporary)
|
||||
.ToList();
|
||||
RegisterConsumers(consumers);
|
||||
|
||||
configure.AddServiceBusMessageScheduler();
|
||||
configure.AddConsumers(shortLivedConsumers.Select(c => c.ConsumerType).ToArray());
|
||||
configure.AddConsumers(temporaryConsumers.Select(c => c.ConsumerType).ToArray());
|
||||
|
||||
configure.UsingAzureServiceBus((context, serviceBus) =>
|
||||
{
|
||||
var options = context.GetRequiredService<IOptions<MassTransitWorkflowDispatcherOptions>>().Value;
|
||||
var instanceNameRetriever = context.GetRequiredService<IInstanceNameRetriever>();
|
||||
var instanceNameProvider = context.GetRequiredService<IApplicationInstanceNameProvider>();
|
||||
|
||||
if (ConnectionString != null)
|
||||
serviceBus.Host(ConnectionString);
|
||||
serviceBus.UseServiceBusMessageScheduler();
|
||||
ConfigureServiceBus?.Invoke(serviceBus);
|
||||
|
||||
foreach (var consumer in shortLivedConsumers)
|
||||
foreach (var consumer in temporaryConsumers)
|
||||
{
|
||||
serviceBus.ReceiveEndpoint($"Elsa-{instanceNameRetriever.GetName()}-{consumer.Name}", configurator =>
|
||||
serviceBus.ReceiveEndpoint($"Elsa-{instanceNameProvider.GetName()}-{consumer.Name}", configurator =>
|
||||
{
|
||||
configurator.AutoDeleteOnIdle = options.ShortTermQueueLifetime ?? TimeSpan.FromHours(1);
|
||||
configurator.AutoDeleteOnIdle = options.TemporaryQueueTtl ?? TimeSpan.FromHours(1);
|
||||
configurator.ConcurrentMessageLimit = options.ConcurrentMessageLimit;
|
||||
configurator.ConfigureConsumer(context, consumer.ConsumerType);
|
||||
});
|
||||
|
|
@ -109,7 +109,7 @@ public class AzureServiceBusFeature : FeatureBase
|
|||
|
||||
subscriptionTopology.Add(new MessageSubscriptionTopology(topicName,
|
||||
consumer.Name ?? genericType.Name.ToLower(),
|
||||
consumer.IsShortLived));
|
||||
consumer.IsTemporary));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,14 +11,14 @@ namespace Elsa.MassTransit.AzureServiceBus.Handlers;
|
|||
public class OrphanedSubscriptionRemover(
|
||||
MessageTopologyProvider topologyProvider,
|
||||
ServiceBusAdministrationClient client)
|
||||
: INotificationHandler<InstanceDeactivated>
|
||||
: INotificationHandler<HeartbeatTimedOut>
|
||||
{
|
||||
/// <summary>
|
||||
/// Removes orphaned subscriptions from Azure Service Bus.
|
||||
/// </summary>
|
||||
public async Task HandleAsync(InstanceDeactivated notification, CancellationToken cancellationToken)
|
||||
public async Task HandleAsync(HeartbeatTimedOut notification, CancellationToken cancellationToken)
|
||||
{
|
||||
var subscriptionTopology = topologyProvider.GetShortLivedSubscriptions().ToList();
|
||||
var subscriptionTopology = topologyProvider.GetTemporarySubscriptions().ToList();
|
||||
|
||||
foreach (var subscription in subscriptionTopology)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@ namespace Elsa.MassTransit.AzureServiceBus.Models;
|
|||
/// <summary>
|
||||
/// Represents the topology of a message subscription in Azure Service Bus.
|
||||
/// </summary>
|
||||
public record MessageSubscriptionTopology(string TopicName, string SubscriptionName, bool IsShortLived);
|
||||
public record MessageSubscriptionTopology(string TopicName, string SubscriptionName, bool IsTemporary);
|
||||
|
|
@ -18,10 +18,10 @@ public class MessageTopologyProvider
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves all the short-lived message subscriptions from the subscription topology.
|
||||
/// Retrieves all the temporary message subscriptions from the subscription topology.
|
||||
/// </summary>
|
||||
public IEnumerable<MessageSubscriptionTopology> GetShortLivedSubscriptions()
|
||||
public IEnumerable<MessageSubscriptionTopology> GetTemporarySubscriptions()
|
||||
{
|
||||
return _subscriptionTopology.Where(x => x.IsShortLived);
|
||||
return _subscriptionTopology.Where(x => x.IsTemporary);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Elsa.Hosting.Management\Elsa.Hosting.Management.csproj" />
|
||||
<ProjectReference Include="..\Elsa.MassTransit\Elsa.MassTransit.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ using Elsa.Extensions;
|
|||
using Elsa.Features.Abstractions;
|
||||
using Elsa.Features.Attributes;
|
||||
using Elsa.Features.Services;
|
||||
using Elsa.Hosting.Management.Contracts;
|
||||
using Elsa.MassTransit.Consumers;
|
||||
using Elsa.MassTransit.Features;
|
||||
using Elsa.MassTransit.Options;
|
||||
using Elsa.Workflows.Contracts;
|
||||
using MassTransit;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
|
@ -28,7 +28,7 @@ public class RabbitMqServiceBusFeature : FeatureBase
|
|||
|
||||
/// Configures the RabbitMQ transport options.
|
||||
public Action<RabbitMqTransportOptions>? TransportOptions { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Configures the RabbitMQ bus.
|
||||
/// </summary>
|
||||
|
|
@ -42,26 +42,26 @@ public class RabbitMqServiceBusFeature : FeatureBase
|
|||
massTransitFeature.BusConfigurator = configure =>
|
||||
{
|
||||
var tempConsumers = massTransitFeature.GetConsumers()
|
||||
.Where(c => c.IsShortLived)
|
||||
.Where(c => c.IsTemporary)
|
||||
.ToList();
|
||||
|
||||
|
||||
configure.AddConsumers(tempConsumers.Select(c => c.ConsumerType).ToArray());
|
||||
|
||||
|
||||
configure.UsingRabbitMq((context, serviceBus) =>
|
||||
{
|
||||
var options = context.GetRequiredService<IOptions<MassTransitWorkflowDispatcherOptions>>().Value;
|
||||
var instanceNameRetriever = context.GetRequiredService<IInstanceNameRetriever>();
|
||||
|
||||
var instanceNameProvider = context.GetRequiredService<IApplicationInstanceNameProvider>();
|
||||
|
||||
if (!string.IsNullOrEmpty(ConnectionString))
|
||||
serviceBus.Host(ConnectionString);
|
||||
|
||||
ConfigureServiceBus?.Invoke(serviceBus);
|
||||
|
||||
|
||||
foreach (var consumer in tempConsumers)
|
||||
{
|
||||
serviceBus.ReceiveEndpoint($"{instanceNameRetriever.GetName()}-{consumer.Name}", configurator =>
|
||||
serviceBus.ReceiveEndpoint($"{instanceNameProvider.GetName()}-{consumer.Name}", configurator =>
|
||||
{
|
||||
configurator.QueueExpiration = options.ShortTermQueueLifetime ?? TimeSpan.FromHours(1);
|
||||
configurator.QueueExpiration = options.TemporaryQueueTtl ?? TimeSpan.FromHours(1);
|
||||
configurator.ConcurrentMessageLimit = options.ConcurrentMessageLimit;
|
||||
configurator.ConfigureConsumer<DispatchCancelWorkflowsRequestConsumer>(context);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ public class MassTransitFeature : FeatureBase
|
|||
// Concatenate the manually registered consumers with the workflow message consumers.
|
||||
var consumerTypeDefinitions = this.GetConsumers()
|
||||
//Temporary queues require implementation specific variables which will be handled in their respective projects
|
||||
.Where(c => c.IsShortLived == false)
|
||||
.Where(c => c.IsTemporary == false)
|
||||
.Concat(workflowMessageConsumers).ToArray();
|
||||
|
||||
Services.AddMassTransit(bus =>
|
||||
|
|
|
|||
|
|
@ -7,4 +7,4 @@ public record ConsumerTypeDefinition(
|
|||
Type ConsumerType,
|
||||
Type? ConsumerDefinitionType = default,
|
||||
string? Name = null,
|
||||
bool IsShortLived = false);
|
||||
bool IsTemporary = false);
|
||||
|
|
@ -5,8 +5,8 @@ namespace Elsa.MassTransit.Options;
|
|||
/// Provides options to the <see cref="DispatchWorkflowRequestConsumerDefinition"/>
|
||||
public class MassTransitWorkflowDispatcherOptions
|
||||
{
|
||||
/// The TTL of queues that are seen as short lived (typically queues that are created per running instance).
|
||||
public TimeSpan? ShortTermQueueLifetime { get; set; }
|
||||
/// The TTL of queues that are seen as temporary (typically queues that are created per running instance).
|
||||
public TimeSpan? TemporaryQueueTtl { get; set; }
|
||||
/// The number of concurrent messages to process.
|
||||
public int? ConcurrentMessageLimit { get; set; }
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
namespace Elsa.Workflows.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a name of the current instance.
|
||||
/// </summary>
|
||||
public interface IInstanceNameRetriever
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns a name for the instance.
|
||||
/// </summary>
|
||||
public string GetName();
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
using Elsa.Workflows.Contracts;
|
||||
|
||||
namespace Elsa.Workflows.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Returns a randomly generated instance name.
|
||||
/// </summary>
|
||||
public class RandomInstanceNameRetriever : IInstanceNameRetriever
|
||||
{
|
||||
private readonly string _instanceName;
|
||||
|
||||
public RandomInstanceNameRetriever(RandomLongIdentityGenerator identityGenerator)
|
||||
{
|
||||
_instanceName = identityGenerator.GenerateId();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetName() => _instanceName;
|
||||
}
|
||||
|
|
@ -104,10 +104,6 @@ public class WorkflowRuntimeFeature : FeatureBase
|
|||
/// </summary>
|
||||
public Func<IServiceProvider, IBackgroundActivityScheduler> BackgroundActivityScheduler { get; set; } = sp => ActivatorUtilities.CreateInstance<LocalBackgroundActivityScheduler>(sp);
|
||||
|
||||
/// <summary>
|
||||
/// A factory that instantiates an <see cref="IInstanceNameRetriever"/>.
|
||||
/// </summary>
|
||||
public Func<IServiceProvider, IInstanceNameRetriever> InstanceNameRetriever { get; set; } = sp => ActivatorUtilities.CreateInstance<RandomInstanceNameRetriever>(sp);
|
||||
|
||||
/// <summary>
|
||||
/// A delegate to configure the <see cref="DistributedLockingOptions"/>.
|
||||
|
|
@ -183,7 +179,6 @@ public class WorkflowRuntimeFeature : FeatureBase
|
|||
.AddScoped(WorkflowExecutionContextStore)
|
||||
.AddSingleton(RunTaskDispatcher)
|
||||
.AddSingleton(BackgroundActivityScheduler)
|
||||
.AddSingleton(InstanceNameRetriever)
|
||||
.AddSingleton<RandomLongIdentityGenerator>()
|
||||
.AddScoped<IBookmarkManager, DefaultBookmarkManager>()
|
||||
.AddScoped<IActivityExecutionManager, DefaultActivityExecutionManager>()
|
||||
|
|
|
|||
Loading…
Reference in a new issue