From e942f799eca3334447e0ae28ec47c5879f0f127d Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Thu, 11 Aug 2022 12:45:07 +0200 Subject: [PATCH] Add default implementations for job queue and scheduler --- Elsa.sln | 23 ++++-- .../Elsa.AllInOne.Web.csproj | 2 +- src/bundles/Elsa.AllInOne.Web/Program.cs | 11 +-- .../Elsa.WorkflowServer.Web.csproj | 2 +- .../Jobs/IndexBlockchainJob.cs | 4 +- .../Elsa.WorkflowServer.Web/Program.cs | 18 +---- .../Elsa.Features/Implementations/Module.cs | 22 ++--- .../Elsa.Jobs.Abstractions/AssemblyInfo.cs | 2 - .../DependencyInjectionExtensions.cs | 20 ----- .../Services/IJobQueueProvider.cs | 8 -- .../Services/IJobSchedulerProvider.cs | 8 -- .../Services/IServiceBusProvider.cs | 8 -- .../Features/ActivityDefinitionsFeature.cs | 2 + .../ActivityDefinitionPublisher.cs | 1 + .../Implementations/Worker.cs | 1 - src/modules/Elsa.Common/Elsa.Common.csproj | 13 +++ .../Features/SystemClockFeature.cs | 19 +++++ .../Implementations/SystemClock.cs | 4 +- .../Services/ISystemClock.cs | 2 +- .../Elsa.Hangfire/Elsa.Hangfire.csproj | 2 +- .../Elsa.Hangfire/Features/HangfireFeature.cs | 44 ++++++++++ .../Features/HangfireJobsFeature.cs | 23 ++++++ .../Implementations/HangfireJobQueue.cs | 7 +- .../HangfireJobQueueProvider.cs | 61 -------------- src/modules/Elsa.Hangfire/Jobs/RunElsaJob.cs | 1 - .../Activities/JobActivity.cs | 5 +- .../Attributes/JobAttribute.cs | 2 +- .../Elsa.Jobs.Activities.csproj} | 6 +- .../Extensions/ModuleExtensions.cs | 13 +++ .../Features/JobActivitiesFeature.cs} | 12 +-- .../Handlers/JobExecutedHandler.cs | 6 +- .../Helpers/JobTypeNameHelper.cs | 6 +- .../Implementations/JobActivityProvider.cs | 8 +- .../Implementations/JobRegistry.cs | 4 +- .../Models/EnqueuedJobPayload.cs | 2 +- .../Services/IJobRegistry.cs | 2 +- .../Elsa.Jobs}/Abstractions/Job.cs | 3 + .../Elsa.Jobs/Elsa.Jobs.csproj} | 2 + .../Elsa.Jobs/Extensions/ModuleExtensions.cs | 26 ++++++ src/modules/Elsa.Jobs/Features/JobsFeature.cs | 44 ++++++++++ .../HostedServices/JobQueueHostedService.cs | 41 ++++++++++ .../Elsa.Jobs}/Implementations/JobFactory.cs | 3 +- .../Elsa.Jobs}/Implementations/JobRunner.cs | 0 .../Implementations/JobSerializer.cs | 0 .../Implementations/LocalJobQueue.cs | 24 ++++++ .../Implementations/LocalJobScheduler.cs | 72 +++++++++++++++++ .../Elsa.Jobs}/Models/JobExecutionContext.cs | 0 .../Elsa.Jobs}/Notifications/JobExecuted.cs | 0 .../ScheduledJobs/ScheduledCronJob.cs | 59 ++++++++++++++ .../ScheduledJobs/ScheduledRecurringJob.cs | 58 ++++++++++++++ .../ScheduledSpecificInstantJob.cs | 51 ++++++++++++ .../Elsa.Jobs}/Schedules/CronSchedule.cs | 0 .../Elsa.Jobs}/Schedules/RecurringSchedule.cs | 0 .../Schedules/SpecificInstantSchedule.cs | 0 .../Elsa.Jobs}/Services/IJob.cs | 3 + .../Elsa.Jobs}/Services/IJobFactory.cs | 5 +- .../Elsa.Jobs}/Services/IJobQueue.cs | 2 +- .../Elsa.Jobs}/Services/IJobRunner.cs | 6 ++ .../Elsa.Jobs}/Services/IJobScheduler.cs | 0 .../Elsa.Jobs}/Services/IJobSerializer.cs | 0 .../Elsa.Jobs}/Services/ISchedule.cs | 0 .../Elsa.Jobs/Services/IScheduledJob.cs | 7 ++ .../DependencyInjectionExtensions.cs | 13 --- .../Extensions/ModuleExtensions.cs | 13 +++ .../Features/MassTransitDispatchersFeature.cs | 22 +++++ .../Features/MassTransitServiceBusFeature.cs | 19 +++++ .../MassTransitServiceBusProvider.cs | 16 ---- .../Elsa.Mediator/Elsa.Mediator.csproj | 1 + .../DependencyInjectionExtensions.cs | 21 ++++- .../BackgroundCommandSenderHostedService.cs | 38 +++++++++ .../BackgroundEventPublisherHostedService.cs | 38 +++++++++ .../BackgroundCommandSender.cs | 11 +++ .../BackgroundEventPublisher.cs | 11 +++ .../Services/IBackgroundCommandSender.cs | 12 +++ .../Services/IBackgroundEventPublisher.cs | 12 +++ .../Grains/WorkflowInstanceGrain.cs | 1 - .../Implementations/GrainClientFactory.cs | 1 - .../ProtoActorWorkflowInvoker.cs | 1 - src/modules/Elsa.Quartz/Elsa.Quartz.csproj | 2 +- .../Elsa.Quartz/Features/QuartzFeature.cs | 48 +++++++++++ .../Features/QuartzSchedulerFeature.cs | 22 +++++ .../Implementations/QuartzJobScheduler.cs | 2 +- .../QuartzJobSchedulerProvider.cs | 80 ------------------- .../Elsa.Scheduling/Activities/Delay.cs | 1 + .../Elsa.Scheduling/Activities/StartAt.cs | 1 + .../Elsa.Scheduling/Activities/Timer.cs | 1 + .../Elsa.Scheduling/Elsa.Scheduling.csproj | 2 +- .../DependencyInjectionExtensions.cs | 20 ----- .../Extensions/ModuleExtensions.cs | 14 ++++ .../Features/SchedulingFeature.cs | 32 ++++++++ ...s.cs => ScheduleWorkflowsHostedService.cs} | 4 +- .../Elsa.Scheduling/Jobs/RunWorkflowJob.cs | 1 - .../DispatchWorkflowDefinitionResult.cs | 1 - .../ExecuteWorkflowDefinitionResult.cs | 1 - .../WorkflowDefinitions/BulkDelete.cs | 1 - .../WorkflowDefinitions/BulkPublish.cs | 1 - .../WorkflowDefinitions/BulkRetract.cs | 1 - .../Endpoints/WorkflowDefinitions/Dispatch.cs | 1 - .../Endpoints/WorkflowDefinitions/Execute.cs | 1 - .../Endpoints/WorkflowDefinitions/Export.cs | 1 - .../Endpoints/WorkflowDefinitions/Get.cs | 1 - .../Endpoints/WorkflowDefinitions/Post.cs | 1 - .../Endpoints/WorkflowDefinitions/Publish.cs | 1 - .../Endpoints/WorkflowDefinitions/Retract.cs | 1 - .../Models/WorkflowDefinitionModel.cs | 1 - .../Elsa.Workflows.Core.csproj | 1 + .../ActivityExecutionContextExtensions.cs | 1 + .../Features/WorkflowsFeature.cs | 3 +- .../Components/ActivityInvokerMiddleware.cs | 7 +- .../Services/IActivityPortResolver.cs | 2 - .../Features/WorkflowManagementFeature.cs | 2 + .../WorkflowDefinitionPublisher.cs | 2 +- .../EFCoreWorkflowPersistenceFeature.cs | 2 + .../EFCoreWorkflowDefinitionStore.cs | 1 - .../Extensions/WorkflowExtensions.cs | 1 - .../MemoryWorkflowDefinitionStore.cs | 1 - .../Activities/DispatchWorkflow.cs | 1 - .../DependencyInjectionExtensions.cs | 13 +-- .../Features/WorkflowRuntimeFeature.cs | 3 + .../PopulateWorkflowDefinitionStore.cs | 1 - .../Implementations/DefaultWorkflowInvoker.cs | 1 - .../WorkflowInstanceFactory.cs | 2 +- .../Implementations/WorkflowService.cs | 1 - .../ResumeWorkflowInstructionInterpreter.cs | 1 - .../TriggerWorkflowInstructionInterpreter.cs | 1 - .../PersistWorkflowInstanceMiddleware.cs | 12 ++- .../DispatchWorkflowDefinitionRequest.cs | 1 - .../Models/InvokeWorkflowDefinitionRequest.cs | 1 - .../Services/IWorkflowInstanceFactory.cs | 1 - .../Services/IWorkflowService.cs | 2 - .../ClrWorkflowDefinitionProvider.cs | 3 +- .../Elsa.Samples.Web1.csproj | 2 +- .../aspnet/Elsa.Samples.Web1/Program.cs | 8 +- .../Workflows/DelayWorkflow.cs | 1 + .../Workflows/HeartbeatWorkflow.cs | 1 + .../Workflows/StartAtBookmarkWorkflow.cs | 1 + .../Workflows/StartAtTriggerWorkflow.cs | 1 + .../Elsa.Samples.Web2.csproj | 2 +- .../aspnet/Elsa.Samples.Web2/Program.cs | 8 +- .../Elsa.Samples.Web3.csproj | 2 +- .../aspnet/Elsa.Samples.Web3/Program.cs | 8 +- 141 files changed, 946 insertions(+), 408 deletions(-) delete mode 100644 src/common/Elsa.Jobs.Abstractions/AssemblyInfo.cs delete mode 100644 src/common/Elsa.Jobs.Abstractions/Extensions/DependencyInjectionExtensions.cs delete mode 100644 src/common/Elsa.Jobs.Abstractions/Services/IJobQueueProvider.cs delete mode 100644 src/common/Elsa.Jobs.Abstractions/Services/IJobSchedulerProvider.cs delete mode 100644 src/common/Elsa.ServiceBus.Abstractions/Services/IServiceBusProvider.cs create mode 100644 src/modules/Elsa.Common/Elsa.Common.csproj create mode 100644 src/modules/Elsa.Common/Features/SystemClockFeature.cs rename src/modules/{Elsa.Workflows.Core => Elsa.Common}/Implementations/SystemClock.cs (55%) rename src/modules/{Elsa.Workflows.Core => Elsa.Common}/Services/ISystemClock.cs (63%) create mode 100644 src/modules/Elsa.Hangfire/Features/HangfireFeature.cs create mode 100644 src/modules/Elsa.Hangfire/Features/HangfireJobsFeature.cs delete mode 100644 src/modules/Elsa.Hangfire/Implementations/HangfireJobQueueProvider.cs rename src/modules/{Elsa.Activities.Jobs => Elsa.Jobs.Activities}/Activities/JobActivity.cs (84%) rename src/modules/{Elsa.Activities.Jobs => Elsa.Jobs.Activities}/Attributes/JobAttribute.cs (95%) rename src/modules/{Elsa.Activities.Jobs/Elsa.Activities.Jobs.csproj => Elsa.Jobs.Activities/Elsa.Jobs.Activities.csproj} (75%) create mode 100644 src/modules/Elsa.Jobs.Activities/Extensions/ModuleExtensions.cs rename src/modules/{Elsa.Activities.Jobs/Features/JobsFeature.cs => Elsa.Jobs.Activities/Features/JobActivitiesFeature.cs} (65%) rename src/modules/{Elsa.Activities.Jobs => Elsa.Jobs.Activities}/Handlers/JobExecutedHandler.cs (87%) rename src/modules/{Elsa.Activities.Jobs => Elsa.Jobs.Activities}/Helpers/JobTypeNameHelper.cs (87%) rename src/modules/{Elsa.Activities.Jobs => Elsa.Jobs.Activities}/Implementations/JobActivityProvider.cs (94%) rename src/modules/{Elsa.Activities.Jobs => Elsa.Jobs.Activities}/Implementations/JobRegistry.cs (74%) rename src/modules/{Elsa.Activities.Jobs => Elsa.Jobs.Activities}/Models/EnqueuedJobPayload.cs (87%) rename src/modules/{Elsa.Activities.Jobs => Elsa.Jobs.Activities}/Services/IJobRegistry.cs (79%) rename src/{common/Elsa.Jobs.Abstractions => modules/Elsa.Jobs}/Abstractions/Job.cs (87%) rename src/{common/Elsa.Jobs.Abstractions/Elsa.Jobs.Abstractions.csproj => modules/Elsa.Jobs/Elsa.Jobs.csproj} (80%) create mode 100644 src/modules/Elsa.Jobs/Extensions/ModuleExtensions.cs create mode 100644 src/modules/Elsa.Jobs/Features/JobsFeature.cs create mode 100644 src/modules/Elsa.Jobs/HostedServices/JobQueueHostedService.cs rename src/{common/Elsa.Jobs.Abstractions => modules/Elsa.Jobs}/Implementations/JobFactory.cs (83%) rename src/{common/Elsa.Jobs.Abstractions => modules/Elsa.Jobs}/Implementations/JobRunner.cs (100%) rename src/{common/Elsa.Jobs.Abstractions => modules/Elsa.Jobs}/Implementations/JobSerializer.cs (100%) create mode 100644 src/modules/Elsa.Jobs/Implementations/LocalJobQueue.cs create mode 100644 src/modules/Elsa.Jobs/Implementations/LocalJobScheduler.cs rename src/{common/Elsa.Jobs.Abstractions => modules/Elsa.Jobs}/Models/JobExecutionContext.cs (100%) rename src/{common/Elsa.Jobs.Abstractions => modules/Elsa.Jobs}/Notifications/JobExecuted.cs (100%) create mode 100644 src/modules/Elsa.Jobs/ScheduledJobs/ScheduledCronJob.cs create mode 100644 src/modules/Elsa.Jobs/ScheduledJobs/ScheduledRecurringJob.cs create mode 100644 src/modules/Elsa.Jobs/ScheduledJobs/ScheduledSpecificInstantJob.cs rename src/{common/Elsa.Jobs.Abstractions => modules/Elsa.Jobs}/Schedules/CronSchedule.cs (100%) rename src/{common/Elsa.Jobs.Abstractions => modules/Elsa.Jobs}/Schedules/RecurringSchedule.cs (100%) rename src/{common/Elsa.Jobs.Abstractions => modules/Elsa.Jobs}/Schedules/SpecificInstantSchedule.cs (100%) rename src/{common/Elsa.Jobs.Abstractions => modules/Elsa.Jobs}/Services/IJob.cs (69%) rename src/{common/Elsa.Jobs.Abstractions => modules/Elsa.Jobs}/Services/IJobFactory.cs (52%) rename src/{common/Elsa.Jobs.Abstractions => modules/Elsa.Jobs}/Services/IJobQueue.cs (63%) rename src/{common/Elsa.Jobs.Abstractions => modules/Elsa.Jobs}/Services/IJobRunner.cs (61%) rename src/{common/Elsa.Jobs.Abstractions => modules/Elsa.Jobs}/Services/IJobScheduler.cs (100%) rename src/{common/Elsa.Jobs.Abstractions => modules/Elsa.Jobs}/Services/IJobSerializer.cs (100%) rename src/{common/Elsa.Jobs.Abstractions => modules/Elsa.Jobs}/Services/ISchedule.cs (100%) create mode 100644 src/modules/Elsa.Jobs/Services/IScheduledJob.cs delete mode 100644 src/modules/Elsa.MassTransit/Extensions/DependencyInjectionExtensions.cs create mode 100644 src/modules/Elsa.MassTransit/Extensions/ModuleExtensions.cs create mode 100644 src/modules/Elsa.MassTransit/Features/MassTransitDispatchersFeature.cs create mode 100644 src/modules/Elsa.MassTransit/Features/MassTransitServiceBusFeature.cs delete mode 100644 src/modules/Elsa.MassTransit/Implementations/MassTransitServiceBusProvider.cs create mode 100644 src/modules/Elsa.Mediator/HostedServices/BackgroundCommandSenderHostedService.cs create mode 100644 src/modules/Elsa.Mediator/HostedServices/BackgroundEventPublisherHostedService.cs create mode 100644 src/modules/Elsa.Mediator/Implementations/BackgroundCommandSender.cs create mode 100644 src/modules/Elsa.Mediator/Implementations/BackgroundEventPublisher.cs create mode 100644 src/modules/Elsa.Mediator/Services/IBackgroundCommandSender.cs create mode 100644 src/modules/Elsa.Mediator/Services/IBackgroundEventPublisher.cs create mode 100644 src/modules/Elsa.Quartz/Features/QuartzFeature.cs create mode 100644 src/modules/Elsa.Quartz/Features/QuartzSchedulerFeature.cs delete mode 100644 src/modules/Elsa.Quartz/Implementations/QuartzJobSchedulerProvider.cs delete mode 100644 src/modules/Elsa.Scheduling/Extensions/DependencyInjectionExtensions.cs create mode 100644 src/modules/Elsa.Scheduling/Extensions/ModuleExtensions.cs create mode 100644 src/modules/Elsa.Scheduling/Features/SchedulingFeature.cs rename src/modules/Elsa.Scheduling/HostedServices/{ScheduleWorkflows.cs => ScheduleWorkflowsHostedService.cs} (88%) diff --git a/Elsa.sln b/Elsa.sln index 77a6f62af..69b533e49 100644 --- a/Elsa.sln +++ b/Elsa.sln @@ -64,8 +64,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa", "src\bundles\Elsa\El EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Formatting", "src\common\Elsa.Formatting\Elsa.Formatting.csproj", "{60CEE728-3187-481B-B6EA-10D5284D8B55}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Jobs.Abstractions", "src\common\Elsa.Jobs.Abstractions\Elsa.Jobs.Abstractions.csproj", "{2782C593-98CD-4B80-B595-8BAE066DCBC3}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.ServiceBus.Abstractions", "src\common\Elsa.ServiceBus.Abstractions\Elsa.ServiceBus.Abstractions.csproj", "{448FCDE6-DE44-4E44-A1CC-B9AA51471121}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Liquid", "src\modules\Elsa.Liquid\Elsa.Liquid.csproj", "{8E5BD3D9-3529-48BC-B741-CFB7A69DB233}" @@ -118,7 +116,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Api.Common", "src\comm EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Tokens.Api", "src\modules\Elsa.Tokens.Api\Elsa.Tokens.Api.csproj", "{30B49E42-AE61-4F7C-981F-923F07BB3986}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Activities.Jobs", "src\modules\Elsa.Activities.Jobs\Elsa.Activities.Jobs.csproj", "{81A2AE6B-3D0C-4A4A-A80B-7A661FBC8117}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Jobs.Activities", "src\modules\Elsa.Jobs.Activities\Elsa.Jobs.Activities.csproj", "{81A2AE6B-3D0C-4A4A-A80B-7A661FBC8117}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Jobs", "src\modules\Elsa.Jobs\Elsa.Jobs.csproj", "{CF1938A0-BD10-4AA1-9ABC-6D02303A9D53}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Common", "src\modules\Elsa.Common\Elsa.Common.csproj", "{D229105F-6879-4452-9189-75DE060C0F4C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -206,10 +208,6 @@ Global {60CEE728-3187-481B-B6EA-10D5284D8B55}.Debug|Any CPU.Build.0 = Debug|Any CPU {60CEE728-3187-481B-B6EA-10D5284D8B55}.Release|Any CPU.ActiveCfg = Release|Any CPU {60CEE728-3187-481B-B6EA-10D5284D8B55}.Release|Any CPU.Build.0 = Release|Any CPU - {2782C593-98CD-4B80-B595-8BAE066DCBC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2782C593-98CD-4B80-B595-8BAE066DCBC3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2782C593-98CD-4B80-B595-8BAE066DCBC3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2782C593-98CD-4B80-B595-8BAE066DCBC3}.Release|Any CPU.Build.0 = Release|Any CPU {448FCDE6-DE44-4E44-A1CC-B9AA51471121}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {448FCDE6-DE44-4E44-A1CC-B9AA51471121}.Debug|Any CPU.Build.0 = Debug|Any CPU {448FCDE6-DE44-4E44-A1CC-B9AA51471121}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -318,6 +316,14 @@ Global {81A2AE6B-3D0C-4A4A-A80B-7A661FBC8117}.Debug|Any CPU.Build.0 = Debug|Any CPU {81A2AE6B-3D0C-4A4A-A80B-7A661FBC8117}.Release|Any CPU.ActiveCfg = Release|Any CPU {81A2AE6B-3D0C-4A4A-A80B-7A661FBC8117}.Release|Any CPU.Build.0 = Release|Any CPU + {CF1938A0-BD10-4AA1-9ABC-6D02303A9D53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CF1938A0-BD10-4AA1-9ABC-6D02303A9D53}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CF1938A0-BD10-4AA1-9ABC-6D02303A9D53}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CF1938A0-BD10-4AA1-9ABC-6D02303A9D53}.Release|Any CPU.Build.0 = Release|Any CPU + {D229105F-6879-4452-9189-75DE060C0F4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D229105F-6879-4452-9189-75DE060C0F4C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D229105F-6879-4452-9189-75DE060C0F4C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D229105F-6879-4452-9189-75DE060C0F4C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {155227F0-A33B-40AA-A4B4-06F813EB921B} = {61017E64-6D00-49CB-9E81-5002DC8F7D5F} @@ -335,7 +341,6 @@ Global {177F4FF3-4618-4CB1-BA93-8B024BC64CD8} = {56C2FFB8-EA54-45B5-A095-4A78142EB4B5} {F06B9573-DF68-4606-866C-A7546A10A05A} = {61017E64-6D00-49CB-9E81-5002DC8F7D5F} {60CEE728-3187-481B-B6EA-10D5284D8B55} = {C6658DE0-2B2F-47F0-BB61-2CA66D435C09} - {2782C593-98CD-4B80-B595-8BAE066DCBC3} = {C6658DE0-2B2F-47F0-BB61-2CA66D435C09} {448FCDE6-DE44-4E44-A1CC-B9AA51471121} = {C6658DE0-2B2F-47F0-BB61-2CA66D435C09} {B2049499-D384-46DF-8837-F1180107DD54} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79} {FC5D2CE9-FFB0-478D-8D54-E4109D1FD202} = {F06B9573-DF68-4606-866C-A7546A10A05A} @@ -374,5 +379,7 @@ Global {39CD855E-83B1-4A96-93F7-01608211EBE3} = {C6658DE0-2B2F-47F0-BB61-2CA66D435C09} {30B49E42-AE61-4F7C-981F-923F07BB3986} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79} {81A2AE6B-3D0C-4A4A-A80B-7A661FBC8117} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79} + {CF1938A0-BD10-4AA1-9ABC-6D02303A9D53} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79} + {D229105F-6879-4452-9189-75DE060C0F4C} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79} EndGlobalSection EndGlobal diff --git a/src/bundles/Elsa.AllInOne.Web/Elsa.AllInOne.Web.csproj b/src/bundles/Elsa.AllInOne.Web/Elsa.AllInOne.Web.csproj index 09ecd7742..34ab90a19 100644 --- a/src/bundles/Elsa.AllInOne.Web/Elsa.AllInOne.Web.csproj +++ b/src/bundles/Elsa.AllInOne.Web/Elsa.AllInOne.Web.csproj @@ -10,10 +10,10 @@ - + diff --git a/src/bundles/Elsa.AllInOne.Web/Program.cs b/src/bundles/Elsa.AllInOne.Web/Program.cs index 8e415f7ea..2c093c996 100644 --- a/src/bundles/Elsa.AllInOne.Web/Program.cs +++ b/src/bundles/Elsa.AllInOne.Web/Program.cs @@ -1,17 +1,14 @@ -using System.Text.Json.Serialization; using Elsa.Workflows.Api.Extensions; using Elsa.AspNetCore.Extensions; using Elsa.Extensions; using Elsa.Jobs.Extensions; -using Elsa.Hangfire.Implementations; using Elsa.Http; using Elsa.Http.Extensions; using Elsa.JavaScript.Activities; using Elsa.JavaScript.Extensions; -using Elsa.Quartz.Implementations; using Elsa.Scheduling.Activities; -using Elsa.Scheduling.Extensions; using Elsa.Liquid.Extensions; +using Elsa.Scheduling.Extensions; using Elsa.Workflows.Core; using Elsa.Workflows.Core.Activities; using Elsa.Workflows.Core.Activities.Flowchart.Activities; @@ -43,6 +40,8 @@ services .AddActivity() .AddActivity() ) + .UseJobs() + .UseScheduling() .UseJavaScript() .UseLiquid() .UseHttp() @@ -50,10 +49,6 @@ services .UseMvc() ); -services - .AddJobServices(new QuartzJobSchedulerProvider(), new HangfireJobQueueProvider()) - .AddSchedulingServices(); - // Register serialization configurator for configuring what types to allow to be serialized. services.AddSingleton(); services.AddSingleton(); diff --git a/src/bundles/Elsa.WorkflowServer.Web/Elsa.WorkflowServer.Web.csproj b/src/bundles/Elsa.WorkflowServer.Web/Elsa.WorkflowServer.Web.csproj index a4b003b89..576b16841 100644 --- a/src/bundles/Elsa.WorkflowServer.Web/Elsa.WorkflowServer.Web.csproj +++ b/src/bundles/Elsa.WorkflowServer.Web/Elsa.WorkflowServer.Web.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/bundles/Elsa.WorkflowServer.Web/Jobs/IndexBlockchainJob.cs b/src/bundles/Elsa.WorkflowServer.Web/Jobs/IndexBlockchainJob.cs index 1268626be..be996b30a 100644 --- a/src/bundles/Elsa.WorkflowServer.Web/Jobs/IndexBlockchainJob.cs +++ b/src/bundles/Elsa.WorkflowServer.Web/Jobs/IndexBlockchainJob.cs @@ -1,5 +1,5 @@ -using Elsa.Activities.Jobs.Features; using Elsa.Jobs.Abstractions; +using Elsa.Jobs.Activities.Features; using Elsa.Jobs.Models; using Elsa.Jobs.Services; @@ -7,7 +7,7 @@ namespace Elsa.WorkflowServer.Web.Jobs; /// /// Jobs can be scheduled manually using , -/// but when enabling the , these jobs become available as activities too. +/// but when enabling the , these jobs become available as activities too. /// public class IndexBlockchainJob : Job { diff --git a/src/bundles/Elsa.WorkflowServer.Web/Program.cs b/src/bundles/Elsa.WorkflowServer.Web/Program.cs index 919236969..b86170ff1 100644 --- a/src/bundles/Elsa.WorkflowServer.Web/Program.cs +++ b/src/bundles/Elsa.WorkflowServer.Web/Program.cs @@ -1,8 +1,5 @@ using System.Text.Json; using System.Text.Json.Serialization; -using Elsa.Activities.Jobs.Features; -using Elsa.Activities.Jobs.Implementations; -using Elsa.Activities.Jobs.Services; using Elsa.ActivityDefinitions.EntityFrameworkCore.Extensions; using Elsa.ActivityDefinitions.EntityFrameworkCore.Sqlite; using Elsa.Api.Common; @@ -11,18 +8,17 @@ using Elsa.Api.Common.Options; using Elsa.AspNetCore.Extensions; using Elsa.Extensions; using Elsa.Features.Extensions; -using Elsa.Hangfire.Implementations; using Elsa.Http; using Elsa.Http.Extensions; using Elsa.JavaScript.Activities; using Elsa.JavaScript.Extensions; -using Elsa.Jobs.Extensions; +using Elsa.Jobs.Activities.Extensions; +using Elsa.Jobs.Activities.Implementations; +using Elsa.Jobs.Activities.Services; using Elsa.Labels.EntityFrameworkCore.Extensions; using Elsa.Labels.EntityFrameworkCore.Sqlite; using Elsa.Labels.Extensions; using Elsa.Liquid.Extensions; -using Elsa.Quartz.Implementations; -using Elsa.Scheduling.Extensions; using Elsa.WorkflowContexts.Extensions; using Elsa.Workflows.Api.Extensions; using Elsa.Workflows.Core.Activities; @@ -35,7 +31,6 @@ using Elsa.Workflows.Persistence.EntityFrameworkCore.Extensions; using Elsa.Workflows.Persistence.EntityFrameworkCore.Sqlite; using Elsa.Workflows.Persistence.Extensions; using Elsa.Workflows.Runtime.Extensions; -using Elsa.WorkflowServer.Web; using Elsa.WorkflowServer.Web.Implementations; using Elsa.WorkflowServer.Web.Jobs; using FastEndpoints; @@ -80,7 +75,7 @@ services feature.CredentialsValidator = sp => sp.GetRequiredService(); feature.AccessTokenIssuer = sp => sp.GetRequiredService(); }) - .Use() + .UseJobActivities() .UseWorkflowPersistence(p => p.UseEntityFrameworkCore(ef => ef.UseSqlite())) .UseWorkflowApiEndpoints() .UseJavaScript() @@ -91,11 +86,6 @@ services .UseMvc() ); -services - .AddJobServices(new QuartzJobSchedulerProvider(), new HangfireJobQueueProvider()) - .AddSchedulingServices() - ; - services.AddFastEndpoints(); services.AddAuthenticationJWTBearer(accessTokenOptions.SigningKey); services.AddHealthChecks(); diff --git a/src/common/Elsa.Features/Implementations/Module.cs b/src/common/Elsa.Features/Implementations/Module.cs index 9faf8ff41..c2819fb8d 100644 --- a/src/common/Elsa.Features/Implementations/Module.cs +++ b/src/common/Elsa.Features/Implementations/Module.cs @@ -11,7 +11,7 @@ public class Module : IModule { private record HostedServiceDescriptor(int Order, Type HostedServiceType); - private readonly ISet _configurators = new HashSet(); + private readonly ISet _features = new HashSet(); private readonly ICollection _hostedServiceDescriptors = new List(); public Module(IServiceCollection services) @@ -25,10 +25,10 @@ public class Module : IModule public T Configure(Func factory, Action? configure = default) where T : class, IFeature { - if (_configurators.FirstOrDefault(x => x is T) is not T configurator) + if (_features.FirstOrDefault(x => x is T) is not T configurator) { configurator = factory(this); - _configurators.Add(configurator); + _features.Add(configurator); } configure?.Invoke(configurator); @@ -45,18 +45,18 @@ public class Module : IModule { ResolveDependencies(); - foreach (var configurator in _configurators) + foreach (var feature in _features) { - configurator.Configure(); - configurator.ConfigureHostedServices(); + feature.Configure(); + feature.ConfigureHostedServices(); } foreach (var hostedServiceDescriptor in _hostedServiceDescriptors.OrderBy(x => x.Order)) Services.TryAddEnumerable(ServiceDescriptor.Singleton(typeof(IHostedService), hostedServiceDescriptor.HostedServiceType)); - foreach (var configurator in _configurators) + foreach (var feature in _features) { - configurator.Apply(); + feature.Apply(); } } @@ -64,7 +64,7 @@ public class Module : IModule { var resolvedDependencyTypes = new HashSet(); - foreach (var configurator in _configurators.ToList()) + foreach (var configurator in _features.ToList()) ResolveDependencies(configurator, resolvedDependencyTypes); } @@ -83,13 +83,13 @@ public class Module : IModule private IFeature AddConfigurator(Type type) { - var configurator = _configurators.FirstOrDefault(x => x.GetType() == type); + var configurator = _features.FirstOrDefault(x => x.GetType() == type); if (configurator != null) return configurator; configurator = (IFeature)Activator.CreateInstance(type, this)!; - _configurators.Add(configurator); + _features.Add(configurator); return configurator; } } \ No newline at end of file diff --git a/src/common/Elsa.Jobs.Abstractions/AssemblyInfo.cs b/src/common/Elsa.Jobs.Abstractions/AssemblyInfo.cs deleted file mode 100644 index e46bb2692..000000000 --- a/src/common/Elsa.Jobs.Abstractions/AssemblyInfo.cs +++ /dev/null @@ -1,2 +0,0 @@ -using System; -[assembly: CLSCompliant(true)] \ No newline at end of file diff --git a/src/common/Elsa.Jobs.Abstractions/Extensions/DependencyInjectionExtensions.cs b/src/common/Elsa.Jobs.Abstractions/Extensions/DependencyInjectionExtensions.cs deleted file mode 100644 index d27811ffc..000000000 --- a/src/common/Elsa.Jobs.Abstractions/Extensions/DependencyInjectionExtensions.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Elsa.Jobs.Implementations; -using Elsa.Jobs.Services; -using Microsoft.Extensions.DependencyInjection; - -namespace Elsa.Jobs.Extensions; - -public static class DependencyInjectionExtensions -{ - public static IServiceCollection AddJobServices(this IServiceCollection services, IJobSchedulerProvider schedulerProvider, IJobQueueProvider queueProvider) - { - services - .AddSingleton() - .AddSingleton() - .AddSingleton(); - - schedulerProvider.ConfigureServices(services); - queueProvider.ConfigureServices(services); - return services; - } -} \ No newline at end of file diff --git a/src/common/Elsa.Jobs.Abstractions/Services/IJobQueueProvider.cs b/src/common/Elsa.Jobs.Abstractions/Services/IJobQueueProvider.cs deleted file mode 100644 index 1716dbd1c..000000000 --- a/src/common/Elsa.Jobs.Abstractions/Services/IJobQueueProvider.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; - -namespace Elsa.Jobs.Services; - -public interface IJobQueueProvider -{ - void ConfigureServices(IServiceCollection services); -} \ No newline at end of file diff --git a/src/common/Elsa.Jobs.Abstractions/Services/IJobSchedulerProvider.cs b/src/common/Elsa.Jobs.Abstractions/Services/IJobSchedulerProvider.cs deleted file mode 100644 index ef9a58d42..000000000 --- a/src/common/Elsa.Jobs.Abstractions/Services/IJobSchedulerProvider.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; - -namespace Elsa.Jobs.Services; - -public interface IJobSchedulerProvider -{ - void ConfigureServices(IServiceCollection services); -} \ No newline at end of file diff --git a/src/common/Elsa.ServiceBus.Abstractions/Services/IServiceBusProvider.cs b/src/common/Elsa.ServiceBus.Abstractions/Services/IServiceBusProvider.cs deleted file mode 100644 index ef8d9e409..000000000 --- a/src/common/Elsa.ServiceBus.Abstractions/Services/IServiceBusProvider.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; - -namespace Elsa.ServiceBus.Abstractions.Services; - -public interface IServiceBusProvider -{ - void ConfigureServices(IServiceCollection services); -} \ No newline at end of file diff --git a/src/modules/Elsa.ActivityDefinitions/Features/ActivityDefinitionsFeature.cs b/src/modules/Elsa.ActivityDefinitions/Features/ActivityDefinitionsFeature.cs index 41717ae06..43f092269 100644 --- a/src/modules/Elsa.ActivityDefinitions/Features/ActivityDefinitionsFeature.cs +++ b/src/modules/Elsa.ActivityDefinitions/Features/ActivityDefinitionsFeature.cs @@ -1,6 +1,7 @@ using Elsa.ActivityDefinitions.Entities; using Elsa.ActivityDefinitions.Implementations; using Elsa.ActivityDefinitions.Services; +using Elsa.Common.Features; using Elsa.Features.Abstractions; using Elsa.Features.Attributes; using Elsa.Features.Services; @@ -14,6 +15,7 @@ using Microsoft.Extensions.DependencyInjection; namespace Elsa.ActivityDefinitions.Features; [DependsOn(typeof(MediatorFeature))] +[DependsOn(typeof(SystemClockFeature))] public class ActivityDefinitionsFeature : FeatureBase { public ActivityDefinitionsFeature(IModule module) : base(module) diff --git a/src/modules/Elsa.ActivityDefinitions/Implementations/ActivityDefinitionPublisher.cs b/src/modules/Elsa.ActivityDefinitions/Implementations/ActivityDefinitionPublisher.cs index 0d357458a..61e2f3b07 100644 --- a/src/modules/Elsa.ActivityDefinitions/Implementations/ActivityDefinitionPublisher.cs +++ b/src/modules/Elsa.ActivityDefinitions/Implementations/ActivityDefinitionPublisher.cs @@ -2,6 +2,7 @@ using System.Text.Json; using Elsa.ActivityDefinitions.Entities; using Elsa.ActivityDefinitions.Notifications; using Elsa.ActivityDefinitions.Services; +using Elsa.Common.Services; using Elsa.Mediator.Services; using Elsa.Persistence.Common.Models; using Elsa.Workflows.Core.Activities.Flowchart.Activities; diff --git a/src/modules/Elsa.AzureServiceBus/Implementations/Worker.cs b/src/modules/Elsa.AzureServiceBus/Implementations/Worker.cs index 2afa49abc..338d81b90 100644 --- a/src/modules/Elsa.AzureServiceBus/Implementations/Worker.cs +++ b/src/modules/Elsa.AzureServiceBus/Implementations/Worker.cs @@ -3,7 +3,6 @@ using Elsa.AzureServiceBus.Activities; using Elsa.AzureServiceBus.Models; using Elsa.Workflows.Core.Helpers; using Elsa.Workflows.Core.Services; -using Elsa.Workflows.Runtime.Models; using Elsa.Workflows.Runtime.Services; using Microsoft.Extensions.Logging; diff --git a/src/modules/Elsa.Common/Elsa.Common.csproj b/src/modules/Elsa.Common/Elsa.Common.csproj new file mode 100644 index 000000000..5465086a8 --- /dev/null +++ b/src/modules/Elsa.Common/Elsa.Common.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/src/modules/Elsa.Common/Features/SystemClockFeature.cs b/src/modules/Elsa.Common/Features/SystemClockFeature.cs new file mode 100644 index 000000000..addea2d13 --- /dev/null +++ b/src/modules/Elsa.Common/Features/SystemClockFeature.cs @@ -0,0 +1,19 @@ +using Elsa.Common.Implementations; +using Elsa.Common.Services; +using Elsa.Features.Abstractions; +using Elsa.Features.Services; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Common.Features; + +public class SystemClockFeature : FeatureBase +{ + public SystemClockFeature(IModule module) : base(module) + { + } + + public override void Apply() + { + Services.AddSingleton(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Core/Implementations/SystemClock.cs b/src/modules/Elsa.Common/Implementations/SystemClock.cs similarity index 55% rename from src/modules/Elsa.Workflows.Core/Implementations/SystemClock.cs rename to src/modules/Elsa.Common/Implementations/SystemClock.cs index b61f29b6e..b8a731857 100644 --- a/src/modules/Elsa.Workflows.Core/Implementations/SystemClock.cs +++ b/src/modules/Elsa.Common/Implementations/SystemClock.cs @@ -1,6 +1,6 @@ -using Elsa.Workflows.Core.Services; +using Elsa.Common.Services; -namespace Elsa.Workflows.Core.Implementations; +namespace Elsa.Common.Implementations; public class SystemClock : ISystemClock { diff --git a/src/modules/Elsa.Workflows.Core/Services/ISystemClock.cs b/src/modules/Elsa.Common/Services/ISystemClock.cs similarity index 63% rename from src/modules/Elsa.Workflows.Core/Services/ISystemClock.cs rename to src/modules/Elsa.Common/Services/ISystemClock.cs index 4c5a2a900..d674c8857 100644 --- a/src/modules/Elsa.Workflows.Core/Services/ISystemClock.cs +++ b/src/modules/Elsa.Common/Services/ISystemClock.cs @@ -1,4 +1,4 @@ -namespace Elsa.Workflows.Core.Services; +namespace Elsa.Common.Services; public interface ISystemClock { diff --git a/src/modules/Elsa.Hangfire/Elsa.Hangfire.csproj b/src/modules/Elsa.Hangfire/Elsa.Hangfire.csproj index 2d2ee6b2d..baeb84fe0 100644 --- a/src/modules/Elsa.Hangfire/Elsa.Hangfire.csproj +++ b/src/modules/Elsa.Hangfire/Elsa.Hangfire.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/modules/Elsa.Hangfire/Features/HangfireFeature.cs b/src/modules/Elsa.Hangfire/Features/HangfireFeature.cs new file mode 100644 index 000000000..e60476173 --- /dev/null +++ b/src/modules/Elsa.Hangfire/Features/HangfireFeature.cs @@ -0,0 +1,44 @@ +using Elsa.Features.Abstractions; +using Elsa.Features.Services; +using Hangfire; +using Hangfire.MemoryStorage; +using Hangfire.SqlServer; +using Newtonsoft.Json; + +namespace Elsa.Hangfire.Features; + +public class HangfireFeature : FeatureBase +{ + public HangfireFeature(IModule module) : base(module) + { + } + + public bool UseSqlServerStorage { get; set; } + public SqlServerStorageOptions? SqlServerStorageOptions { get; set; } + public string? SqlServerConnectionString { get; set; } + public Action? ConfigureBackgroundServerOptions { get; set; } + + public override void Configure() + { + Services.AddHangfire(configuration => + { + configuration.UseSimpleAssemblyNameTypeSerializer(); + configuration.UseRecommendedSerializerSettings(json => json.TypeNameHandling = TypeNameHandling.Objects); + + if (UseSqlServerStorage) + { + var storageOptions = SqlServerStorageOptions ?? new SqlServerStorageOptions(); + configuration.UseSqlServerStorage(SqlServerConnectionString, storageOptions); + } + else + { + configuration.UseMemoryStorage(); + } + }); + + if (UseSqlServerStorage) + Services.AddHangfireServer((_, options) => ConfigureBackgroundServerOptions?.Invoke(options), new SqlServerStorage(SqlServerConnectionString)); + else + Services.AddHangfireServer(options => { ConfigureBackgroundServerOptions?.Invoke(options); }); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Hangfire/Features/HangfireJobsFeature.cs b/src/modules/Elsa.Hangfire/Features/HangfireJobsFeature.cs new file mode 100644 index 000000000..922b20a00 --- /dev/null +++ b/src/modules/Elsa.Hangfire/Features/HangfireJobsFeature.cs @@ -0,0 +1,23 @@ +using Elsa.Features.Abstractions; +using Elsa.Features.Attributes; +using Elsa.Features.Extensions; +using Elsa.Features.Services; +using Elsa.Hangfire.Implementations; +using Elsa.Jobs.Features; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Hangfire.Features; + +[DependsOn(typeof(JobsFeature))] +[DependsOn(typeof(HangfireFeature))] +public class HangfireJobsFeature : FeatureBase +{ + public HangfireJobsFeature(IModule module) : base(module) + { + } + + public override void Configure() + { + Module.Use(f => f.JobQueueFactory = ActivatorUtilities.GetServiceOrCreateInstance); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Hangfire/Implementations/HangfireJobQueue.cs b/src/modules/Elsa.Hangfire/Implementations/HangfireJobQueue.cs index c8e85d27b..a7547ccf9 100644 --- a/src/modules/Elsa.Hangfire/Implementations/HangfireJobQueue.cs +++ b/src/modules/Elsa.Hangfire/Implementations/HangfireJobQueue.cs @@ -1,7 +1,6 @@ using Elsa.Hangfire.Jobs; using Elsa.Jobs.Services; using Hangfire; -using Hangfire.Server; using Hangfire.States; using HangfireJob = Hangfire.Common.Job; @@ -16,11 +15,11 @@ public class HangfireJobQueue : IJobQueue _backgroundJobClient = backgroundJobClient; } - public Task SubmitJobAsync(IJob job, string? queueName = default, CancellationToken cancellationToken = default) + public Task SubmitJobAsync(IJob job, string? queueName = default, CancellationToken cancellationToken = default) { var hangfireJob = HangfireJob.FromExpression(x => x.RunAsync(job, CancellationToken.None)); - var jobId = _backgroundJobClient.Create(hangfireJob, new EnqueuedState(queueName ?? "default")); + _backgroundJobClient.Create(hangfireJob, new EnqueuedState(queueName ?? "default")); - return Task.FromResult(jobId); + return Task.CompletedTask; } } \ No newline at end of file diff --git a/src/modules/Elsa.Hangfire/Implementations/HangfireJobQueueProvider.cs b/src/modules/Elsa.Hangfire/Implementations/HangfireJobQueueProvider.cs deleted file mode 100644 index 235bce994..000000000 --- a/src/modules/Elsa.Hangfire/Implementations/HangfireJobQueueProvider.cs +++ /dev/null @@ -1,61 +0,0 @@ -using Elsa.Jobs.Services; -using Hangfire; -using Hangfire.MemoryStorage; -using Hangfire.SqlServer; -using Microsoft.Extensions.DependencyInjection; -using Newtonsoft.Json; - -namespace Elsa.Hangfire.Implementations; - -public class HangfireJobQueueProvider : IJobQueueProvider -{ - public HangfireJobQueueProvider(bool registerHangfire = true) - { - RegisterHangfire = registerHangfire; - } - - public HangfireJobQueueProvider(string sqlServerConnectionString) - { - SqlServerConnectionString = sqlServerConnectionString; - UseSqlServerStorage = true; - RegisterHangfire = true; - } - - public bool RegisterHangfire { get; set; } - public bool UseSqlServerStorage { get; set; } - public string? SqlServerConnectionString { get; set; } - public SqlServerStorageOptions? SqlServerStorageOptions { get; set; } - public Action? ConfigureBackgroundServerOptions { get; set; } - - public void ConfigureServices(IServiceCollection services) - { - if (RegisterHangfire) - { - services.AddHangfire(configuration => - { - configuration.UseSimpleAssemblyNameTypeSerializer(); - configuration.UseRecommendedSerializerSettings(json => json.TypeNameHandling = TypeNameHandling.Objects); - - if (UseSqlServerStorage) - { - var storageOptions = SqlServerStorageOptions ?? new SqlServerStorageOptions(); - configuration.UseSqlServerStorage(SqlServerConnectionString, storageOptions); - } - else - { - configuration.UseMemoryStorage(); - } - }); - - if (UseSqlServerStorage) - services.AddHangfireServer((_, options) => ConfigureBackgroundServerOptions?.Invoke(options), new SqlServerStorage(SqlServerConnectionString)); - else - services.AddHangfireServer(options => - { - ConfigureBackgroundServerOptions?.Invoke(options); - }); - } - - services.AddSingleton(); - } -} \ No newline at end of file diff --git a/src/modules/Elsa.Hangfire/Jobs/RunElsaJob.cs b/src/modules/Elsa.Hangfire/Jobs/RunElsaJob.cs index 8ca85b084..544d4af44 100644 --- a/src/modules/Elsa.Hangfire/Jobs/RunElsaJob.cs +++ b/src/modules/Elsa.Hangfire/Jobs/RunElsaJob.cs @@ -1,5 +1,4 @@ using Elsa.Jobs.Services; -using Hangfire.Server; namespace Elsa.Hangfire.Jobs; diff --git a/src/modules/Elsa.Activities.Jobs/Activities/JobActivity.cs b/src/modules/Elsa.Jobs.Activities/Activities/JobActivity.cs similarity index 84% rename from src/modules/Elsa.Activities.Jobs/Activities/JobActivity.cs rename to src/modules/Elsa.Jobs.Activities/Activities/JobActivity.cs index bd3b74546..20bfc3b2b 100644 --- a/src/modules/Elsa.Activities.Jobs/Activities/JobActivity.cs +++ b/src/modules/Elsa.Jobs.Activities/Activities/JobActivity.cs @@ -1,11 +1,12 @@ -using Elsa.Activities.Jobs.Models; +using Elsa.Jobs.Activities.Models; using Elsa.Jobs.Services; using Elsa.Workflows.Core.Models; +// ReSharper disable once CheckNamespace namespace Elsa.Activities.Jobs.Activities; /// -/// Executes a given job, suspending execution of the workflow until the job finishes. +/// Executes a job of a given type, suspending execution of the workflow until the job finishes. /// public class JobActivity : ActivityBase { diff --git a/src/modules/Elsa.Activities.Jobs/Attributes/JobAttribute.cs b/src/modules/Elsa.Jobs.Activities/Attributes/JobAttribute.cs similarity index 95% rename from src/modules/Elsa.Activities.Jobs/Attributes/JobAttribute.cs rename to src/modules/Elsa.Jobs.Activities/Attributes/JobAttribute.cs index 4ebb6554e..3e6d2e239 100644 --- a/src/modules/Elsa.Activities.Jobs/Attributes/JobAttribute.cs +++ b/src/modules/Elsa.Jobs.Activities/Attributes/JobAttribute.cs @@ -1,4 +1,4 @@ -namespace Elsa.Activities.Jobs.Attributes; +namespace Elsa.Jobs.Activities.Attributes; [AttributeUsage(AttributeTargets.Class)] public class JobAttribute : Attribute diff --git a/src/modules/Elsa.Activities.Jobs/Elsa.Activities.Jobs.csproj b/src/modules/Elsa.Jobs.Activities/Elsa.Jobs.Activities.csproj similarity index 75% rename from src/modules/Elsa.Activities.Jobs/Elsa.Activities.Jobs.csproj rename to src/modules/Elsa.Jobs.Activities/Elsa.Jobs.Activities.csproj index 669c9b6b7..8576d04d7 100644 --- a/src/modules/Elsa.Activities.Jobs/Elsa.Activities.Jobs.csproj +++ b/src/modules/Elsa.Jobs.Activities/Elsa.Jobs.Activities.csproj @@ -7,14 +7,10 @@ - + - - - - diff --git a/src/modules/Elsa.Jobs.Activities/Extensions/ModuleExtensions.cs b/src/modules/Elsa.Jobs.Activities/Extensions/ModuleExtensions.cs new file mode 100644 index 000000000..e90ad2855 --- /dev/null +++ b/src/modules/Elsa.Jobs.Activities/Extensions/ModuleExtensions.cs @@ -0,0 +1,13 @@ +using Elsa.Features.Services; +using Elsa.Jobs.Activities.Features; + +namespace Elsa.Jobs.Activities.Extensions; + +public static class ModuleExtensions +{ + public static IModule UseJobActivities(this IModule module, Action? configure = default ) + { + module.Configure(configure); + return module; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Activities.Jobs/Features/JobsFeature.cs b/src/modules/Elsa.Jobs.Activities/Features/JobActivitiesFeature.cs similarity index 65% rename from src/modules/Elsa.Activities.Jobs/Features/JobsFeature.cs rename to src/modules/Elsa.Jobs.Activities/Features/JobActivitiesFeature.cs index 02af3d692..bf31df63b 100644 --- a/src/modules/Elsa.Activities.Jobs/Features/JobsFeature.cs +++ b/src/modules/Elsa.Jobs.Activities/Features/JobActivitiesFeature.cs @@ -1,19 +1,21 @@ -using Elsa.Activities.Jobs.Implementations; -using Elsa.Activities.Jobs.Services; using Elsa.Features.Abstractions; using Elsa.Features.Attributes; using Elsa.Features.Services; +using Elsa.Jobs.Activities.Implementations; +using Elsa.Jobs.Activities.Services; +using Elsa.Jobs.Features; using Elsa.Mediator.Extensions; using Elsa.Mediator.Features; using Elsa.Workflows.Management.Services; using Microsoft.Extensions.DependencyInjection; -namespace Elsa.Activities.Jobs.Features; +namespace Elsa.Jobs.Activities.Features; [DependsOn(typeof(MediatorFeature))] -public class JobsFeature : FeatureBase +[DependsOn(typeof(JobsFeature))] +public class JobActivitiesFeature : FeatureBase { - public JobsFeature(IModule module) : base(module) + public JobActivitiesFeature(IModule module) : base(module) { } diff --git a/src/modules/Elsa.Activities.Jobs/Handlers/JobExecutedHandler.cs b/src/modules/Elsa.Jobs.Activities/Handlers/JobExecutedHandler.cs similarity index 87% rename from src/modules/Elsa.Activities.Jobs/Handlers/JobExecutedHandler.cs rename to src/modules/Elsa.Jobs.Activities/Handlers/JobExecutedHandler.cs index 25b191929..0ea592a71 100644 --- a/src/modules/Elsa.Activities.Jobs/Handlers/JobExecutedHandler.cs +++ b/src/modules/Elsa.Jobs.Activities/Handlers/JobExecutedHandler.cs @@ -1,10 +1,10 @@ -using Elsa.Activities.Jobs.Helpers; -using Elsa.Activities.Jobs.Models; +using Elsa.Jobs.Activities.Helpers; +using Elsa.Jobs.Activities.Models; using Elsa.Jobs.Notifications; using Elsa.Mediator.Services; using Elsa.Workflows.Runtime.Services; -namespace Elsa.Activities.Jobs.Handlers; +namespace Elsa.Jobs.Activities.Handlers; public class JobExecutedHandler : INotificationHandler { diff --git a/src/modules/Elsa.Activities.Jobs/Helpers/JobTypeNameHelper.cs b/src/modules/Elsa.Jobs.Activities/Helpers/JobTypeNameHelper.cs similarity index 87% rename from src/modules/Elsa.Activities.Jobs/Helpers/JobTypeNameHelper.cs rename to src/modules/Elsa.Jobs.Activities/Helpers/JobTypeNameHelper.cs index ba065eb6c..304502b67 100644 --- a/src/modules/Elsa.Activities.Jobs/Helpers/JobTypeNameHelper.cs +++ b/src/modules/Elsa.Jobs.Activities/Helpers/JobTypeNameHelper.cs @@ -1,10 +1,8 @@ using System.Reflection; -using Elsa.Activities.Jobs.Attributes; +using Elsa.Jobs.Activities.Attributes; using Elsa.Jobs.Services; -using Elsa.Workflows.Core.Attributes; -using Elsa.Workflows.Core.Services; -namespace Elsa.Activities.Jobs.Helpers; +namespace Elsa.Jobs.Activities.Helpers; public static class JobTypeNameHelper { diff --git a/src/modules/Elsa.Activities.Jobs/Implementations/JobActivityProvider.cs b/src/modules/Elsa.Jobs.Activities/Implementations/JobActivityProvider.cs similarity index 94% rename from src/modules/Elsa.Activities.Jobs/Implementations/JobActivityProvider.cs rename to src/modules/Elsa.Jobs.Activities/Implementations/JobActivityProvider.cs index 066dab1bc..694256d60 100644 --- a/src/modules/Elsa.Activities.Jobs/Implementations/JobActivityProvider.cs +++ b/src/modules/Elsa.Jobs.Activities/Implementations/JobActivityProvider.cs @@ -1,9 +1,9 @@ using System.ComponentModel; using System.Reflection; using Elsa.Activities.Jobs.Activities; -using Elsa.Activities.Jobs.Attributes; -using Elsa.Activities.Jobs.Helpers; -using Elsa.Activities.Jobs.Services; +using Elsa.Jobs.Activities.Attributes; +using Elsa.Jobs.Activities.Helpers; +using Elsa.Jobs.Activities.Services; using Elsa.Jobs.Services; using Elsa.Workflows.Core.Helpers; using Elsa.Workflows.Core.Models; @@ -11,7 +11,7 @@ using Elsa.Workflows.Management.Extensions; using Elsa.Workflows.Management.Services; using Humanizer; -namespace Elsa.Activities.Jobs.Implementations; +namespace Elsa.Jobs.Activities.Implementations; /// /// Provides activity descriptors based on registered implementations. diff --git a/src/modules/Elsa.Activities.Jobs/Implementations/JobRegistry.cs b/src/modules/Elsa.Jobs.Activities/Implementations/JobRegistry.cs similarity index 74% rename from src/modules/Elsa.Activities.Jobs/Implementations/JobRegistry.cs rename to src/modules/Elsa.Jobs.Activities/Implementations/JobRegistry.cs index de068c8e7..8a21563e0 100644 --- a/src/modules/Elsa.Activities.Jobs/Implementations/JobRegistry.cs +++ b/src/modules/Elsa.Jobs.Activities/Implementations/JobRegistry.cs @@ -1,6 +1,6 @@ -using Elsa.Activities.Jobs.Services; +using Elsa.Jobs.Activities.Services; -namespace Elsa.Activities.Jobs.Implementations; +namespace Elsa.Jobs.Activities.Implementations; public class JobRegistry : IJobRegistry { diff --git a/src/modules/Elsa.Activities.Jobs/Models/EnqueuedJobPayload.cs b/src/modules/Elsa.Jobs.Activities/Models/EnqueuedJobPayload.cs similarity index 87% rename from src/modules/Elsa.Activities.Jobs/Models/EnqueuedJobPayload.cs rename to src/modules/Elsa.Jobs.Activities/Models/EnqueuedJobPayload.cs index 5d10a4b9a..8ca37cb5d 100644 --- a/src/modules/Elsa.Activities.Jobs/Models/EnqueuedJobPayload.cs +++ b/src/modules/Elsa.Jobs.Activities/Models/EnqueuedJobPayload.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -namespace Elsa.Activities.Jobs.Models; +namespace Elsa.Jobs.Activities.Models; public record EnqueuedJobPayload { diff --git a/src/modules/Elsa.Activities.Jobs/Services/IJobRegistry.cs b/src/modules/Elsa.Jobs.Activities/Services/IJobRegistry.cs similarity index 79% rename from src/modules/Elsa.Activities.Jobs/Services/IJobRegistry.cs rename to src/modules/Elsa.Jobs.Activities/Services/IJobRegistry.cs index 85db48071..a973291c6 100644 --- a/src/modules/Elsa.Activities.Jobs/Services/IJobRegistry.cs +++ b/src/modules/Elsa.Jobs.Activities/Services/IJobRegistry.cs @@ -1,4 +1,4 @@ -namespace Elsa.Activities.Jobs.Services; +namespace Elsa.Jobs.Activities.Services; /// /// Represents a registry of jobs. diff --git a/src/common/Elsa.Jobs.Abstractions/Abstractions/Job.cs b/src/modules/Elsa.Jobs/Abstractions/Job.cs similarity index 87% rename from src/common/Elsa.Jobs.Abstractions/Abstractions/Job.cs rename to src/modules/Elsa.Jobs/Abstractions/Job.cs index df6230968..03cb214c8 100644 --- a/src/common/Elsa.Jobs.Abstractions/Abstractions/Job.cs +++ b/src/modules/Elsa.Jobs/Abstractions/Job.cs @@ -4,6 +4,9 @@ using Elsa.Jobs.Services; namespace Elsa.Jobs.Abstractions; +/// +/// A base class for job implementations. +/// public abstract class Job : IJob { public string Id { get; set; } = default!; diff --git a/src/common/Elsa.Jobs.Abstractions/Elsa.Jobs.Abstractions.csproj b/src/modules/Elsa.Jobs/Elsa.Jobs.csproj similarity index 80% rename from src/common/Elsa.Jobs.Abstractions/Elsa.Jobs.Abstractions.csproj rename to src/modules/Elsa.Jobs/Elsa.Jobs.csproj index af9c3eba4..6de17f7a7 100644 --- a/src/common/Elsa.Jobs.Abstractions/Elsa.Jobs.Abstractions.csproj +++ b/src/modules/Elsa.Jobs/Elsa.Jobs.csproj @@ -8,11 +8,13 @@ + + diff --git a/src/modules/Elsa.Jobs/Extensions/ModuleExtensions.cs b/src/modules/Elsa.Jobs/Extensions/ModuleExtensions.cs new file mode 100644 index 000000000..0385f9807 --- /dev/null +++ b/src/modules/Elsa.Jobs/Extensions/ModuleExtensions.cs @@ -0,0 +1,26 @@ +using System; +using System.Threading.Channels; +using Elsa.Features.Services; +using Elsa.Jobs.Features; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Jobs.Extensions; + +public static class ModuleExtensions +{ + public static IModule UseJobs(this IModule module, Action? configure = default ) + { + module.Configure(configure); + return module; + } + + public static IServiceCollection CreateChannel(this IServiceCollection services) => + services + .AddSingleton(CreateChannel()) + .AddSingleton(CreateChannelReader) + .AddSingleton(CreateChannelWriter); + + private static Channel CreateChannel() => Channel.CreateUnbounded(new UnboundedChannelOptions()); + private static ChannelReader CreateChannelReader(IServiceProvider serviceProvider) => serviceProvider.GetRequiredService>().Reader; + private static ChannelWriter CreateChannelWriter(IServiceProvider serviceProvider) => serviceProvider.GetRequiredService>().Writer; +} \ No newline at end of file diff --git a/src/modules/Elsa.Jobs/Features/JobsFeature.cs b/src/modules/Elsa.Jobs/Features/JobsFeature.cs new file mode 100644 index 000000000..ef9ed0c34 --- /dev/null +++ b/src/modules/Elsa.Jobs/Features/JobsFeature.cs @@ -0,0 +1,44 @@ +using System; +using Elsa.Common.Features; +using Elsa.Features.Abstractions; +using Elsa.Features.Attributes; +using Elsa.Features.Services; +using Elsa.Jobs.Extensions; +using Elsa.Jobs.HostedServices; +using Elsa.Jobs.Implementations; +using Elsa.Jobs.Services; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Jobs.Features; + +[DependsOn(typeof(SystemClockFeature))] +public class JobsFeature : FeatureBase +{ + public JobsFeature(IModule module) : base(module) + { + } + + public Func JobQueueFactory { get; set; } = ActivatorUtilities.GetServiceOrCreateInstance; + public Func JobSchedulerFactory { get; set; } = ActivatorUtilities.GetServiceOrCreateInstance; + + public override void Configure() + { + Services + .AddSingleton() + .AddSingleton() + .AddSingleton(); + } + + public override void ConfigureHostedServices() + { + Services.AddHostedService(); + } + + public override void Apply() + { + Services + .AddSingleton(JobQueueFactory) + .AddSingleton(JobSchedulerFactory) + .CreateChannel(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Jobs/HostedServices/JobQueueHostedService.cs b/src/modules/Elsa.Jobs/HostedServices/JobQueueHostedService.cs new file mode 100644 index 000000000..2906c5c3d --- /dev/null +++ b/src/modules/Elsa.Jobs/HostedServices/JobQueueHostedService.cs @@ -0,0 +1,41 @@ +using System; +using System.Threading; +using System.Threading.Channels; +using System.Threading.Tasks; +using Elsa.Jobs.Services; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace Elsa.Jobs.HostedServices; + +/// +/// Continuously reads from a channel to which jobs can be sent, executing each received job. +/// +public class JobQueueHostedService : BackgroundService +{ + private readonly ChannelReader _channelReader; + private readonly IJobRunner _jobRunner; + private readonly ILogger _logger; + + public JobQueueHostedService(ChannelReader channelReader, IJobRunner jobRunner, ILogger logger) + { + _channelReader = channelReader; + _jobRunner = jobRunner; + _logger = logger; + } + + protected override async Task ExecuteAsync(CancellationToken cancellationToken) + { + await foreach (var job in _channelReader.ReadAllAsync(cancellationToken)) + { + try + { + await _jobRunner.RunJobAsync(job, cancellationToken); + } + catch (Exception e) + { + _logger.LogError(e, "An unhandled exception occured while running a job"); + } + } + } +} \ No newline at end of file diff --git a/src/common/Elsa.Jobs.Abstractions/Implementations/JobFactory.cs b/src/modules/Elsa.Jobs/Implementations/JobFactory.cs similarity index 83% rename from src/common/Elsa.Jobs.Abstractions/Implementations/JobFactory.cs rename to src/modules/Elsa.Jobs/Implementations/JobFactory.cs index 555120ede..8338c3f5b 100644 --- a/src/common/Elsa.Jobs.Abstractions/Implementations/JobFactory.cs +++ b/src/modules/Elsa.Jobs/Implementations/JobFactory.cs @@ -1,6 +1,7 @@ using System; +using Elsa.Jobs.Services; -namespace Elsa.Jobs.Services; +namespace Elsa.Jobs.Implementations; public class JobFactory : IJobFactory { diff --git a/src/common/Elsa.Jobs.Abstractions/Implementations/JobRunner.cs b/src/modules/Elsa.Jobs/Implementations/JobRunner.cs similarity index 100% rename from src/common/Elsa.Jobs.Abstractions/Implementations/JobRunner.cs rename to src/modules/Elsa.Jobs/Implementations/JobRunner.cs diff --git a/src/common/Elsa.Jobs.Abstractions/Implementations/JobSerializer.cs b/src/modules/Elsa.Jobs/Implementations/JobSerializer.cs similarity index 100% rename from src/common/Elsa.Jobs.Abstractions/Implementations/JobSerializer.cs rename to src/modules/Elsa.Jobs/Implementations/JobSerializer.cs diff --git a/src/modules/Elsa.Jobs/Implementations/LocalJobQueue.cs b/src/modules/Elsa.Jobs/Implementations/LocalJobQueue.cs new file mode 100644 index 000000000..7f3d63faf --- /dev/null +++ b/src/modules/Elsa.Jobs/Implementations/LocalJobQueue.cs @@ -0,0 +1,24 @@ +using System.Threading; +using System.Threading.Channels; +using System.Threading.Tasks; +using Elsa.Jobs.Services; + +namespace Elsa.Jobs.Implementations; + +/// +/// Represents a local, in-memory queue of jobs that will be processed in-process. +/// +public class LocalJobQueue : IJobQueue +{ + private readonly ChannelWriter _channelWriter; + + public LocalJobQueue(ChannelWriter channelWriter) + { + _channelWriter = channelWriter; + } + + public async Task SubmitJobAsync(IJob job, string? queueName = default, CancellationToken cancellationToken = default) + { + await _channelWriter.WriteAsync(job, cancellationToken); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Jobs/Implementations/LocalJobScheduler.cs b/src/modules/Elsa.Jobs/Implementations/LocalJobScheduler.cs new file mode 100644 index 000000000..6e9ed857b --- /dev/null +++ b/src/modules/Elsa.Jobs/Implementations/LocalJobScheduler.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Elsa.Common.Services; +using Elsa.Jobs.ScheduledJobs; +using Elsa.Jobs.Schedules; +using Elsa.Jobs.Services; + +namespace Elsa.Jobs.Implementations; + +public class LocalJobScheduler : IJobScheduler +{ + private readonly ISystemClock _systemClock; + private readonly IJobRunner _jobRunner; + private readonly IDictionary _scheduledJobs = new Dictionary(); + + public LocalJobScheduler(ISystemClock systemClock, IJobRunner jobRunner) + { + _systemClock = systemClock; + _jobRunner = jobRunner; + } + + public Task ScheduleAsync(IJob job, string name, ISchedule schedule, string[]? groupKeys = default, CancellationToken cancellationToken = default) + { + switch (schedule) + { + case CronSchedule cronSchedule: + { + var scheduledJob = new ScheduledCronJob(name, job, _systemClock, cronSchedule.CronExpression, _jobRunner, cancellationToken); + RegisterScheduledJob(scheduledJob); + break; + } + case RecurringSchedule recurringSchedule: + { + var scheduledJob = new ScheduledRecurringJob(name, job, _systemClock, recurringSchedule.StartAt, recurringSchedule.Interval, _jobRunner, cancellationToken); + RegisterScheduledJob(scheduledJob); + break; + } + case SpecificInstantSchedule specificInstantSchedule: + { + var scheduledJob = new ScheduledSpecificInstantJob(name, job, _systemClock, specificInstantSchedule.DateTime, _jobRunner, cancellationToken); + RegisterScheduledJob(scheduledJob); + break; + } + default: + throw new NotSupportedException($"Schedule of type {schedule.GetType()} is not supported."); + } + + return Task.CompletedTask; + } + + private void RegisterScheduledJob(IScheduledJob scheduledJob) + { + if (_scheduledJobs.TryGetValue(scheduledJob.Name, out var existingScheduledJob)) existingScheduledJob.Cancel(); + _scheduledJobs[scheduledJob.Name] = scheduledJob; + } + + public Task UnscheduleAsync(string name, CancellationToken cancellationToken = default) + { + if (_scheduledJobs.TryGetValue(name, out var existingScheduledJob)) existingScheduledJob.Cancel(); + return Task.CompletedTask; + } + + public Task ClearAsync(string[]? groupKeys = default, CancellationToken cancellationToken = default) + { + foreach (var scheduledJob in _scheduledJobs.Values) scheduledJob.Cancel(); + + _scheduledJobs.Clear(); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/src/common/Elsa.Jobs.Abstractions/Models/JobExecutionContext.cs b/src/modules/Elsa.Jobs/Models/JobExecutionContext.cs similarity index 100% rename from src/common/Elsa.Jobs.Abstractions/Models/JobExecutionContext.cs rename to src/modules/Elsa.Jobs/Models/JobExecutionContext.cs diff --git a/src/common/Elsa.Jobs.Abstractions/Notifications/JobExecuted.cs b/src/modules/Elsa.Jobs/Notifications/JobExecuted.cs similarity index 100% rename from src/common/Elsa.Jobs.Abstractions/Notifications/JobExecuted.cs rename to src/modules/Elsa.Jobs/Notifications/JobExecuted.cs diff --git a/src/modules/Elsa.Jobs/ScheduledJobs/ScheduledCronJob.cs b/src/modules/Elsa.Jobs/ScheduledJobs/ScheduledCronJob.cs new file mode 100644 index 000000000..0ca2039d5 --- /dev/null +++ b/src/modules/Elsa.Jobs/ScheduledJobs/ScheduledCronJob.cs @@ -0,0 +1,59 @@ +using System.Threading; +using Cronos; +using Elsa.Common.Services; +using Elsa.Jobs.Services; +using Timer = System.Timers.Timer; + +namespace Elsa.Jobs.ScheduledJobs; + +public class ScheduledCronJob : IScheduledJob +{ + private readonly IJob _job; + private readonly ISystemClock _systemClock; + private readonly IJobRunner _jobRunner; + private readonly CronExpression _parsedCronExpression; + private readonly CancellationToken _cancellationToken; + private Timer? _timer; + + public ScheduledCronJob(string name, IJob job, ISystemClock systemClock, string cronExpression, IJobRunner jobRunner, CancellationToken cancellationToken) + { + Name = name; + + _job = job; + _systemClock = systemClock; + _parsedCronExpression = CronExpression.Parse(cronExpression); + _jobRunner = jobRunner; + _cancellationToken = cancellationToken; + + Schedule(); + } + + public string Name { get; set; } + public void Cancel() => _timer?.Dispose(); + + private void Schedule() + { + var now = _systemClock.UtcNow; + var parsedCronExpression = _parsedCronExpression; + var nextOccurence = parsedCronExpression.GetNextOccurrence(now.UtcDateTime)!; + + var delay = nextOccurence.Value - now; + + if (delay.Milliseconds <= 0) + { + Schedule(); + return; + } + + _timer = new Timer(delay.TotalMilliseconds); + + _timer.Elapsed += async (_, _) => + { + _timer.Dispose(); + _timer = null; + + if (!_cancellationToken.IsCancellationRequested) await _jobRunner.RunJobAsync(_job, _cancellationToken); + if (!_cancellationToken.IsCancellationRequested) Schedule(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Jobs/ScheduledJobs/ScheduledRecurringJob.cs b/src/modules/Elsa.Jobs/ScheduledJobs/ScheduledRecurringJob.cs new file mode 100644 index 000000000..e6a21bf03 --- /dev/null +++ b/src/modules/Elsa.Jobs/ScheduledJobs/ScheduledRecurringJob.cs @@ -0,0 +1,58 @@ +using System; +using System.Threading; +using Elsa.Common.Services; +using Elsa.Jobs.Services; +using Timer = System.Timers.Timer; + +namespace Elsa.Jobs.ScheduledJobs; + +public class ScheduledRecurringJob : IScheduledJob +{ + private readonly IJob _job; + private readonly ISystemClock _systemClock; + private readonly TimeSpan _interval; + private readonly IJobRunner _jobRunner; + private readonly CancellationToken _cancellationToken; + private DateTimeOffset _startAt; + private Timer? _timer; + + public ScheduledRecurringJob(string name, IJob job, ISystemClock systemClock, DateTimeOffset startAt, TimeSpan interval, IJobRunner jobRunner, CancellationToken cancellationToken) + { + Name = name; + _job = job; + _systemClock = systemClock; + _startAt = startAt; + _interval = interval; + _jobRunner = jobRunner; + _cancellationToken = cancellationToken; + + Schedule(); + } + + public string Name { get; set; } + public void Cancel() => _timer?.Dispose(); + + private void Schedule() + { + var now = _systemClock.UtcNow; + var delay = now - _startAt; + + if (delay.Milliseconds <= 0) + { + Schedule(); + return; + } + + _timer = new Timer(delay.TotalMilliseconds); + + _timer.Elapsed += async (_, _) => + { + _timer.Dispose(); + _timer = null; + _startAt = now + _interval; + + if (!_cancellationToken.IsCancellationRequested) await _jobRunner.RunJobAsync(_job, _cancellationToken); + if (!_cancellationToken.IsCancellationRequested) Schedule(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Jobs/ScheduledJobs/ScheduledSpecificInstantJob.cs b/src/modules/Elsa.Jobs/ScheduledJobs/ScheduledSpecificInstantJob.cs new file mode 100644 index 000000000..d19e60081 --- /dev/null +++ b/src/modules/Elsa.Jobs/ScheduledJobs/ScheduledSpecificInstantJob.cs @@ -0,0 +1,51 @@ +using System; +using System.Threading; +using Elsa.Common.Services; +using Elsa.Jobs.Services; +using Timer = System.Timers.Timer; + +namespace Elsa.Jobs.ScheduledJobs; + +public class ScheduledSpecificInstantJob : IScheduledJob +{ + private readonly IJob _job; + private readonly ISystemClock _systemClock; + private readonly DateTimeOffset _startAt; + private readonly IJobRunner _jobRunner; + private readonly CancellationToken _cancellationToken; + private Timer? _timer; + + public ScheduledSpecificInstantJob(string name, IJob job, ISystemClock systemClock, DateTimeOffset startAt, IJobRunner jobRunner, CancellationToken cancellationToken) + { + _job = job; + _systemClock = systemClock; + _startAt = startAt; + _jobRunner = jobRunner; + _cancellationToken = cancellationToken; + Name = name; + + Schedule(); + } + + public string Name { get; set; } + public void Cancel() => _timer?.Dispose(); + + private void Schedule() + { + var now = _systemClock.UtcNow; + var delay = now - _startAt; + + if (delay.Milliseconds <= 0) + delay = TimeSpan.Zero; + + _timer = new Timer(delay.TotalMilliseconds); + + _timer.Elapsed += async (_, _) => + { + _timer.Dispose(); + _timer = null; + + if (!_cancellationToken.IsCancellationRequested) await _jobRunner.RunJobAsync(_job, _cancellationToken); + }; + } +} \ No newline at end of file diff --git a/src/common/Elsa.Jobs.Abstractions/Schedules/CronSchedule.cs b/src/modules/Elsa.Jobs/Schedules/CronSchedule.cs similarity index 100% rename from src/common/Elsa.Jobs.Abstractions/Schedules/CronSchedule.cs rename to src/modules/Elsa.Jobs/Schedules/CronSchedule.cs diff --git a/src/common/Elsa.Jobs.Abstractions/Schedules/RecurringSchedule.cs b/src/modules/Elsa.Jobs/Schedules/RecurringSchedule.cs similarity index 100% rename from src/common/Elsa.Jobs.Abstractions/Schedules/RecurringSchedule.cs rename to src/modules/Elsa.Jobs/Schedules/RecurringSchedule.cs diff --git a/src/common/Elsa.Jobs.Abstractions/Schedules/SpecificInstantSchedule.cs b/src/modules/Elsa.Jobs/Schedules/SpecificInstantSchedule.cs similarity index 100% rename from src/common/Elsa.Jobs.Abstractions/Schedules/SpecificInstantSchedule.cs rename to src/modules/Elsa.Jobs/Schedules/SpecificInstantSchedule.cs diff --git a/src/common/Elsa.Jobs.Abstractions/Services/IJob.cs b/src/modules/Elsa.Jobs/Services/IJob.cs similarity index 69% rename from src/common/Elsa.Jobs.Abstractions/Services/IJob.cs rename to src/modules/Elsa.Jobs/Services/IJob.cs index beb756e5b..9efa49991 100644 --- a/src/common/Elsa.Jobs.Abstractions/Services/IJob.cs +++ b/src/modules/Elsa.Jobs/Services/IJob.cs @@ -3,6 +3,9 @@ using Elsa.Jobs.Models; namespace Elsa.Jobs.Services; +/// +/// Implemented by types that represent a background job. +/// public interface IJob { string Id { get; set; } diff --git a/src/common/Elsa.Jobs.Abstractions/Services/IJobFactory.cs b/src/modules/Elsa.Jobs/Services/IJobFactory.cs similarity index 52% rename from src/common/Elsa.Jobs.Abstractions/Services/IJobFactory.cs rename to src/modules/Elsa.Jobs/Services/IJobFactory.cs index 9d5232ad2..35ca4d4f8 100644 --- a/src/common/Elsa.Jobs.Abstractions/Services/IJobFactory.cs +++ b/src/modules/Elsa.Jobs/Services/IJobFactory.cs @@ -3,9 +3,12 @@ using System; namespace Elsa.Jobs.Services; /// -/// Instantiates new jobs of a given type. +/// Instantiates jobs of a given type. /// public interface IJobFactory { + /// + /// Instantiates a job of the specified type. + /// IJob Create(Type jobType); } \ No newline at end of file diff --git a/src/common/Elsa.Jobs.Abstractions/Services/IJobQueue.cs b/src/modules/Elsa.Jobs/Services/IJobQueue.cs similarity index 63% rename from src/common/Elsa.Jobs.Abstractions/Services/IJobQueue.cs rename to src/modules/Elsa.Jobs/Services/IJobQueue.cs index 7fcf0a2b6..ea5fb5a9e 100644 --- a/src/common/Elsa.Jobs.Abstractions/Services/IJobQueue.cs +++ b/src/modules/Elsa.Jobs/Services/IJobQueue.cs @@ -8,5 +8,5 @@ namespace Elsa.Jobs.Services; /// public interface IJobQueue { - Task SubmitJobAsync(IJob job, string? queueName = default, CancellationToken cancellationToken = default); + Task SubmitJobAsync(IJob job, string? queueName = default, CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/src/common/Elsa.Jobs.Abstractions/Services/IJobRunner.cs b/src/modules/Elsa.Jobs/Services/IJobRunner.cs similarity index 61% rename from src/common/Elsa.Jobs.Abstractions/Services/IJobRunner.cs rename to src/modules/Elsa.Jobs/Services/IJobRunner.cs index 3dd9988ff..a6c3ef172 100644 --- a/src/common/Elsa.Jobs.Abstractions/Services/IJobRunner.cs +++ b/src/modules/Elsa.Jobs/Services/IJobRunner.cs @@ -3,7 +3,13 @@ using System.Threading.Tasks; namespace Elsa.Jobs.Services; +/// +/// Runs specified jobs. +/// public interface IJobRunner { + /// + /// Runs the specified job. + /// Task RunJobAsync(IJob job, CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/src/common/Elsa.Jobs.Abstractions/Services/IJobScheduler.cs b/src/modules/Elsa.Jobs/Services/IJobScheduler.cs similarity index 100% rename from src/common/Elsa.Jobs.Abstractions/Services/IJobScheduler.cs rename to src/modules/Elsa.Jobs/Services/IJobScheduler.cs diff --git a/src/common/Elsa.Jobs.Abstractions/Services/IJobSerializer.cs b/src/modules/Elsa.Jobs/Services/IJobSerializer.cs similarity index 100% rename from src/common/Elsa.Jobs.Abstractions/Services/IJobSerializer.cs rename to src/modules/Elsa.Jobs/Services/IJobSerializer.cs diff --git a/src/common/Elsa.Jobs.Abstractions/Services/ISchedule.cs b/src/modules/Elsa.Jobs/Services/ISchedule.cs similarity index 100% rename from src/common/Elsa.Jobs.Abstractions/Services/ISchedule.cs rename to src/modules/Elsa.Jobs/Services/ISchedule.cs diff --git a/src/modules/Elsa.Jobs/Services/IScheduledJob.cs b/src/modules/Elsa.Jobs/Services/IScheduledJob.cs new file mode 100644 index 000000000..cb61d0713 --- /dev/null +++ b/src/modules/Elsa.Jobs/Services/IScheduledJob.cs @@ -0,0 +1,7 @@ +namespace Elsa.Jobs.Services; + +internal interface IScheduledJob +{ + string Name { get; set; } + void Cancel(); +} \ No newline at end of file diff --git a/src/modules/Elsa.MassTransit/Extensions/DependencyInjectionExtensions.cs b/src/modules/Elsa.MassTransit/Extensions/DependencyInjectionExtensions.cs deleted file mode 100644 index 455ae06da..000000000 --- a/src/modules/Elsa.MassTransit/Extensions/DependencyInjectionExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Elsa.MassTransit.Implementations; -using Elsa.Workflows.Runtime.Services; -using Microsoft.Extensions.DependencyInjection; - -namespace Elsa.MassTransit.Extensions; - -public static class DependencyInjectionExtensions -{ - public static IServiceCollection AddMassTransitServices(this IServiceCollection services) - { - return services.AddSingleton(); - } -} \ No newline at end of file diff --git a/src/modules/Elsa.MassTransit/Extensions/ModuleExtensions.cs b/src/modules/Elsa.MassTransit/Extensions/ModuleExtensions.cs new file mode 100644 index 000000000..6f79c3354 --- /dev/null +++ b/src/modules/Elsa.MassTransit/Extensions/ModuleExtensions.cs @@ -0,0 +1,13 @@ +using Elsa.Features.Services; +using Elsa.MassTransit.Features; + +namespace Elsa.MassTransit.Extensions; + +public static class ModuleExtensions +{ + public static IModule AddMassTransitWorkflowDispatchers(this IModule module) + { + module.Configure(); + return module; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.MassTransit/Features/MassTransitDispatchersFeature.cs b/src/modules/Elsa.MassTransit/Features/MassTransitDispatchersFeature.cs new file mode 100644 index 000000000..7becd7fab --- /dev/null +++ b/src/modules/Elsa.MassTransit/Features/MassTransitDispatchersFeature.cs @@ -0,0 +1,22 @@ +using Elsa.Features.Abstractions; +using Elsa.Features.Attributes; +using Elsa.Features.Services; +using Elsa.MassTransit.Implementations; +using Elsa.Workflows.Runtime.Features; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.MassTransit.Features; + +[DependsOn(typeof(WorkflowRuntimeFeature))] +[DependsOn(typeof(MassTransitServiceBusFeature))] +public class MassTransitDispatchersFeature : FeatureBase +{ + public MassTransitDispatchersFeature(IModule module) : base(module) + { + } + + public override void Configure() + { + Module.Configure(f => f.WorkflowDispatcherFactory = ActivatorUtilities.GetServiceOrCreateInstance); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.MassTransit/Features/MassTransitServiceBusFeature.cs b/src/modules/Elsa.MassTransit/Features/MassTransitServiceBusFeature.cs new file mode 100644 index 000000000..7c12cbcb7 --- /dev/null +++ b/src/modules/Elsa.MassTransit/Features/MassTransitServiceBusFeature.cs @@ -0,0 +1,19 @@ +using Elsa.Features.Abstractions; +using Elsa.Features.Services; +using Elsa.MassTransit.Implementations; +using Elsa.ServiceBus.Abstractions.Services; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.MassTransit.Features; + +public class MassTransitServiceBusFeature : FeatureBase +{ + public MassTransitServiceBusFeature(IModule module) : base(module) + { + } + + public override void Apply() + { + Services.AddSingleton(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.MassTransit/Implementations/MassTransitServiceBusProvider.cs b/src/modules/Elsa.MassTransit/Implementations/MassTransitServiceBusProvider.cs deleted file mode 100644 index fe9754e58..000000000 --- a/src/modules/Elsa.MassTransit/Implementations/MassTransitServiceBusProvider.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Elsa.ServiceBus.Abstractions.Services; -using Microsoft.Extensions.DependencyInjection; - -namespace Elsa.MassTransit.Implementations; - -/// -/// A MassTransit implementation for . -/// -public class MassTransitServiceBusProvider : IServiceBusProvider -{ - public void ConfigureServices(IServiceCollection services) - { - services - .AddSingleton(); - } -} \ No newline at end of file diff --git a/src/modules/Elsa.Mediator/Elsa.Mediator.csproj b/src/modules/Elsa.Mediator/Elsa.Mediator.csproj index 4acb383cb..3999c6973 100644 --- a/src/modules/Elsa.Mediator/Elsa.Mediator.csproj +++ b/src/modules/Elsa.Mediator/Elsa.Mediator.csproj @@ -8,6 +8,7 @@ + diff --git a/src/modules/Elsa.Mediator/Extensions/DependencyInjectionExtensions.cs b/src/modules/Elsa.Mediator/Extensions/DependencyInjectionExtensions.cs index a328e86ba..019be8f98 100644 --- a/src/modules/Elsa.Mediator/Extensions/DependencyInjectionExtensions.cs +++ b/src/modules/Elsa.Mediator/Extensions/DependencyInjectionExtensions.cs @@ -1,4 +1,5 @@ using System.Reflection; +using System.Threading.Channels; using Elsa.Mediator.Implementations; using Elsa.Mediator.Middleware.Command; using Elsa.Mediator.Middleware.Command.Contracts; @@ -10,6 +11,7 @@ using Elsa.Mediator.Models; using Elsa.Mediator.Services; using Elsa.Features.Services; using Elsa.Mediator.Features; +using Elsa.Mediator.HostedServices; using Microsoft.Extensions.DependencyInjection; namespace Elsa.Mediator.Extensions; @@ -29,9 +31,16 @@ public static class DependencyInjectionExtensions .AddSingleton(sp => sp.GetRequiredService()) .AddSingleton(sp => sp.GetRequiredService()) .AddSingleton(sp => sp.GetRequiredService()) + .AddSingleton() + .AddSingleton() .AddSingleton() .AddSingleton() - .AddSingleton(); + .AddSingleton() + .AddHostedService() + .AddHostedService() + .CreateChannel() + .CreateChannel() + ; } public static IServiceCollection AddCommandHandler(this IServiceCollection services) @@ -76,6 +85,12 @@ public static class DependencyInjectionExtensions public static IServiceCollection AddCommandHandlersFrom(this IServiceCollection services, Type markerType) => services.AddHandlersFromInternal(markerType); public static IServiceCollection AddCommandHandlersFrom(this IServiceCollection services, Assembly assembly) => services.AddHandlersFromInternal(assembly); + public static IServiceCollection CreateChannel(this IServiceCollection services) => + services + .AddSingleton(CreateChannel()) + .AddSingleton(CreateChannelReader) + .AddSingleton(CreateChannelWriter); + private static IServiceCollection AddHandlersFromInternal(this IServiceCollection services) => services.AddHandlersFromInternal(typeof(TMarker)); private static IServiceCollection AddHandlersFromInternal(this IServiceCollection services, Type assemblyMarkerType) => services.AddHandlersFromInternal(assemblyMarkerType.Assembly); @@ -90,4 +105,8 @@ public static class DependencyInjectionExtensions return services; } + + private static Channel CreateChannel() => Channel.CreateUnbounded(new UnboundedChannelOptions()); + private static ChannelReader CreateChannelReader(IServiceProvider serviceProvider) => serviceProvider.GetRequiredService>().Reader; + private static ChannelWriter CreateChannelWriter(IServiceProvider serviceProvider) => serviceProvider.GetRequiredService>().Writer; } \ No newline at end of file diff --git a/src/modules/Elsa.Mediator/HostedServices/BackgroundCommandSenderHostedService.cs b/src/modules/Elsa.Mediator/HostedServices/BackgroundCommandSenderHostedService.cs new file mode 100644 index 000000000..47b160e8a --- /dev/null +++ b/src/modules/Elsa.Mediator/HostedServices/BackgroundCommandSenderHostedService.cs @@ -0,0 +1,38 @@ +using System.Threading.Channels; +using Elsa.Mediator.Services; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace Elsa.Mediator.HostedServices; + +/// +/// Continuously reads from a channel to which commands can be sent, executing each received command. +/// +public class BackgroundCommandSenderHostedService : BackgroundService +{ + private readonly ChannelReader _channelReader; + private readonly ICommandSender _commandSender; + private readonly ILogger _logger; + + public BackgroundCommandSenderHostedService(ChannelReader channelReader, ICommandSender commandSender, ILogger logger) + { + _channelReader = channelReader; + _commandSender = commandSender; + _logger = logger; + } + + protected override async Task ExecuteAsync(CancellationToken cancellationToken) + { + await foreach (var request in _channelReader.ReadAllAsync(cancellationToken)) + { + try + { + await _commandSender.ExecuteAsync(request, cancellationToken); + } + catch (Exception e) + { + _logger.LogError(e, "An unhandled exception occured while processing the queue"); + } + } + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Mediator/HostedServices/BackgroundEventPublisherHostedService.cs b/src/modules/Elsa.Mediator/HostedServices/BackgroundEventPublisherHostedService.cs new file mode 100644 index 000000000..24db7b7fa --- /dev/null +++ b/src/modules/Elsa.Mediator/HostedServices/BackgroundEventPublisherHostedService.cs @@ -0,0 +1,38 @@ +using System.Threading.Channels; +using Elsa.Mediator.Services; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace Elsa.Mediator.HostedServices; + +/// +/// Continuously reads from a channel to which notifications can be sent, publishing each received notification. +/// +public class BackgroundEventPublisherHostedService : BackgroundService +{ + private readonly ChannelReader _channelReader; + private readonly IEventPublisher _eventPublisher; + private readonly ILogger _logger; + + public BackgroundEventPublisherHostedService(ChannelReader channelReader, IEventPublisher eventPublisher, ILogger logger) + { + _channelReader = channelReader; + _eventPublisher = eventPublisher; + _logger = logger; + } + + protected override async Task ExecuteAsync(CancellationToken cancellationToken) + { + await foreach (var notification in _channelReader.ReadAllAsync(cancellationToken)) + { + try + { + await _eventPublisher.PublishAsync(notification, cancellationToken); + } + catch (Exception e) + { + _logger.LogError(e, "An unhandled exception occured while processing the queue"); + } + } + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Mediator/Implementations/BackgroundCommandSender.cs b/src/modules/Elsa.Mediator/Implementations/BackgroundCommandSender.cs new file mode 100644 index 000000000..7848af618 --- /dev/null +++ b/src/modules/Elsa.Mediator/Implementations/BackgroundCommandSender.cs @@ -0,0 +1,11 @@ +using System.Threading.Channels; +using Elsa.Mediator.Services; + +namespace Elsa.Mediator.Implementations; + +public class BackgroundCommandSender : IBackgroundCommandSender +{ + private readonly ChannelWriter _channelWriter; + public BackgroundCommandSender(ChannelWriter channelWriter) => _channelWriter = channelWriter; + public async Task SendAsync(ICommand command, CancellationToken cancellationToken = default) => await _channelWriter.WriteAsync(command, cancellationToken); +} \ No newline at end of file diff --git a/src/modules/Elsa.Mediator/Implementations/BackgroundEventPublisher.cs b/src/modules/Elsa.Mediator/Implementations/BackgroundEventPublisher.cs new file mode 100644 index 000000000..a6a79d58a --- /dev/null +++ b/src/modules/Elsa.Mediator/Implementations/BackgroundEventPublisher.cs @@ -0,0 +1,11 @@ +using System.Threading.Channels; +using Elsa.Mediator.Services; + +namespace Elsa.Mediator.Implementations; + +public class BackgroundEventPublisher : IBackgroundEventPublisher +{ + private readonly ChannelWriter _channelWriter; + public BackgroundEventPublisher(ChannelWriter channelWriter) => _channelWriter = channelWriter; + public async Task PublishAsync(INotification notification, CancellationToken cancellationToken = default) => await _channelWriter.WriteAsync(notification, cancellationToken); +} \ No newline at end of file diff --git a/src/modules/Elsa.Mediator/Services/IBackgroundCommandSender.cs b/src/modules/Elsa.Mediator/Services/IBackgroundCommandSender.cs new file mode 100644 index 000000000..e6ce0d283 --- /dev/null +++ b/src/modules/Elsa.Mediator/Services/IBackgroundCommandSender.cs @@ -0,0 +1,12 @@ +namespace Elsa.Mediator.Services; + +/// +/// Send requests to be processed asynchronously in the background. +/// +public interface IBackgroundCommandSender +{ + /// + /// Submits the specified command to a channel writer. The channel is processed asynchronously from a background service. + /// + Task SendAsync(ICommand command, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Mediator/Services/IBackgroundEventPublisher.cs b/src/modules/Elsa.Mediator/Services/IBackgroundEventPublisher.cs new file mode 100644 index 000000000..b21385dbe --- /dev/null +++ b/src/modules/Elsa.Mediator/Services/IBackgroundEventPublisher.cs @@ -0,0 +1,12 @@ +namespace Elsa.Mediator.Services; + +/// +/// Publish notifications to be processed asynchronously in the background. +/// +public interface IBackgroundEventPublisher +{ + /// + /// Publish the specified notification using from a background service. + /// + Task PublishAsync(INotification notification, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.ProtoActor/Grains/WorkflowInstanceGrain.cs b/src/modules/Elsa.ProtoActor/Grains/WorkflowInstanceGrain.cs index af15a3777..aa16ddba2 100644 --- a/src/modules/Elsa.ProtoActor/Grains/WorkflowInstanceGrain.cs +++ b/src/modules/Elsa.ProtoActor/Grains/WorkflowInstanceGrain.cs @@ -12,7 +12,6 @@ using Elsa.Workflows.Core.Serialization; using Elsa.Workflows.Core.Services; using Elsa.Workflows.Core.State; using Elsa.Workflows.Persistence.Entities; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Persistence.Services; using Elsa.Workflows.Runtime.Services; using Proto; diff --git a/src/modules/Elsa.ProtoActor/Implementations/GrainClientFactory.cs b/src/modules/Elsa.ProtoActor/Implementations/GrainClientFactory.cs index 63d76de6c..b09b7b437 100644 --- a/src/modules/Elsa.ProtoActor/Implementations/GrainClientFactory.cs +++ b/src/modules/Elsa.ProtoActor/Implementations/GrainClientFactory.cs @@ -1,6 +1,5 @@ using Elsa.Persistence.Common.Models; using Elsa.Runtime.Protos; -using Elsa.Workflows.Persistence.Models; using Proto.Cluster; namespace Elsa.ProtoActor.Implementations; diff --git a/src/modules/Elsa.ProtoActor/Implementations/ProtoActorWorkflowInvoker.cs b/src/modules/Elsa.ProtoActor/Implementations/ProtoActorWorkflowInvoker.cs index 0fa3acded..537cd8af3 100644 --- a/src/modules/Elsa.ProtoActor/Implementations/ProtoActorWorkflowInvoker.cs +++ b/src/modules/Elsa.ProtoActor/Implementations/ProtoActorWorkflowInvoker.cs @@ -11,7 +11,6 @@ using Elsa.Workflows.Core.Models; using Elsa.Workflows.Core.Serialization; using Elsa.Workflows.Core.State; using Elsa.Workflows.Persistence.Entities; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Runtime.Models; using Elsa.Workflows.Runtime.Services; using Proto; diff --git a/src/modules/Elsa.Quartz/Elsa.Quartz.csproj b/src/modules/Elsa.Quartz/Elsa.Quartz.csproj index faf77ed30..233bf88af 100644 --- a/src/modules/Elsa.Quartz/Elsa.Quartz.csproj +++ b/src/modules/Elsa.Quartz/Elsa.Quartz.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/modules/Elsa.Quartz/Features/QuartzFeature.cs b/src/modules/Elsa.Quartz/Features/QuartzFeature.cs new file mode 100644 index 000000000..42ca1e320 --- /dev/null +++ b/src/modules/Elsa.Quartz/Features/QuartzFeature.cs @@ -0,0 +1,48 @@ +using Elsa.Features.Abstractions; +using Elsa.Features.Services; +using Elsa.Quartz.Extensions; +using Microsoft.Extensions.DependencyInjection; +using Quartz; + +namespace Elsa.Quartz.Features; + +public class QuartzFeature : FeatureBase +{ + public QuartzFeature(IModule module) : base(module) + { + } + + public Action? ConfigureQuartzOptions { get; set; } + public Action? ConfigureQuartz { get; set; } + public Action? ConfigureQuartzHostedService { get; set; } + + public override void Configure() + { + if (ConfigureQuartzOptions != null) + Services.Configure(ConfigureQuartzOptions); + + Services + .AddQuartz(configure => + { + ConfigureQuartzInternal(configure, ConfigureQuartz); + configure.AddElsaJobs(); + }); + } + + public override void ConfigureHostedServices() + { + Services.AddQuartzHostedService(options => + { + options.WaitForJobsToComplete = true; + ConfigureQuartzHostedService?.Invoke(options); + }); + } + + private static void ConfigureQuartzInternal(IServiceCollectionQuartzConfigurator quartz, Action? configureQuartz) + { + quartz.UseMicrosoftDependencyInjectionJobFactory(); + quartz.UseSimpleTypeLoader(); + quartz.UseInMemoryStore(); + configureQuartz?.Invoke(quartz); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Quartz/Features/QuartzSchedulerFeature.cs b/src/modules/Elsa.Quartz/Features/QuartzSchedulerFeature.cs new file mode 100644 index 000000000..12d76618a --- /dev/null +++ b/src/modules/Elsa.Quartz/Features/QuartzSchedulerFeature.cs @@ -0,0 +1,22 @@ +using Elsa.Features.Abstractions; +using Elsa.Features.Attributes; +using Elsa.Features.Services; +using Elsa.Jobs.Features; +using Elsa.Quartz.Implementations; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Quartz.Features; + +[DependsOn(typeof(JobsFeature))] +[DependsOn(typeof(QuartzFeature))] +public class QuartzSchedulerFeature : FeatureBase +{ + public QuartzSchedulerFeature(IModule module) : base(module) + { + } + + public override void Configure() + { + Module.Configure(f => f.JobSchedulerFactory = ActivatorUtilities.GetServiceOrCreateInstance); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Quartz/Implementations/QuartzJobScheduler.cs b/src/modules/Elsa.Quartz/Implementations/QuartzJobScheduler.cs index 9c7f7d890..5749deccc 100644 --- a/src/modules/Elsa.Quartz/Implementations/QuartzJobScheduler.cs +++ b/src/modules/Elsa.Quartz/Implementations/QuartzJobScheduler.cs @@ -87,7 +87,7 @@ public class QuartzJobScheduler : IJobScheduler } default: - throw new NotSupportedException($"Schedule of type {schedule.GetType()} is not supported. But if you create an issue, we'll make this logic extensible & replaceable :)"); + throw new NotSupportedException($"Schedule of type {schedule.GetType()} is not supported."); } return builder.Build(); diff --git a/src/modules/Elsa.Quartz/Implementations/QuartzJobSchedulerProvider.cs b/src/modules/Elsa.Quartz/Implementations/QuartzJobSchedulerProvider.cs deleted file mode 100644 index 17a916963..000000000 --- a/src/modules/Elsa.Quartz/Implementations/QuartzJobSchedulerProvider.cs +++ /dev/null @@ -1,80 +0,0 @@ -using Elsa.Jobs.Services; -using Elsa.Quartz.Extensions; -using Microsoft.Extensions.DependencyInjection; -using Quartz; - -namespace Elsa.Quartz.Implementations; - -/// -/// A Quartz.NET implementation for . -/// -public class QuartzJobSchedulerProvider : IJobSchedulerProvider -{ - public QuartzJobSchedulerProvider(bool registerQuartz = true) - { - RegisterQuartz = registerQuartz; - } - - public QuartzJobSchedulerProvider(Action configureQuartzOptions) - { - RegisterQuartz = true; - ConfigureQuartzOptions = configureQuartzOptions; - } - - public QuartzJobSchedulerProvider( - Action configureQuartzOptions, - Action configureQuartz) - { - RegisterQuartz = true; - ConfigureQuartzOptions = configureQuartzOptions; - ConfigureQuartz = configureQuartz; - } - - public QuartzJobSchedulerProvider( - Action configureQuartzOptions, - Action configureQuartz, - Action configureQuartzHostedService) - { - RegisterQuartz = true; - ConfigureQuartzOptions = configureQuartzOptions; - ConfigureQuartz = configureQuartz; - ConfigureQuartzHostedService = configureQuartzHostedService; - } - - public bool RegisterQuartz { get; set; } - public Action? ConfigureQuartzOptions { get; set; } - public Action? ConfigureQuartz { get; set; } - public Action? ConfigureQuartzHostedService { get; set; } - - public void ConfigureServices(IServiceCollection services) - { - if (RegisterQuartz) - { - if (ConfigureQuartzOptions != null) - services.Configure(ConfigureQuartzOptions); - - services - .AddQuartz(configure => - { - ConfigureQuartzInternal(configure, ConfigureQuartz); - configure.AddElsaJobs(); - }) - .AddQuartzHostedService(options => - { - options.WaitForJobsToComplete = true; - ConfigureQuartzHostedService?.Invoke(options); - }); - } - - services.AddSingleton(); - - } - - private static void ConfigureQuartzInternal(IServiceCollectionQuartzConfigurator quartz, Action? configureQuartz) - { - quartz.UseMicrosoftDependencyInjectionJobFactory(); - quartz.UseSimpleTypeLoader(); - quartz.UseInMemoryStore(); - configureQuartz?.Invoke(quartz); - } -} \ No newline at end of file diff --git a/src/modules/Elsa.Scheduling/Activities/Delay.cs b/src/modules/Elsa.Scheduling/Activities/Delay.cs index cae72d253..151fec374 100644 --- a/src/modules/Elsa.Scheduling/Activities/Delay.cs +++ b/src/modules/Elsa.Scheduling/Activities/Delay.cs @@ -1,4 +1,5 @@ using System; +using Elsa.Common.Services; using Elsa.Workflows.Core; using Elsa.Workflows.Core.Attributes; using Elsa.Workflows.Core.Models; diff --git a/src/modules/Elsa.Scheduling/Activities/StartAt.cs b/src/modules/Elsa.Scheduling/Activities/StartAt.cs index 07a02b2bf..a598106c8 100644 --- a/src/modules/Elsa.Scheduling/Activities/StartAt.cs +++ b/src/modules/Elsa.Scheduling/Activities/StartAt.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using Elsa.Common.Services; using Elsa.Expressions.Models; using Elsa.Workflows.Core; using Elsa.Workflows.Core.Attributes; diff --git a/src/modules/Elsa.Scheduling/Activities/Timer.cs b/src/modules/Elsa.Scheduling/Activities/Timer.cs index 34ad1fbd2..299c52e18 100644 --- a/src/modules/Elsa.Scheduling/Activities/Timer.cs +++ b/src/modules/Elsa.Scheduling/Activities/Timer.cs @@ -1,5 +1,6 @@ using System; using System.Text.Json.Serialization; +using Elsa.Common.Services; using Elsa.Workflows.Core; using Elsa.Workflows.Core.Attributes; using Elsa.Workflows.Core.Models; diff --git a/src/modules/Elsa.Scheduling/Elsa.Scheduling.csproj b/src/modules/Elsa.Scheduling/Elsa.Scheduling.csproj index 6c746d054..fb5bbc108 100644 --- a/src/modules/Elsa.Scheduling/Elsa.Scheduling.csproj +++ b/src/modules/Elsa.Scheduling/Elsa.Scheduling.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/modules/Elsa.Scheduling/Extensions/DependencyInjectionExtensions.cs b/src/modules/Elsa.Scheduling/Extensions/DependencyInjectionExtensions.cs deleted file mode 100644 index ad0c8a0d4..000000000 --- a/src/modules/Elsa.Scheduling/Extensions/DependencyInjectionExtensions.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Elsa.Mediator.Extensions; -using Elsa.Scheduling.Implementations; -using Elsa.Scheduling.Services; -using Microsoft.Extensions.DependencyInjection; - -namespace Elsa.Scheduling.Extensions; - -public static class DependencyInjectionExtensions -{ - public static IServiceCollection AddSchedulingServices(this IServiceCollection services) - { - services - .AddSingleton() - .AddSingleton() - .AddNotificationHandlersFrom() - .AddHostedService(); - - return services; - } -} \ No newline at end of file diff --git a/src/modules/Elsa.Scheduling/Extensions/ModuleExtensions.cs b/src/modules/Elsa.Scheduling/Extensions/ModuleExtensions.cs new file mode 100644 index 000000000..9b304a110 --- /dev/null +++ b/src/modules/Elsa.Scheduling/Extensions/ModuleExtensions.cs @@ -0,0 +1,14 @@ +using System; +using Elsa.Features.Services; +using Elsa.Scheduling.Features; + +namespace Elsa.Scheduling.Extensions; + +public static class ModuleExtensions +{ + public static IModule UseScheduling(this IModule module, Action? configure = default ) + { + module.Configure(configure); + return module; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Scheduling/Features/SchedulingFeature.cs b/src/modules/Elsa.Scheduling/Features/SchedulingFeature.cs new file mode 100644 index 000000000..2311ad35d --- /dev/null +++ b/src/modules/Elsa.Scheduling/Features/SchedulingFeature.cs @@ -0,0 +1,32 @@ +using Elsa.Common.Features; +using Elsa.Features.Abstractions; +using Elsa.Features.Attributes; +using Elsa.Features.Services; +using Elsa.Mediator.Extensions; +using Elsa.Scheduling.HostedServices; +using Elsa.Scheduling.Implementations; +using Elsa.Scheduling.Services; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Scheduling.Features; + +[DependsOn(typeof(SystemClockFeature))] +public class SchedulingFeature : FeatureBase +{ + public SchedulingFeature(IModule module) : base(module) + { + } + + public override void ConfigureHostedServices() + { + Services.AddHostedService(); + } + + public override void Apply() + { + Services + .AddSingleton() + .AddSingleton() + .AddNotificationHandlersFrom(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Scheduling/HostedServices/ScheduleWorkflows.cs b/src/modules/Elsa.Scheduling/HostedServices/ScheduleWorkflowsHostedService.cs similarity index 88% rename from src/modules/Elsa.Scheduling/HostedServices/ScheduleWorkflows.cs rename to src/modules/Elsa.Scheduling/HostedServices/ScheduleWorkflowsHostedService.cs index bd9aabba6..2d0317644 100644 --- a/src/modules/Elsa.Scheduling/HostedServices/ScheduleWorkflows.cs +++ b/src/modules/Elsa.Scheduling/HostedServices/ScheduleWorkflowsHostedService.cs @@ -13,12 +13,12 @@ namespace Elsa.Scheduling.HostedServices; /// /// Loads all timer-specific workflow bookmarks from the database and create scheduled jobs for them. /// -public class ScheduleWorkflows : BackgroundService +public class ScheduleWorkflowsHostedService : BackgroundService { private readonly IWorkflowBookmarkStore _bookmarkStore; private readonly IWorkflowBookmarkScheduler _workflowBookmarkScheduler; - public ScheduleWorkflows(IWorkflowBookmarkStore bookmarkStore, IWorkflowBookmarkScheduler workflowBookmarkScheduler) + public ScheduleWorkflowsHostedService(IWorkflowBookmarkStore bookmarkStore, IWorkflowBookmarkScheduler workflowBookmarkScheduler) { _bookmarkStore = bookmarkStore; _workflowBookmarkScheduler = workflowBookmarkScheduler; diff --git a/src/modules/Elsa.Scheduling/Jobs/RunWorkflowJob.cs b/src/modules/Elsa.Scheduling/Jobs/RunWorkflowJob.cs index b3489af1b..95cafb03d 100644 --- a/src/modules/Elsa.Scheduling/Jobs/RunWorkflowJob.cs +++ b/src/modules/Elsa.Scheduling/Jobs/RunWorkflowJob.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using Elsa.Jobs.Abstractions; using Elsa.Jobs.Models; using Elsa.Persistence.Common.Models; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Runtime.Models; using Elsa.Workflows.Runtime.Services; diff --git a/src/modules/Elsa.Workflows.Api/ApiResults/DispatchWorkflowDefinitionResult.cs b/src/modules/Elsa.Workflows.Api/ApiResults/DispatchWorkflowDefinitionResult.cs index d83f72189..fc5b055e3 100644 --- a/src/modules/Elsa.Workflows.Api/ApiResults/DispatchWorkflowDefinitionResult.cs +++ b/src/modules/Elsa.Workflows.Api/ApiResults/DispatchWorkflowDefinitionResult.cs @@ -1,7 +1,6 @@ using System.Net; using System.Threading.Tasks; using Elsa.Persistence.Common.Models; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Runtime.Models; using Elsa.Workflows.Runtime.Services; using Microsoft.AspNetCore.Http; diff --git a/src/modules/Elsa.Workflows.Api/ApiResults/ExecuteWorkflowDefinitionResult.cs b/src/modules/Elsa.Workflows.Api/ApiResults/ExecuteWorkflowDefinitionResult.cs index 8efcc81a1..ffd9f02a6 100644 --- a/src/modules/Elsa.Workflows.Api/ApiResults/ExecuteWorkflowDefinitionResult.cs +++ b/src/modules/Elsa.Workflows.Api/ApiResults/ExecuteWorkflowDefinitionResult.cs @@ -2,7 +2,6 @@ using System.Threading; using System.Threading.Tasks; using Elsa.Persistence.Common.Models; using Elsa.Workflows.Core.Serialization; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Runtime.Models; using Elsa.Workflows.Runtime.Services; using Microsoft.AspNetCore.Http; diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkDelete.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkDelete.cs index 9ab54bfa7..8fb7c668b 100644 --- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkDelete.cs +++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkDelete.cs @@ -5,7 +5,6 @@ using System.Threading.Tasks; using Elsa.AspNetCore.Attributes; using Elsa.Workflows.Core.Serialization; using Elsa.Workflows.Management.Services; -using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkPublish.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkPublish.cs index f53ac255c..af34db6bb 100644 --- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkPublish.cs +++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkPublish.cs @@ -5,7 +5,6 @@ using Elsa.AspNetCore.Attributes; using Elsa.Persistence.Common.Models; using Elsa.Workflows.Core.Serialization; using Elsa.Workflows.Management.Services; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Persistence.Services; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkRetract.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkRetract.cs index a9121cc9e..f6cb402d9 100644 --- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkRetract.cs +++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkRetract.cs @@ -5,7 +5,6 @@ using Elsa.AspNetCore.Attributes; using Elsa.Persistence.Common.Models; using Elsa.Workflows.Core.Serialization; using Elsa.Workflows.Management.Services; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Persistence.Services; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Dispatch.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Dispatch.cs index 0985f8de0..8fdb21035 100644 --- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Dispatch.cs +++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Dispatch.cs @@ -3,7 +3,6 @@ using System.Threading.Tasks; using Elsa.AspNetCore.Attributes; using Elsa.Persistence.Common.Models; using Elsa.Workflows.Api.ApiResults; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Persistence.Services; using Elsa.Workflows.Runtime.Models; using Microsoft.AspNetCore.Http; diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Execute.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Execute.cs index b7e19a11d..175135e59 100644 --- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Execute.cs +++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Execute.cs @@ -4,7 +4,6 @@ using Elsa.AspNetCore.Attributes; using Elsa.Persistence.Common.Models; using Elsa.Workflows.Api.ApiResults; using Elsa.Workflows.Core.Models; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Persistence.Services; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Export.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Export.cs index f09871f79..663d536bc 100644 --- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Export.cs +++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Export.cs @@ -8,7 +8,6 @@ using Elsa.Persistence.Common.Models; using Elsa.Workflows.Api.Models; using Elsa.Workflows.Core.Serialization; using Elsa.Workflows.Management.Mappers; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Persistence.Services; using Elsa.Workflows.Runtime.Services; using Humanizer; diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Get.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Get.cs index 87f0e87ce..85d2b3263 100644 --- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Get.cs +++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Get.cs @@ -6,7 +6,6 @@ using Elsa.Persistence.Common.Models; using Elsa.Workflows.Api.Models; using Elsa.Workflows.Core.Serialization; using Elsa.Workflows.Management.Mappers; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Persistence.Services; using Elsa.Workflows.Runtime.Services; using Microsoft.AspNetCore.Http; diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Post.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Post.cs index ae935b405..1feb1b9ad 100644 --- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Post.cs +++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Post.cs @@ -13,7 +13,6 @@ using Elsa.Workflows.Management.Materializers; using Elsa.Workflows.Management.Models; using Elsa.Workflows.Management.Services; using Elsa.Workflows.Persistence.Entities; -using Elsa.Workflows.Persistence.Models; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Publish.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Publish.cs index 1a32911da..eeac84c1c 100644 --- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Publish.cs +++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Publish.cs @@ -5,7 +5,6 @@ using Elsa.Persistence.Common.Models; using Elsa.Workflows.Core.Serialization; using Elsa.Workflows.Management.Services; using Elsa.Workflows.Persistence.Entities; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Persistence.Services; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Retract.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Retract.cs index 1f12f5723..37c37fc78 100644 --- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Retract.cs +++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Retract.cs @@ -5,7 +5,6 @@ using Elsa.Persistence.Common.Models; using Elsa.Workflows.Core.Serialization; using Elsa.Workflows.Management.Services; using Elsa.Workflows.Persistence.Entities; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Persistence.Services; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; diff --git a/src/modules/Elsa.Workflows.Api/Models/WorkflowDefinitionModel.cs b/src/modules/Elsa.Workflows.Api/Models/WorkflowDefinitionModel.cs index 2fcfd5fb9..e6cbe2b76 100644 --- a/src/modules/Elsa.Workflows.Api/Models/WorkflowDefinitionModel.cs +++ b/src/modules/Elsa.Workflows.Api/Models/WorkflowDefinitionModel.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using Elsa.Workflows.Core.Services; using Elsa.Workflows.Management.Models; -using Elsa.Workflows.Persistence.Models; namespace Elsa.Workflows.Api.Models; diff --git a/src/modules/Elsa.Workflows.Core/Elsa.Workflows.Core.csproj b/src/modules/Elsa.Workflows.Core/Elsa.Workflows.Core.csproj index 2fcf7a69d..eebe78a67 100644 --- a/src/modules/Elsa.Workflows.Core/Elsa.Workflows.Core.csproj +++ b/src/modules/Elsa.Workflows.Core/Elsa.Workflows.Core.csproj @@ -18,6 +18,7 @@ + diff --git a/src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs b/src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs index 6ecbe6f8b..fe9f4988a 100644 --- a/src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs +++ b/src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs @@ -1,4 +1,5 @@ using System.Linq.Expressions; +using Elsa.Common.Services; using Elsa.Expressions.Services; using Elsa.Workflows.Core.Models; using Elsa.Workflows.Core.Services; diff --git a/src/modules/Elsa.Workflows.Core/Features/WorkflowsFeature.cs b/src/modules/Elsa.Workflows.Core/Features/WorkflowsFeature.cs index beb46aeaa..237bb3e9d 100644 --- a/src/modules/Elsa.Workflows.Core/Features/WorkflowsFeature.cs +++ b/src/modules/Elsa.Workflows.Core/Features/WorkflowsFeature.cs @@ -1,3 +1,4 @@ +using Elsa.Common.Features; using Elsa.Expressions; using Elsa.Expressions.Extensions; using Elsa.Expressions.Features; @@ -16,6 +17,7 @@ using Microsoft.Extensions.DependencyInjection; namespace Elsa.Workflows.Core.Features; +[DependsOn(typeof(SystemClockFeature))] [DependsOn(typeof(ExpressionsFeature))] public class WorkflowsFeature : FeatureBase { @@ -64,7 +66,6 @@ public class WorkflowsFeature : FeatureBase .AddSingleton() .AddSingleton() .AddSingleton() - .AddSingleton() .AddSingleton() .AddTransient() .AddSingleton(typeof(Func), sp => () => sp.GetRequiredService()) diff --git a/src/modules/Elsa.Workflows.Core/Pipelines/ActivityExecution/Components/ActivityInvokerMiddleware.cs b/src/modules/Elsa.Workflows.Core/Pipelines/ActivityExecution/Components/ActivityInvokerMiddleware.cs index cd9413e6d..23dd02a61 100644 --- a/src/modules/Elsa.Workflows.Core/Pipelines/ActivityExecution/Components/ActivityInvokerMiddleware.cs +++ b/src/modules/Elsa.Workflows.Core/Pipelines/ActivityExecution/Components/ActivityInvokerMiddleware.cs @@ -1,3 +1,4 @@ +using Elsa.Common.Services; using Elsa.Workflows.Core.Models; using Elsa.Workflows.Core.Services; using Microsoft.Extensions.Logging; @@ -13,13 +14,13 @@ public static class InvokeDriversMiddlewareExtensions public class ActivityInvokerMiddleware : IActivityExecutionMiddleware { private readonly ActivityMiddlewareDelegate _next; - private readonly ISystemClock _clock; + private readonly ISystemClock _systemClock; private readonly ILogger _logger; - public ActivityInvokerMiddleware(ActivityMiddlewareDelegate next, ISystemClock clock, ILogger logger) + public ActivityInvokerMiddleware(ActivityMiddlewareDelegate next, ISystemClock systemClock, ILogger logger) { _next = next; - _clock = clock; + _systemClock = systemClock; _logger = logger; } diff --git a/src/modules/Elsa.Workflows.Core/Services/IActivityPortResolver.cs b/src/modules/Elsa.Workflows.Core/Services/IActivityPortResolver.cs index 59ad0f701..de834746b 100644 --- a/src/modules/Elsa.Workflows.Core/Services/IActivityPortResolver.cs +++ b/src/modules/Elsa.Workflows.Core/Services/IActivityPortResolver.cs @@ -1,5 +1,3 @@ -using System.Reflection; - namespace Elsa.Workflows.Core.Services; /// diff --git a/src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs b/src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs index 2c1aca117..91f831753 100644 --- a/src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs +++ b/src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs @@ -1,3 +1,4 @@ +using Elsa.Common.Features; using Elsa.Expressions.Services; using Elsa.Features.Abstractions; using Elsa.Features.Attributes; @@ -18,6 +19,7 @@ using Microsoft.Extensions.DependencyInjection; namespace Elsa.Workflows.Management.Features; [DependsOn(typeof(MediatorFeature))] +[DependsOn(typeof(SystemClockFeature))] [DependsOn(typeof(WorkflowsFeature))] [DependsOn(typeof(WorkflowPersistenceFeature))] public class WorkflowManagementFeature : FeatureBase diff --git a/src/modules/Elsa.Workflows.Management/Implementations/WorkflowDefinitionPublisher.cs b/src/modules/Elsa.Workflows.Management/Implementations/WorkflowDefinitionPublisher.cs index 89f1b2e8b..4907c4b18 100644 --- a/src/modules/Elsa.Workflows.Management/Implementations/WorkflowDefinitionPublisher.cs +++ b/src/modules/Elsa.Workflows.Management/Implementations/WorkflowDefinitionPublisher.cs @@ -1,4 +1,5 @@ using System.Text.Json; +using Elsa.Common.Services; using Elsa.Mediator.Services; using Elsa.Persistence.Common.Models; using Elsa.Workflows.Core.Activities; @@ -8,7 +9,6 @@ using Elsa.Workflows.Management.Materializers; using Elsa.Workflows.Management.Notifications; using Elsa.Workflows.Management.Services; using Elsa.Workflows.Persistence.Entities; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Persistence.Services; namespace Elsa.Workflows.Management.Implementations diff --git a/src/modules/Elsa.Workflows.Persistence.EntityFrameworkCore/Features/EFCoreWorkflowPersistenceFeature.cs b/src/modules/Elsa.Workflows.Persistence.EntityFrameworkCore/Features/EFCoreWorkflowPersistenceFeature.cs index 2e0365462..f32f8e132 100644 --- a/src/modules/Elsa.Workflows.Persistence.EntityFrameworkCore/Features/EFCoreWorkflowPersistenceFeature.cs +++ b/src/modules/Elsa.Workflows.Persistence.EntityFrameworkCore/Features/EFCoreWorkflowPersistenceFeature.cs @@ -1,3 +1,4 @@ +using Elsa.Features.Attributes; using Elsa.Features.Services; using Elsa.Persistence.EntityFrameworkCore.Common.Abstractions; using Elsa.Persistence.EntityFrameworkCore.Common.Services; @@ -9,6 +10,7 @@ using Microsoft.Extensions.DependencyInjection; namespace Elsa.Workflows.Persistence.EntityFrameworkCore.Features; +[DependsOn(typeof(WorkflowPersistenceFeature))] public class EFCoreWorkflowPersistenceFeature : EFCorePersistenceFeature { public EFCoreWorkflowPersistenceFeature(IModule module) : base(module) diff --git a/src/modules/Elsa.Workflows.Persistence.EntityFrameworkCore/Implementations/EFCoreWorkflowDefinitionStore.cs b/src/modules/Elsa.Workflows.Persistence.EntityFrameworkCore/Implementations/EFCoreWorkflowDefinitionStore.cs index edb0c385c..deacdc851 100644 --- a/src/modules/Elsa.Workflows.Persistence.EntityFrameworkCore/Implementations/EFCoreWorkflowDefinitionStore.cs +++ b/src/modules/Elsa.Workflows.Persistence.EntityFrameworkCore/Implementations/EFCoreWorkflowDefinitionStore.cs @@ -4,7 +4,6 @@ using Elsa.Persistence.Common.Models; using Elsa.Persistence.EntityFrameworkCore.Common.Extensions; using Elsa.Persistence.EntityFrameworkCore.Common.Services; using Elsa.Workflows.Persistence.Entities; -using Elsa.Workflows.Persistence.Extensions; using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Persistence.Services; diff --git a/src/modules/Elsa.Workflows.Persistence/Extensions/WorkflowExtensions.cs b/src/modules/Elsa.Workflows.Persistence/Extensions/WorkflowExtensions.cs index b35018460..039c38577 100644 --- a/src/modules/Elsa.Workflows.Persistence/Extensions/WorkflowExtensions.cs +++ b/src/modules/Elsa.Workflows.Persistence/Extensions/WorkflowExtensions.cs @@ -1,6 +1,5 @@ using Elsa.Persistence.Common.Models; using Elsa.Workflows.Core.Models; -using Elsa.Workflows.Persistence.Models; namespace Elsa.Workflows.Persistence.Extensions; diff --git a/src/modules/Elsa.Workflows.Persistence/Implementations/MemoryWorkflowDefinitionStore.cs b/src/modules/Elsa.Workflows.Persistence/Implementations/MemoryWorkflowDefinitionStore.cs index 546de5fff..b896a05a4 100644 --- a/src/modules/Elsa.Workflows.Persistence/Implementations/MemoryWorkflowDefinitionStore.cs +++ b/src/modules/Elsa.Workflows.Persistence/Implementations/MemoryWorkflowDefinitionStore.cs @@ -2,7 +2,6 @@ using Elsa.Persistence.Common.Extensions; using Elsa.Persistence.Common.Implementations; using Elsa.Persistence.Common.Models; using Elsa.Workflows.Persistence.Entities; -using Elsa.Workflows.Persistence.Extensions; using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Persistence.Services; diff --git a/src/modules/Elsa.Workflows.Runtime/Activities/DispatchWorkflow.cs b/src/modules/Elsa.Workflows.Runtime/Activities/DispatchWorkflow.cs index bd46568f2..b02cde09f 100644 --- a/src/modules/Elsa.Workflows.Runtime/Activities/DispatchWorkflow.cs +++ b/src/modules/Elsa.Workflows.Runtime/Activities/DispatchWorkflow.cs @@ -2,7 +2,6 @@ using Elsa.Persistence.Common.Models; using Elsa.Workflows.Core; using Elsa.Workflows.Core.Attributes; using Elsa.Workflows.Core.Models; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Runtime.Services; using Microsoft.Extensions.Logging; diff --git a/src/modules/Elsa.Workflows.Runtime/Extensions/DependencyInjectionExtensions.cs b/src/modules/Elsa.Workflows.Runtime/Extensions/DependencyInjectionExtensions.cs index 7ec7dfdbb..bd82c7f41 100644 --- a/src/modules/Elsa.Workflows.Runtime/Extensions/DependencyInjectionExtensions.cs +++ b/src/modules/Elsa.Workflows.Runtime/Extensions/DependencyInjectionExtensions.cs @@ -1,4 +1,3 @@ -using System.Threading.Channels; using Elsa.Features.Services; using Elsa.Workflows.Runtime.Features; using Elsa.Workflows.Runtime.Services; @@ -13,17 +12,7 @@ public static class DependencyInjectionExtensions module.Configure(configure); return module; } - - public static IServiceCollection CreateChannel(this IServiceCollection services) => - services - .AddSingleton(CreateChannel()) - .AddSingleton(CreateChannelReader) - .AddSingleton(CreateChannelWriter); - - private static Channel CreateChannel() => Channel.CreateUnbounded(new UnboundedChannelOptions()); - private static ChannelReader CreateChannelReader(IServiceProvider serviceProvider) => serviceProvider.GetRequiredService>().Reader; - private static ChannelWriter CreateChannelWriter(IServiceProvider serviceProvider) => serviceProvider.GetRequiredService>().Writer; - + public static IServiceCollection AddWorkflowDefinitionProvider(this IServiceCollection services) where T : class, IWorkflowDefinitionProvider => services.AddSingleton(); public static IServiceCollection AddStimulusHandler(this IServiceCollection services) where T : class, IStimulusHandler => services.AddSingleton(); public static IServiceCollection AddInstructionInterpreter(this IServiceCollection services) where T : class, IWorkflowInstructionInterpreter => services.AddSingleton(); diff --git a/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs b/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs index d643a9644..7659715ba 100644 --- a/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs +++ b/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs @@ -1,4 +1,6 @@ +using Elsa.Common.Features; using Elsa.Features.Abstractions; +using Elsa.Features.Attributes; using Elsa.Features.Services; using Elsa.Mediator.Extensions; using Elsa.Workflows.Core.Services; @@ -15,6 +17,7 @@ using Microsoft.Extensions.DependencyInjection; namespace Elsa.Workflows.Runtime.Features; +[DependsOn(typeof(SystemClockFeature))] public class WorkflowRuntimeFeature : FeatureBase { public WorkflowRuntimeFeature(IModule module) : base(module) diff --git a/src/modules/Elsa.Workflows.Runtime/HostedServices/PopulateWorkflowDefinitionStore.cs b/src/modules/Elsa.Workflows.Runtime/HostedServices/PopulateWorkflowDefinitionStore.cs index 57d583478..d9d0b6ba9 100644 --- a/src/modules/Elsa.Workflows.Runtime/HostedServices/PopulateWorkflowDefinitionStore.cs +++ b/src/modules/Elsa.Workflows.Runtime/HostedServices/PopulateWorkflowDefinitionStore.cs @@ -1,7 +1,6 @@ using Elsa.Persistence.Common.Models; using Elsa.Workflows.Core.Models; using Elsa.Workflows.Persistence.Entities; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Persistence.Services; using Elsa.Workflows.Runtime.Services; using Microsoft.Extensions.Hosting; diff --git a/src/modules/Elsa.Workflows.Runtime/Implementations/DefaultWorkflowInvoker.cs b/src/modules/Elsa.Workflows.Runtime/Implementations/DefaultWorkflowInvoker.cs index fe3ec20ef..eba1ff4f3 100644 --- a/src/modules/Elsa.Workflows.Runtime/Implementations/DefaultWorkflowInvoker.cs +++ b/src/modules/Elsa.Workflows.Runtime/Implementations/DefaultWorkflowInvoker.cs @@ -3,7 +3,6 @@ using Elsa.Workflows.Core.Models; using Elsa.Workflows.Core.Services; using Elsa.Workflows.Core.State; using Elsa.Workflows.Persistence.Entities; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Persistence.Services; using Elsa.Workflows.Runtime.Models; using Elsa.Workflows.Runtime.Services; diff --git a/src/modules/Elsa.Workflows.Runtime/Implementations/WorkflowInstanceFactory.cs b/src/modules/Elsa.Workflows.Runtime/Implementations/WorkflowInstanceFactory.cs index 4d4a036c1..3b3a6c4f9 100644 --- a/src/modules/Elsa.Workflows.Runtime/Implementations/WorkflowInstanceFactory.cs +++ b/src/modules/Elsa.Workflows.Runtime/Implementations/WorkflowInstanceFactory.cs @@ -1,9 +1,9 @@ +using Elsa.Common.Services; using Elsa.Persistence.Common.Models; using Elsa.Workflows.Core.Models; using Elsa.Workflows.Core.Services; using Elsa.Workflows.Core.State; using Elsa.Workflows.Persistence.Entities; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Persistence.Services; using Elsa.Workflows.Runtime.Services; diff --git a/src/modules/Elsa.Workflows.Runtime/Implementations/WorkflowService.cs b/src/modules/Elsa.Workflows.Runtime/Implementations/WorkflowService.cs index 6c1b546f1..61b19a0b1 100644 --- a/src/modules/Elsa.Workflows.Runtime/Implementations/WorkflowService.cs +++ b/src/modules/Elsa.Workflows.Runtime/Implementations/WorkflowService.cs @@ -1,7 +1,6 @@ using Elsa.Persistence.Common.Models; using Elsa.Workflows.Core.Models; using Elsa.Workflows.Core.Services; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Runtime.Models; using Elsa.Workflows.Runtime.Services; diff --git a/src/modules/Elsa.Workflows.Runtime/Interpreters/ResumeWorkflowInstructionInterpreter.cs b/src/modules/Elsa.Workflows.Runtime/Interpreters/ResumeWorkflowInstructionInterpreter.cs index 2959b911c..ee11c6523 100644 --- a/src/modules/Elsa.Workflows.Runtime/Interpreters/ResumeWorkflowInstructionInterpreter.cs +++ b/src/modules/Elsa.Workflows.Runtime/Interpreters/ResumeWorkflowInstructionInterpreter.cs @@ -2,7 +2,6 @@ using Elsa.Persistence.Common.Models; using Elsa.Workflows.Core.Models; using Elsa.Workflows.Core.Services; using Elsa.Workflows.Persistence.Entities; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Persistence.Services; using Elsa.Workflows.Runtime.Abstractions; using Elsa.Workflows.Runtime.Models; diff --git a/src/modules/Elsa.Workflows.Runtime/Interpreters/TriggerWorkflowInstructionInterpreter.cs b/src/modules/Elsa.Workflows.Runtime/Interpreters/TriggerWorkflowInstructionInterpreter.cs index 0b7fd4f09..ad1f4f61f 100644 --- a/src/modules/Elsa.Workflows.Runtime/Interpreters/TriggerWorkflowInstructionInterpreter.cs +++ b/src/modules/Elsa.Workflows.Runtime/Interpreters/TriggerWorkflowInstructionInterpreter.cs @@ -1,6 +1,5 @@ using Elsa.Persistence.Common.Models; using Elsa.Workflows.Persistence.Entities; -using Elsa.Workflows.Persistence.Models; using Elsa.Workflows.Persistence.Services; using Elsa.Workflows.Runtime.Abstractions; using Elsa.Workflows.Runtime.Models; diff --git a/src/modules/Elsa.Workflows.Runtime/Middleware/PersistWorkflowInstanceMiddleware.cs b/src/modules/Elsa.Workflows.Runtime/Middleware/PersistWorkflowInstanceMiddleware.cs index 7f5de318e..4428f60d1 100644 --- a/src/modules/Elsa.Workflows.Runtime/Middleware/PersistWorkflowInstanceMiddleware.cs +++ b/src/modules/Elsa.Workflows.Runtime/Middleware/PersistWorkflowInstanceMiddleware.cs @@ -1,3 +1,4 @@ +using Elsa.Common.Services; using Elsa.Mediator.Services; using Elsa.Workflows.Core.Helpers; using Elsa.Workflows.Core.Models; @@ -22,35 +23,32 @@ public class PersistWorkflowInstanceMiddleware : WorkflowExecutionMiddleware private readonly IWorkflowInstanceStore _workflowInstanceStore; private readonly IWorkflowBookmarkStore _bookmarkStore; - private readonly IRequestSender _requestSender; private readonly IEventPublisher _eventPublisher; private readonly IWorkflowStateSerializer _workflowStateSerializer; private readonly IStorageDriverManager _storageDriverManager; private readonly IBookmarkManager _bookmarkManager; private readonly IIdentityGenerator _identityGenerator; - private readonly ISystemClock _clock; + private readonly ISystemClock _systemClock; public PersistWorkflowInstanceMiddleware( WorkflowMiddlewareDelegate next, IWorkflowInstanceStore workflowInstanceStore, IWorkflowBookmarkStore bookmarkStore, - IRequestSender requestSender, IEventPublisher eventPublisher, IBookmarkManager bookmarkManager, IWorkflowStateSerializer workflowStateSerializer, IStorageDriverManager storageDriverManager, IIdentityGenerator identityGenerator, - ISystemClock clock) : base(next) + ISystemClock systemClock) : base(next) { _workflowInstanceStore = workflowInstanceStore; _bookmarkStore = bookmarkStore; - _requestSender = requestSender; _eventPublisher = eventPublisher; _bookmarkManager = bookmarkManager; _workflowStateSerializer = workflowStateSerializer; _storageDriverManager = storageDriverManager; _identityGenerator = identityGenerator; - _clock = clock; + _systemClock = systemClock; } public override async ValueTask InvokeAsync(WorkflowExecutionContext context) @@ -60,7 +58,7 @@ public class PersistWorkflowInstanceMiddleware : WorkflowExecutionMiddleware var (definitionId, version, definitionVersionId) = workflow.Identity; var existingWorkflowInstance = await _workflowInstanceStore.FindByIdAsync(context.Id, cancellationToken); var workflowInstanceName = default(string?); - var now = _clock.UtcNow; + var now = _systemClock.UtcNow; // Get the workflow instance name, if any (could be provided by previously executed middleware). if (context.TransientProperties.TryGetValue(WorkflowInstanceNameKey, out var name)) diff --git a/src/modules/Elsa.Workflows.Runtime/Models/DispatchWorkflowDefinitionRequest.cs b/src/modules/Elsa.Workflows.Runtime/Models/DispatchWorkflowDefinitionRequest.cs index 80e93a359..37f3de809 100644 --- a/src/modules/Elsa.Workflows.Runtime/Models/DispatchWorkflowDefinitionRequest.cs +++ b/src/modules/Elsa.Workflows.Runtime/Models/DispatchWorkflowDefinitionRequest.cs @@ -1,5 +1,4 @@ using Elsa.Persistence.Common.Models; -using Elsa.Workflows.Persistence.Models; namespace Elsa.Workflows.Runtime.Models; diff --git a/src/modules/Elsa.Workflows.Runtime/Models/InvokeWorkflowDefinitionRequest.cs b/src/modules/Elsa.Workflows.Runtime/Models/InvokeWorkflowDefinitionRequest.cs index 49762f117..8213d4a3c 100644 --- a/src/modules/Elsa.Workflows.Runtime/Models/InvokeWorkflowDefinitionRequest.cs +++ b/src/modules/Elsa.Workflows.Runtime/Models/InvokeWorkflowDefinitionRequest.cs @@ -1,5 +1,4 @@ using Elsa.Persistence.Common.Models; -using Elsa.Workflows.Persistence.Models; namespace Elsa.Workflows.Runtime.Models; diff --git a/src/modules/Elsa.Workflows.Runtime/Services/IWorkflowInstanceFactory.cs b/src/modules/Elsa.Workflows.Runtime/Services/IWorkflowInstanceFactory.cs index 2ce704d55..7b01982ad 100644 --- a/src/modules/Elsa.Workflows.Runtime/Services/IWorkflowInstanceFactory.cs +++ b/src/modules/Elsa.Workflows.Runtime/Services/IWorkflowInstanceFactory.cs @@ -1,7 +1,6 @@ using Elsa.Persistence.Common.Models; using Elsa.Workflows.Core.Models; using Elsa.Workflows.Persistence.Entities; -using Elsa.Workflows.Persistence.Models; namespace Elsa.Workflows.Runtime.Services; diff --git a/src/modules/Elsa.Workflows.Runtime/Services/IWorkflowService.cs b/src/modules/Elsa.Workflows.Runtime/Services/IWorkflowService.cs index d7debb8fb..a30399291 100644 --- a/src/modules/Elsa.Workflows.Runtime/Services/IWorkflowService.cs +++ b/src/modules/Elsa.Workflows.Runtime/Services/IWorkflowService.cs @@ -1,7 +1,5 @@ using Elsa.Persistence.Common.Models; using Elsa.Workflows.Core.Models; -using Elsa.Workflows.Persistence.Models; -using Elsa.Workflows.Runtime.Attributes; using Elsa.Workflows.Runtime.Models; namespace Elsa.Workflows.Runtime.Services; diff --git a/src/modules/Elsa.Workflows.Runtime/WorkflowProviders/ClrWorkflowDefinitionProvider.cs b/src/modules/Elsa.Workflows.Runtime/WorkflowProviders/ClrWorkflowDefinitionProvider.cs index 88b74d357..91b9c2a77 100644 --- a/src/modules/Elsa.Workflows.Runtime/WorkflowProviders/ClrWorkflowDefinitionProvider.cs +++ b/src/modules/Elsa.Workflows.Runtime/WorkflowProviders/ClrWorkflowDefinitionProvider.cs @@ -1,4 +1,5 @@ using System.Text.Json; +using Elsa.Common.Services; using Elsa.Workflows.Management.Materializers; using Elsa.Workflows.Core.Serialization; using Elsa.Workflows.Core.Services; @@ -58,7 +59,7 @@ public class ClrWorkflowDefinitionProvider : IWorkflowDefinitionProvider await workflowBuilder.BuildAsync(builder, cancellationToken); var workflow = builder.BuildWorkflow(); - _identityGraphService.AssignIdentitiesAsync(workflow); + await _identityGraphService.AssignIdentitiesAsync(workflow, cancellationToken); var workflowJson = JsonSerializer.Serialize(workflow.Root, _serializerOptionsProvider.CreatePersistenceOptions()); var materializerContext = new ClrWorkflowMaterializerContext(workflowBuilder.GetType()); diff --git a/src/samples/aspnet/Elsa.Samples.Web1/Elsa.Samples.Web1.csproj b/src/samples/aspnet/Elsa.Samples.Web1/Elsa.Samples.Web1.csproj index 043937f79..cd704524f 100644 --- a/src/samples/aspnet/Elsa.Samples.Web1/Elsa.Samples.Web1.csproj +++ b/src/samples/aspnet/Elsa.Samples.Web1/Elsa.Samples.Web1.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/samples/aspnet/Elsa.Samples.Web1/Program.cs b/src/samples/aspnet/Elsa.Samples.Web1/Program.cs index 0b8001985..cf188e66f 100644 --- a/src/samples/aspnet/Elsa.Samples.Web1/Program.cs +++ b/src/samples/aspnet/Elsa.Samples.Web1/Program.cs @@ -1,11 +1,9 @@ using Elsa.AspNetCore.Extensions; using Elsa.Extensions; -using Elsa.Hangfire.Implementations; using Elsa.Http.Extensions; using Elsa.JavaScript.Extensions; using Elsa.Jobs.Extensions; using Elsa.Liquid.Extensions; -using Elsa.Quartz.Implementations; using Elsa.Samples.Web1.Workflows; using Elsa.Scheduling.Extensions; using Elsa.WorkflowContexts.Extensions; @@ -48,6 +46,8 @@ services runtime.Workflows.Add(); runtime.Workflows.Add(); }) + .UseJobs() + .UseScheduling() .UseWorkflowApiEndpoints() .UseJavaScript() .UseLiquid() @@ -55,10 +55,6 @@ services .UseMvc() ); -services - .AddJobServices(new QuartzJobSchedulerProvider(), new HangfireJobQueueProvider()) - .AddSchedulingServices(); - // Add controller services. The below technique allows full control over what controllers get added from which assemblies. // It is even possible to add individual controllers this way using a custom TypesPart. // If you want to include all controllers diff --git a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/DelayWorkflow.cs b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/DelayWorkflow.cs index 7163f3be2..1cdd173c5 100644 --- a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/DelayWorkflow.cs +++ b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/DelayWorkflow.cs @@ -1,3 +1,4 @@ +using Elsa.Common.Services; using Elsa.Scheduling.Activities; using Elsa.Workflows.Core.Activities; using Elsa.Workflows.Core.Services; diff --git a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/HeartbeatWorkflow.cs b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/HeartbeatWorkflow.cs index bed2dbf32..41e2842c7 100644 --- a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/HeartbeatWorkflow.cs +++ b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/HeartbeatWorkflow.cs @@ -1,4 +1,5 @@ using System; +using Elsa.Common.Services; using Elsa.Scheduling.Activities; using Elsa.Workflows.Core.Activities; using Elsa.Workflows.Core.Services; diff --git a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/StartAtBookmarkWorkflow.cs b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/StartAtBookmarkWorkflow.cs index 094867a0d..b5f26133c 100644 --- a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/StartAtBookmarkWorkflow.cs +++ b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/StartAtBookmarkWorkflow.cs @@ -1,3 +1,4 @@ +using Elsa.Common.Services; using Elsa.Scheduling.Activities; using Elsa.Workflows.Core.Activities; using Elsa.Workflows.Core.Services; diff --git a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/StartAtTriggerWorkflow.cs b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/StartAtTriggerWorkflow.cs index 142e2269b..0f1395caa 100644 --- a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/StartAtTriggerWorkflow.cs +++ b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/StartAtTriggerWorkflow.cs @@ -1,4 +1,5 @@ using System; +using Elsa.Common.Services; using Elsa.Scheduling.Activities; using Elsa.Workflows.Core.Activities; using Elsa.Workflows.Core.Services; diff --git a/src/samples/aspnet/Elsa.Samples.Web2/Elsa.Samples.Web2.csproj b/src/samples/aspnet/Elsa.Samples.Web2/Elsa.Samples.Web2.csproj index 148f5f9a6..6a7b66f3c 100644 --- a/src/samples/aspnet/Elsa.Samples.Web2/Elsa.Samples.Web2.csproj +++ b/src/samples/aspnet/Elsa.Samples.Web2/Elsa.Samples.Web2.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/samples/aspnet/Elsa.Samples.Web2/Program.cs b/src/samples/aspnet/Elsa.Samples.Web2/Program.cs index 4b62ba47d..86d9b2c24 100644 --- a/src/samples/aspnet/Elsa.Samples.Web2/Program.cs +++ b/src/samples/aspnet/Elsa.Samples.Web2/Program.cs @@ -1,12 +1,10 @@ using Elsa.AspNetCore.Extensions; using Elsa.Extensions; -using Elsa.Hangfire.Implementations; using Elsa.Http; using Elsa.Http.Extensions; using Elsa.JavaScript.Activities; using Elsa.Jobs.Extensions; using Elsa.ProtoActor.Extensions; -using Elsa.Quartz.Implementations; using Elsa.Scheduling.Activities; using Elsa.Scheduling.Extensions; using Elsa.Workflows.Api.Extensions; @@ -40,15 +38,13 @@ services .AddActivity() .AddActivity() .AddActivity()) + .UseJobs() + .UseScheduling() .UseWorkflowApiEndpoints() .UseHttp() .UseMvc() ); -services - .AddJobServices(new QuartzJobSchedulerProvider(), new HangfireJobQueueProvider()) - .AddSchedulingServices(); - // Testing only: allow client app to connect from anywhere. services.AddCors(cors => cors.AddDefaultPolicy(policy => policy.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin())); diff --git a/src/samples/aspnet/Elsa.Samples.Web3/Elsa.Samples.Web3.csproj b/src/samples/aspnet/Elsa.Samples.Web3/Elsa.Samples.Web3.csproj index f73ca85b4..b8c9512b2 100644 --- a/src/samples/aspnet/Elsa.Samples.Web3/Elsa.Samples.Web3.csproj +++ b/src/samples/aspnet/Elsa.Samples.Web3/Elsa.Samples.Web3.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/samples/aspnet/Elsa.Samples.Web3/Program.cs b/src/samples/aspnet/Elsa.Samples.Web3/Program.cs index 1912eeb40..cd0783163 100644 --- a/src/samples/aspnet/Elsa.Samples.Web3/Program.cs +++ b/src/samples/aspnet/Elsa.Samples.Web3/Program.cs @@ -1,11 +1,9 @@ using Elsa.AspNetCore.Extensions; using Elsa.Extensions; -using Elsa.Hangfire.Implementations; using Elsa.Http; using Elsa.Http.Extensions; using Elsa.JavaScript.Activities; using Elsa.Jobs.Extensions; -using Elsa.Quartz.Implementations; using Elsa.Scheduling.Activities; using Elsa.Scheduling.Extensions; using Elsa.Workflows.Api.Extensions; @@ -31,15 +29,13 @@ services .AddActivity() .AddActivity() .AddActivity()) + .UseJobs() + .UseScheduling() .UseWorkflowApiEndpoints() .UseHttp() .UseMvc() ); -services - .AddJobServices(new QuartzJobSchedulerProvider(), new HangfireJobQueueProvider()) - .AddSchedulingServices(); - // Razor Pages. services.AddRazorPages();