Merge pull request #6284 from elsa-workflows/bug/hangfire
Enable customizable Hangfire job storage and deprecate obsolete APIs.
This commit is contained in:
commit
c8d7882c33
|
|
@ -49,6 +49,7 @@
|
|||
<PackageVersion Include="Grpc.Tools" Version="2.68.1"/>
|
||||
<PackageVersion Include="Hangfire" Version="1.8.17"/>
|
||||
<PackageVersion Include="Hangfire.MemoryStorage" Version="1.8.1.1"/>
|
||||
<PackageVersion Include="Hangfire.PostgreSql" Version="1.20.10"/>
|
||||
<PackageVersion Include="Hangfire.Storage.SQLite" Version="0.4.2"/>
|
||||
<PackageVersion Include="Humanizer.Core" Version="2.14.1"/>
|
||||
<PackageVersion Include="IronCompress" Version="1.6.3"/>
|
||||
|
|
@ -112,44 +113,44 @@
|
|||
<PackageVersion Include="AspNetCore.Authentication.ApiKey" Version="8.0.1"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="8.0.11" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.11" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.11" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.11" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.DataProtection.Abstractions" Version="8.0.11" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.11" />
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite" Version="8.0.11" />
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite.Core" Version="8.0.11" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.11" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.11" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.11" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.11" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.11" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyModel" Version="8.0.2" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="8.0.11" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.2" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Options" Version="8.0.2" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" />
|
||||
<PackageVersion Include="Npgsql" Version="8.0.6" />
|
||||
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.11" />
|
||||
<PackageVersion Include="Oracle.EntityFrameworkCore" Version="8.23.60" />
|
||||
<PackageVersion Include="Polly" Version="8.4.2" />
|
||||
<PackageVersion Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.2" />
|
||||
<PackageVersion Include="Refit" Version="8.0.0" />
|
||||
<PackageVersion Include="Refit.HttpClientFactory" Version="8.0.0" />
|
||||
<PackageVersion Include="System.Formats.Asn1" Version="8.0.1" />
|
||||
<PackageVersion Include="System.Text.Json" Version="8.0.5" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="8.0.11"/>
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.11"/>
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.11"/>
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.11"/>
|
||||
<PackageVersion Include="Microsoft.AspNetCore.DataProtection.Abstractions" Version="8.0.11"/>
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.11"/>
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite" Version="8.0.11"/>
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite.Core" Version="8.0.11"/>
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.11"/>
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.11"/>
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.11"/>
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.11"/>
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.11"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="8.0.0"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="8.0.0"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyModel" Version="8.0.2"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="8.0.11"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.2"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="8.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Options" Version="8.0.2"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0"/>
|
||||
<PackageVersion Include="Npgsql" Version="8.0.6"/>
|
||||
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.11"/>
|
||||
<PackageVersion Include="Oracle.EntityFrameworkCore" Version="8.23.60"/>
|
||||
<PackageVersion Include="Polly" Version="8.4.2"/>
|
||||
<PackageVersion Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.2"/>
|
||||
<PackageVersion Include="Refit" Version="8.0.0"/>
|
||||
<PackageVersion Include="Refit.HttpClientFactory" Version="8.0.0"/>
|
||||
<PackageVersion Include="System.Formats.Asn1" Version="8.0.1"/>
|
||||
<PackageVersion Include="System.Text.Json" Version="8.0.5"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="9.0.0"/>
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@
|
|||
<PackageReference Include="DistributedLock.Postgres"/>
|
||||
<PackageReference Include="DistributedLock.Redis"/>
|
||||
<PackageReference Include="FluentStorage.Azure.Blobs"/>
|
||||
<PackageReference Include="Hangfire.PostgreSql" />
|
||||
<PackageReference Include="Proto.Cluster.Kubernetes" />
|
||||
<PackageReference Include="Grpc.Net.Client" />
|
||||
<PackageReference Include="Proto.Persistence.Sqlite"/>
|
||||
|
|
|
|||
|
|
@ -49,6 +49,12 @@ using Elsa.Workflows.Runtime.Distributed.Extensions;
|
|||
using Elsa.Workflows.Runtime.Options;
|
||||
using Elsa.Workflows.Runtime.Stores;
|
||||
using Elsa.Workflows.Runtime.Tasks;
|
||||
using Hangfire;
|
||||
using Hangfire.MemoryStorage;
|
||||
using Hangfire.PostgreSql;
|
||||
using Hangfire.PostgreSql.Factories;
|
||||
using Hangfire.SqlServer;
|
||||
using Hangfire.Storage.SQLite;
|
||||
using JetBrains.Annotations;
|
||||
using Medallion.Threading.FileSystem;
|
||||
using Medallion.Threading.Postgres;
|
||||
|
|
@ -78,8 +84,8 @@ const bool useSignalR = false; // Disabled until Elsa Studio sends authenticated
|
|||
const WorkflowRuntime workflowRuntime = WorkflowRuntime.Distributed;
|
||||
const DistributedCachingTransport distributedCachingTransport = DistributedCachingTransport.MassTransit;
|
||||
const MassTransitBroker massTransitBroker = MassTransitBroker.Memory;
|
||||
const bool useMultitenancy = false;
|
||||
const bool useTenantsFromConfiguration = false;
|
||||
const bool useMultitenancy = true;
|
||||
const bool useTenantsFromConfiguration = true;
|
||||
const bool useAgents = false;
|
||||
const bool useSecrets = false;
|
||||
const bool disableVariableWrappers = false;
|
||||
|
|
@ -133,7 +139,36 @@ services
|
|||
});
|
||||
|
||||
if (useHangfire)
|
||||
elsa.UseHangfire();
|
||||
{
|
||||
JobStorage jobStorage;
|
||||
if (sqlDatabaseProvider == SqlDatabaseProvider.PostgreSql)
|
||||
{
|
||||
jobStorage = new PostgreSqlStorage(new NpgsqlConnectionFactory(postgresConnectionString, new()
|
||||
{
|
||||
QueuePollInterval = TimeSpan.FromSeconds(1)
|
||||
}));
|
||||
}
|
||||
else if (sqlDatabaseProvider == SqlDatabaseProvider.Sqlite)
|
||||
{
|
||||
jobStorage = new SQLiteStorage(sqliteConnectionString, new()
|
||||
{
|
||||
QueuePollInterval = TimeSpan.FromSeconds(1)
|
||||
});
|
||||
}
|
||||
else if (sqlDatabaseProvider == SqlDatabaseProvider.SqlServer)
|
||||
{
|
||||
jobStorage = new SqlServerStorage(sqlServerConnectionString, new()
|
||||
{
|
||||
QueuePollInterval = TimeSpan.FromSeconds(1)
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
jobStorage = new MemoryStorage();
|
||||
}
|
||||
|
||||
elsa.UseHangfire(hangfire => hangfire.UseJobStorage(jobStorage));
|
||||
}
|
||||
|
||||
elsa
|
||||
.AddActivitiesFrom<Program>()
|
||||
|
|
|
|||
|
|
@ -2,14 +2,7 @@
|
|||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Warning",
|
||||
"Elsa": "Warning",
|
||||
"MassTransit": "Warning",
|
||||
"Microsoft.Extensions.Http": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information",
|
||||
"Microsoft.EntityFrameworkCore": "Warning",
|
||||
"Microsoft.AspNetCore": "Warning",
|
||||
"Quartz": "Warning",
|
||||
"System.Net.Http": "Warning"
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"HostBuilder": {
|
||||
|
|
|
|||
|
|
@ -8,14 +8,14 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Hangfire" />
|
||||
<PackageReference Include="Hangfire.MemoryStorage" />
|
||||
<PackageReference Include="Hangfire.Storage.SQLite" />
|
||||
<PackageReference Include="Hangfire"/>
|
||||
<PackageReference Include="Hangfire.MemoryStorage"/>
|
||||
<PackageReference Include="Hangfire.Storage.SQLite"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\common\Elsa.Features\Elsa.Features.csproj" />
|
||||
<ProjectReference Include="..\Elsa.Scheduling\Elsa.Scheduling.csproj" />
|
||||
<ProjectReference Include="..\..\common\Elsa.Features\Elsa.Features.csproj"/>
|
||||
<ProjectReference Include="..\Elsa.Scheduling\Elsa.Scheduling.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ public static class ModuleExtensions
|
|||
/// <summary>
|
||||
/// Configures Hangfire to use SQL Server storage. Only use this feature if you are not configuring Hangfire yourself.
|
||||
/// </summary>
|
||||
[Obsolete("Configure storage directly on the HangfireFeature.")]
|
||||
public static HangfireFeature UseSqlServerStorage(this HangfireFeature feature, Action<HangfireSqlServerStorageFeature> configure)
|
||||
{
|
||||
feature.Module.Use(configure);
|
||||
|
|
@ -34,6 +35,7 @@ public static class ModuleExtensions
|
|||
/// <summary>
|
||||
/// Configures Hangfire to use SQLite storage. Only use this feature if you are not configuring Hangfire yourself.
|
||||
/// </summary>
|
||||
[Obsolete("Configure storage directly on the HangfireFeature.")]
|
||||
public static HangfireFeature UseSqliteStorage(this HangfireFeature feature, Action<HangfireSqliteStorageFeature> configure)
|
||||
{
|
||||
feature.Module.Use(configure);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
using Elsa.Features.Abstractions;
|
||||
using Elsa.Features.Attributes;
|
||||
using Elsa.Features.Services;
|
||||
using Elsa.Workflows.Runtime.Features;
|
||||
using Hangfire;
|
||||
using Hangfire.MemoryStorage;
|
||||
using Newtonsoft.Json;
|
||||
|
|
@ -9,35 +11,63 @@ namespace Elsa.Hangfire.Features;
|
|||
/// <summary>
|
||||
/// Sets up Hangfire. If you're setting up Hangfire yourself, then you should not enable this feature.
|
||||
/// </summary>
|
||||
public class HangfireFeature : FeatureBase
|
||||
[DependsOn(typeof(WorkflowRuntimeFeature))] // Ensure that the workflow runtime feature's hosted services have executed before Hangfire Server starts.
|
||||
public class HangfireFeature(IModule module) : FeatureBase(module)
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public HangfireFeature(IModule module) : base(module)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A delegate that configures Hangfire.
|
||||
/// </summary>
|
||||
public Action<IServiceProvider, IGlobalConfiguration> ConfigureHangfire { get; set; } = (_, cfg) => cfg.UseMemoryStorage();
|
||||
private Action<IServiceProvider, IGlobalConfiguration> _configureHangfire = (_, _) => { };
|
||||
|
||||
/// <summary>
|
||||
/// A delegate that configures Hangfire's background job server options.
|
||||
/// </summary>
|
||||
public Action<IServiceProvider, BackgroundJobServerOptions> ConfigureBackgroundServerOptions { get; set; } = (_, _) => { };
|
||||
private Action<IServiceProvider, BackgroundJobServerOptions> _configureBackgroundServerOptions = (_, _) => { };
|
||||
|
||||
/// <summary>
|
||||
/// A delegate that creates a job storage instance.
|
||||
/// </summary>
|
||||
public Func<JobStorage> CreateJobStorage { get; set; } = () => new MemoryStorage();
|
||||
private Func<JobStorage> _createJobStorage = () => new MemoryStorage();
|
||||
|
||||
/// <summary>
|
||||
/// Configures Hangfire.
|
||||
/// </summary>
|
||||
public HangfireFeature ConfigureHangfire(Action<IServiceProvider, IGlobalConfiguration> configure)
|
||||
{
|
||||
_configureHangfire += configure;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures Hangfire's background job server options.
|
||||
/// </summary>
|
||||
public HangfireFeature ConfigureBackgroundServerOptions(Action<IServiceProvider, BackgroundJobServerOptions> configure)
|
||||
{
|
||||
_configureBackgroundServerOptions += configure;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HangfireFeature UseMemoryStorage()
|
||||
{
|
||||
return UseJobStorage(new MemoryStorage());
|
||||
}
|
||||
|
||||
public HangfireFeature UseJobStorage(JobStorage storage)
|
||||
{
|
||||
_createJobStorage = () => storage;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Apply()
|
||||
{
|
||||
var jobStorage = _createJobStorage();
|
||||
|
||||
Action<IServiceProvider, IGlobalConfiguration> configAction = (sp, cfg) =>
|
||||
{
|
||||
cfg.UseSimpleAssemblyNameTypeSerializer();
|
||||
cfg.UseRecommendedSerializerSettings(json => json.TypeNameHandling = TypeNameHandling.Objects);
|
||||
cfg.UseStorage(jobStorage);
|
||||
};
|
||||
|
||||
Action<IServiceProvider, BackgroundJobServerOptions> serverOptionsAction = (sp, options) =>
|
||||
|
|
@ -46,10 +76,10 @@ public class HangfireFeature : FeatureBase
|
|||
options.SchedulePollingInterval = TimeSpan.FromSeconds(1);
|
||||
};
|
||||
|
||||
configAction += ConfigureHangfire;
|
||||
serverOptionsAction += ConfigureBackgroundServerOptions;
|
||||
configAction += _configureHangfire;
|
||||
serverOptionsAction += _configureBackgroundServerOptions;
|
||||
|
||||
Services.AddHangfire(configAction);
|
||||
Services.AddHangfireServer(serverOptionsAction, CreateJobStorage());
|
||||
Services.AddHangfireServer(serverOptionsAction, jobStorage);
|
||||
}
|
||||
}
|
||||
|
|
@ -11,18 +11,14 @@ namespace Elsa.Hangfire.Features;
|
|||
/// Configures the Hangfire feature to use SQL Server storage. If you're setting up Hangfire yourself, then you should not enable this feature.
|
||||
/// </summary>
|
||||
[DependsOn(typeof(HangfireFeature))]
|
||||
public class HangfireSqlServerStorageFeature : FeatureBase
|
||||
[Obsolete("Configure storage directly on the HangfireFeature.")]
|
||||
public class HangfireSqlServerStorageFeature(IModule module) : FeatureBase(module)
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public HangfireSqlServerStorageFeature(IModule module) : base(module)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The connection string to use when connecting to SQL Server, or the name of the connection string.
|
||||
/// </summary>
|
||||
public string NameOrConnectionString { get; set; } = default!;
|
||||
|
||||
public string NameOrConnectionString { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Configures the SQL Server storage options.
|
||||
/// </summary>
|
||||
|
|
@ -41,13 +37,11 @@ public class HangfireSqlServerStorageFeature : FeatureBase
|
|||
UseRecommendedIsolationLevel = true
|
||||
};
|
||||
ConfigureSqlServerStorageOptions(storageOptions);
|
||||
|
||||
hangfireFeature.ConfigureHangfire = (_, cfg) =>
|
||||
|
||||
hangfireFeature.ConfigureHangfire((_, cfg) =>
|
||||
{
|
||||
cfg.UseSqlServerStorage(NameOrConnectionString, storageOptions);
|
||||
};
|
||||
|
||||
hangfireFeature.CreateJobStorage = () => new SqlServerStorage(NameOrConnectionString, storageOptions);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -10,17 +10,13 @@ namespace Elsa.Hangfire.Features;
|
|||
/// Configures the Hangfire feature to use SQLite storage. If you're setting up Hangfire yourself, then you should not enable this feature.
|
||||
/// </summary>
|
||||
[DependsOn(typeof(HangfireFeature))]
|
||||
public class HangfireSqliteStorageFeature : FeatureBase
|
||||
[Obsolete("Configure storage directly on the HangfireFeature.")]
|
||||
public class HangfireSqliteStorageFeature(IModule module) : FeatureBase(module)
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public HangfireSqliteStorageFeature(IModule module) : base(module)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The connection string to use when connecting to SQL Server, or the name of the connection string.
|
||||
/// </summary>
|
||||
public string NameOrConnectionString { get; set; } = default!;
|
||||
public string NameOrConnectionString { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Configures the SQL Server storage options.
|
||||
|
|
@ -38,12 +34,10 @@ public class HangfireSqliteStorageFeature : FeatureBase
|
|||
};
|
||||
ConfigureSqlServerStorageOptions(storageOptions);
|
||||
|
||||
hangfireFeature.ConfigureHangfire = (_, cfg) =>
|
||||
hangfireFeature.ConfigureHangfire((_, cfg) =>
|
||||
{
|
||||
cfg.UseSQLiteStorage(NameOrConnectionString, storageOptions);
|
||||
};
|
||||
|
||||
hangfireFeature.CreateJobStorage = () => new SQLiteStorage(NameOrConnectionString, storageOptions);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@ namespace Elsa.Workflows;
|
|||
/// <param name="Child">The child <see cref="IActivity"/> being scheduled.</param>
|
||||
/// <param name="CompletionCallback">The <see cref="ActivityCompletionCallback"/> delegate to invoke when the scheduled <see cref="Child"/> activity completes.</param>
|
||||
/// <param name="Tag">An optional tag.</param>
|
||||
public record ActivityCompletionCallbackEntry(ActivityExecutionContext Owner, ActivityNode Child, ActivityCompletionCallback? CompletionCallback, object? Tag = default);
|
||||
public record ActivityCompletionCallbackEntry(ActivityExecutionContext Owner, ActivityNode Child, ActivityCompletionCallback? CompletionCallback, object? Tag = null);
|
||||
|
||||
/// <summary>
|
||||
/// Provides context to the currently executing workflow.
|
||||
|
|
@ -239,7 +239,7 @@ public partial class WorkflowExecutionContext : IExecutionContext
|
|||
public WorkflowSubStatus SubStatus { get; internal set; }
|
||||
|
||||
/// The root <see cref="MemoryRegister"/> associated with the execution context.
|
||||
public MemoryRegister MemoryRegister { get; private set; } = default!;
|
||||
public MemoryRegister MemoryRegister { get; private set; } = null!;
|
||||
|
||||
/// A unique ID of the execution context.
|
||||
public string Id { get; set; }
|
||||
|
|
@ -406,7 +406,7 @@ public partial class WorkflowExecutionContext : IExecutionContext
|
|||
/// <summary>
|
||||
/// Registers a completion callback for the specified activity.
|
||||
/// </summary>
|
||||
internal void AddCompletionCallback(ActivityExecutionContext owner, ActivityNode child, ActivityCompletionCallback? completionCallback = default, object? tag = default)
|
||||
internal void AddCompletionCallback(ActivityExecutionContext owner, ActivityNode child, ActivityCompletionCallback? completionCallback = null, object? tag = null)
|
||||
{
|
||||
var entry = new ActivityCompletionCallbackEntry(owner, child, completionCallback, tag);
|
||||
_completionCallbackEntries.Add(entry);
|
||||
|
|
@ -420,7 +420,7 @@ public partial class WorkflowExecutionContext : IExecutionContext
|
|||
var entry = _completionCallbackEntries.FirstOrDefault(x => x.Owner == owner && x.Child == child);
|
||||
|
||||
if (entry == null)
|
||||
return default;
|
||||
return null;
|
||||
|
||||
RemoveCompletionCallback(entry);
|
||||
return entry;
|
||||
|
|
@ -449,25 +449,25 @@ public partial class WorkflowExecutionContext : IExecutionContext
|
|||
? FindActivityByInstanceId(handle.ActivityInstanceId)
|
||||
: handle.ActivityHash != null
|
||||
? FindActivityByHash(handle.ActivityHash)
|
||||
: default;
|
||||
: null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="ActivityNode"/> with the specified activity ID from the workflow graph.
|
||||
/// </summary>
|
||||
public ActivityNode? FindNodeById(string nodeId) => NodeIdLookup.TryGetValue(nodeId, out var node) ? node : default;
|
||||
public ActivityNode? FindNodeById(string nodeId) => NodeIdLookup.TryGetValue(nodeId, out var node) ? node : null;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="ActivityNode"/> with the specified hash of the activity node ID from the workflow graph.
|
||||
/// </summary>
|
||||
/// <param name="hash">The hash of the activity node ID.</param>
|
||||
/// <returns>The <see cref="ActivityNode"/> with the specified hash of the activity node ID.</returns>
|
||||
public ActivityNode? FindNodeByHash(string hash) => NodeHashLookup.TryGetValue(hash, out var node) ? node : default;
|
||||
public ActivityNode? FindNodeByHash(string hash) => NodeHashLookup.TryGetValue(hash, out var node) ? node : null;
|
||||
|
||||
/// Returns the <see cref="ActivityNode"/> containing the specified activity from the workflow graph.
|
||||
public ActivityNode? FindNodeByActivity(IActivity activity)
|
||||
{
|
||||
return NodeActivityLookup.TryGetValue(activity, out var node) ? node : default;
|
||||
return NodeActivityLookup.TryGetValue(activity, out var node) ? node : null;
|
||||
}
|
||||
|
||||
/// Returns the <see cref="ActivityNode"/> associated with the specified activity ID.
|
||||
|
|
@ -526,7 +526,7 @@ public partial class WorkflowExecutionContext : IExecutionContext
|
|||
}
|
||||
|
||||
/// Creates a new <see cref="ActivityExecutionContext"/> for the specified activity.
|
||||
public async Task<ActivityExecutionContext> CreateActivityExecutionContextAsync(IActivity activity, ActivityInvocationOptions? options = default)
|
||||
public async Task<ActivityExecutionContext> CreateActivityExecutionContextAsync(IActivity activity, ActivityInvocationOptions? options = null)
|
||||
{
|
||||
var activityDescriptor = await ActivityRegistryLookup.FindAsync(activity) ?? throw new ActivityNotFoundException(activity.Type);
|
||||
var tag = options?.Tag;
|
||||
|
|
@ -568,7 +568,7 @@ public partial class WorkflowExecutionContext : IExecutionContext
|
|||
public ActivityOutputRegister GetActivityOutputRegister() => TransientProperties.GetOrAdd(ActivityOutputRegistryKey, () => new ActivityOutputRegister());
|
||||
|
||||
/// Returns the last activity result.
|
||||
public object? GetLastActivityResult() => TransientProperties.TryGetValue(LastActivityResultKey, out var value) ? value : default;
|
||||
public object? GetLastActivityResult() => TransientProperties.TryGetValue(LastActivityResultKey, out var value) ? value : null;
|
||||
|
||||
/// Adds the specified <see cref="ActivityExecutionContext"/> to the workflow execution context.
|
||||
public void AddActivityExecutionContext(ActivityExecutionContext context) => _activityExecutionContexts.Add(context);
|
||||
|
|
|
|||
Loading…
Reference in a new issue