diff --git a/README.md b/README.md index ab62036..a86e81e 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,9 @@ # Sample MassTransit Quartz Scheduler -This sample contains three examples: +This sample contains two projects: 1. Net461 using TopShelf -2. NetCore Win Svc (for still deploying on a Windows Server) -3. NetCore (linux, windows, mac...) +2. NetCore (linux, windows, mac...), it uses [System.ServiceProcess.ServiceController](https://www.nuget.org/packages/System.ServiceProcess.ServiceController) which allows the process to be installed on windows as a service (using sc.exe) The persistence mechanism used in this example is SQLServer, however Quartz.net supports [all of these](https://github.com/quartznet/quartznet/tree/master/database/tables). diff --git a/src/NetCore/NetCore.csproj b/src/NetCore/NetCore.csproj index 49a1c09..9f5f607 100644 --- a/src/NetCore/NetCore.csproj +++ b/src/NetCore/NetCore.csproj @@ -20,6 +20,7 @@ + diff --git a/src/NetCore/Program.cs b/src/NetCore/Program.cs index fe05352..34ad91c 100644 --- a/src/NetCore/Program.cs +++ b/src/NetCore/Program.cs @@ -10,6 +10,8 @@ using Quartz; using Quartz.Impl; using System; +using System.Diagnostics; +using System.Linq; using System.Threading.Tasks; namespace NetCore @@ -18,9 +20,18 @@ class Program { static async Task Main(string[] args) { + var isService = !(Debugger.IsAttached || args.Contains("--console")); + var builder = CreateHostBuilder(args); - await builder.RunConsoleAsync(); + if (isService) + { + await builder.RunAsServiceAsync(); + } + else + { + await builder.RunConsoleAsync(); + } } static IHostBuilder CreateHostBuilder(string[] args) => diff --git a/src/NetCoreWinSvc/ServiceBaseLifetime.cs b/src/NetCore/ServiceBaseLifetime.cs similarity index 98% rename from src/NetCoreWinSvc/ServiceBaseLifetime.cs rename to src/NetCore/ServiceBaseLifetime.cs index c9374d1..b3d4c41 100644 --- a/src/NetCoreWinSvc/ServiceBaseLifetime.cs +++ b/src/NetCore/ServiceBaseLifetime.cs @@ -4,7 +4,7 @@ using System.Threading; using System.Threading.Tasks; -namespace NetCoreWinSvc +namespace NetCore { public class ServiceBaseLifetime : ServiceBase, IHostLifetime { diff --git a/src/NetCoreWinSvc/ServiceBaseLifetimeHostExtensions.cs b/src/NetCore/ServiceBaseLifetimeHostExtensions.cs similarity index 96% rename from src/NetCoreWinSvc/ServiceBaseLifetimeHostExtensions.cs rename to src/NetCore/ServiceBaseLifetimeHostExtensions.cs index 1f92778..330bd8e 100644 --- a/src/NetCoreWinSvc/ServiceBaseLifetimeHostExtensions.cs +++ b/src/NetCore/ServiceBaseLifetimeHostExtensions.cs @@ -3,7 +3,7 @@ using System.Threading; using System.Threading.Tasks; -namespace NetCoreWinSvc +namespace NetCore { public static class ServiceBaseLifetimeHostExtensions { diff --git a/src/NetCoreWinSvc/AppConfig.cs b/src/NetCoreWinSvc/AppConfig.cs deleted file mode 100644 index 6fcc840..0000000 --- a/src/NetCoreWinSvc/AppConfig.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace NetCoreWinSvc -{ - public class AppConfig - { - public string Host { get; set; } - public string VirtualHost { get; set; } - public string Username { get; set; } - public string Password { get; set; } - public string QueueName { get; set; } - } -} diff --git a/src/NetCoreWinSvc/MassTransitConsoleHostedService.cs b/src/NetCoreWinSvc/MassTransitConsoleHostedService.cs deleted file mode 100644 index 466d02f..0000000 --- a/src/NetCoreWinSvc/MassTransitConsoleHostedService.cs +++ /dev/null @@ -1,63 +0,0 @@ -using MassTransit; -using MassTransit.Logging.Tracing; -using MassTransit.QuartzIntegration; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using Quartz; -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace NetCoreWinSvc -{ - public class MassTransitConsoleHostedService : IHostedService - { - readonly IBusControl _bus; - readonly ILogger _logger; - IScheduler _scheduler; - - public MassTransitConsoleHostedService(IBusControl bus, ILoggerFactory loggerFactory, IScheduler scheduler) - { - _bus = bus; - - if (loggerFactory != null && MassTransit.Logging.Logger.Current.GetType() == typeof(TraceLogger)) - MassTransit.ExtensionsLoggingIntegration.ExtensionsLogger.Use(loggerFactory); - _logger = loggerFactory.CreateLogger(); - - _scheduler = scheduler; - } - - public async Task StartAsync(CancellationToken cancellationToken) - { - _logger.LogInformation("Starting bus"); - await _bus.StartAsync(cancellationToken).ConfigureAwait(false); - - _scheduler.JobFactory = new MassTransitJobFactory(_bus); - try - { - _logger.LogInformation("Starting scheduler"); - await _scheduler.Start(); - } - catch(Exception) - { - await _scheduler.Shutdown(); - - throw; - } - - _logger.LogInformation("Started"); - } - - public async Task StopAsync(CancellationToken cancellationToken) - { - await _scheduler.Standby(); - - _logger.LogInformation("Stopping"); - await _bus.StopAsync(cancellationToken); - - await _scheduler.Shutdown(); - - _logger.LogInformation("Stopped"); - } - } -} diff --git a/src/NetCoreWinSvc/NetCoreWinSvc.csproj b/src/NetCoreWinSvc/NetCoreWinSvc.csproj deleted file mode 100644 index 9f5f607..0000000 --- a/src/NetCoreWinSvc/NetCoreWinSvc.csproj +++ /dev/null @@ -1,35 +0,0 @@ - - - - Exe - netcoreapp2.2 - latest - - - - - - - - - - - - - - - - - - - - - - PreserveNewest - - - PreserveNewest - - - - diff --git a/src/NetCoreWinSvc/Program.cs b/src/NetCoreWinSvc/Program.cs deleted file mode 100644 index e2f0d56..0000000 --- a/src/NetCoreWinSvc/Program.cs +++ /dev/null @@ -1,98 +0,0 @@ -using GreenPipes; -using MassTransit; -using MassTransit.QuartzIntegration; -using MassTransit.Scheduling; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using Quartz; -using Quartz.Impl; -using System; -using System.Diagnostics; -using System.Linq; -using System.Threading.Tasks; - -namespace NetCoreWinSvc -{ - class Program - { - static async Task Main(string[] args) - { - var isService = !(Debugger.IsAttached || args.Contains("--console")); - - var builder = CreateHostBuilder(args); - - if (isService) - { - await builder.RunAsServiceAsync(); - } - else - { - await builder.RunConsoleAsync(); - } - } - - static IHostBuilder CreateHostBuilder(string[] args) => - new HostBuilder() - .ConfigureAppConfiguration((hostingContext, config) => - { - config.AddJsonFile("appsettings.json", optional: true); - config.AddEnvironmentVariables(); - - if (args != null) - config.AddCommandLine(args); - }) - .ConfigureServices((hostContext, services) => - { - services.Configure(hostContext.Configuration.GetSection("AppConfig")); - - // Service Bus - services.AddMassTransit(cfg => - { - cfg.AddBus(ConfigureBus); - }); - - services.AddHostedService(); - - services.AddSingleton(x => new StdSchedulerFactory().GetScheduler().ConfigureAwait(false).GetAwaiter().GetResult()); - }) - .ConfigureLogging((hostingContext, logging) => - { - logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); - logging.AddConsole(); - }); - - - - static IBusControl ConfigureBus(IServiceProvider provider) - { - var options = provider.GetRequiredService>().Value; - var scheduler = provider.GetRequiredService(); - - return Bus.Factory.CreateUsingRabbitMq(cfg => - { - var host = cfg.Host(options.Host, options.VirtualHost, h => - { - h.Username(options.Username); - h.Password(options.Password); - }); - - cfg.UseJsonSerializer(); // Because we are using json within Quartz for serializer type - - cfg.ReceiveEndpoint(host, options.QueueName, endpoint => - { - var partitionCount = Environment.ProcessorCount; - endpoint.PrefetchCount = (ushort)(partitionCount); - var partitioner = endpoint.CreatePartitioner(partitionCount); - - endpoint.Consumer(() => new ScheduleMessageConsumer(scheduler), x => - x.Message(m => m.UsePartitioner(partitioner, p => p.Message.CorrelationId))); - endpoint.Consumer(() => new CancelScheduledMessageConsumer(scheduler), - x => x.Message(m => m.UsePartitioner(partitioner, p => p.Message.TokenId))); - }); - }); - } - } -} diff --git a/src/NetCoreWinSvc/appsettings.json b/src/NetCoreWinSvc/appsettings.json deleted file mode 100644 index ffd775c..0000000 --- a/src/NetCoreWinSvc/appsettings.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Debug" - } - }, - "AppConfig": { - "Host": "localhost", - "VirtualHost": "/", - "Username": "guest", - "Password": "guest", - "QueueName": "quartz-scheduler" - } -} \ No newline at end of file diff --git a/src/NetCoreWinSvc/quartz.config b/src/NetCoreWinSvc/quartz.config deleted file mode 100644 index cab3710..0000000 --- a/src/NetCoreWinSvc/quartz.config +++ /dev/null @@ -1,13 +0,0 @@ -quartz.scheduler.instanceName = MassTransit-Scheduler -quartz.scheduler.instanceId = AUTO -quartz.serializer.type = json -quartz.threadPool.type = Quartz.Simpl.SimpleThreadPool, Quartz -quartz.threadPool.threadCount = 10 -quartz.jobStore.misfireThreshold = 60000 -quartz.jobStore.type = Quartz.Impl.AdoJobStore.JobStoreTX, Quartz -quartz.jobStore.driverDelegateType = Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz -quartz.jobStore.tablePrefix = QRTZ_ -quartz.jobStore.dataSource = quartzDS -quartz.dataSource.quartzDS.connectionString = Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=mt-scheduler;Trusted_Connection=True;MultipleActiveResultSets=True;Connection Timeout=30 -quartz.dataSource.quartzDS.provider = SqlServer -quartz.jobStore.useProperties = true \ No newline at end of file diff --git a/src/Sample-Quartz.sln b/src/Sample-Quartz.sln index 9a8d543..a062d36 100644 --- a/src/Sample-Quartz.sln +++ b/src/Sample-Quartz.sln @@ -3,11 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.28307.329 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetCore", "NetCore\NetCore.csproj", "{E0E94665-623A-4CA2-99AD-D9103E17C63F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetCore", "NetCore\NetCore.csproj", "{E0E94665-623A-4CA2-99AD-D9103E17C63F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetCoreWinSvc", "NetCoreWinSvc\NetCoreWinSvc.csproj", "{B1A033D3-4D4F-4A1E-8BE7-BFF5675E2650}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Net461TopShelf", "Net461TopShelf\Net461TopShelf.csproj", "{EFA36BE4-C5FF-4492-ADD0-F5E758BD1758}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Net461TopShelf", "Net461TopShelf\Net461TopShelf.csproj", "{EFA36BE4-C5FF-4492-ADD0-F5E758BD1758}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -19,10 +17,6 @@ Global {E0E94665-623A-4CA2-99AD-D9103E17C63F}.Debug|Any CPU.Build.0 = Debug|Any CPU {E0E94665-623A-4CA2-99AD-D9103E17C63F}.Release|Any CPU.ActiveCfg = Release|Any CPU {E0E94665-623A-4CA2-99AD-D9103E17C63F}.Release|Any CPU.Build.0 = Release|Any CPU - {B1A033D3-4D4F-4A1E-8BE7-BFF5675E2650}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B1A033D3-4D4F-4A1E-8BE7-BFF5675E2650}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B1A033D3-4D4F-4A1E-8BE7-BFF5675E2650}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B1A033D3-4D4F-4A1E-8BE7-BFF5675E2650}.Release|Any CPU.Build.0 = Release|Any CPU {EFA36BE4-C5FF-4492-ADD0-F5E758BD1758}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EFA36BE4-C5FF-4492-ADD0-F5E758BD1758}.Debug|Any CPU.Build.0 = Debug|Any CPU {EFA36BE4-C5FF-4492-ADD0-F5E758BD1758}.Release|Any CPU.ActiveCfg = Release|Any CPU