/// <summary> /// Gets the specified queue. /// </summary> /// <typeparam name="TTransportInit">The type of the transport initialize.</typeparam> /// <typeparam name="TQueue">The type of the queue.</typeparam> /// <param name="queueConnection">Queue and connection information.</param> /// <param name="producerConfiguration">The producer configuration.</param> /// <returns></returns> /// <exception cref="DotNetWorkQueueException">Failed to create the queue. The error message is {createResult.ErrorMessage}</exception> public IProducerMethodJobQueue Get <TTransportInit, TQueue>(QueueConnection queueConnection, Action <QueueProducerConfiguration> producerConfiguration = null) where TTransportInit : ITransportInit, new() where TQueue : class, IJobQueueCreation { var connectionInfo = new BaseConnectionInformation(queueConnection); if (_queues.ContainsKey(connectionInfo)) { return(_queues[connectionInfo]); } var transportName = typeof(TTransportInit).ToString(); if (!_containers.ContainsKey(transportName)) { var container = new QueueContainer <TTransportInit>(_registrations.QueueRegistrations, _registrations.QueueOptions); if (!_containers.TryAdd(transportName, container)) { container.Dispose(); } } if (!_queues.ContainsKey(connectionInfo)) { using (var jobQueueCreation = new JobQueueCreationContainer <TTransportInit>(_registrations.QueueCreationRegistrations, _registrations.QueueCreationOptions)) { using (var createQueue = jobQueueCreation.GetQueueCreation <TQueue>(queueConnection)) { var createResult = createQueue.CreateJobSchedulerQueue(_registrations.QueueCreationRegistrations, queueConnection, _registrations.QueueCreationOptions); if (createResult.Success) { var scope = createQueue.Scope; var queue = _containers[transportName].CreateMethodJobProducer(queueConnection); producerConfiguration?.Invoke(queue.Configuration); if (!_queues.TryAdd(connectionInfo, queue)) { queue.Dispose(); scope.Dispose(); } else { queue.Start(); _creationScopes.TryAdd(connectionInfo, scope); } } else { throw new DotNetWorkQueueException($"Failed to create the queue. The error message is {createResult.ErrorMessage}"); } } } } return(_queues[connectionInfo]); }
public void RunEnqueueTestDynamic <TTransportInit, TJobQueueCreator>(string queueName, string connectionString, bool addInterceptors, Action <string, string, long, ICreationScope> verify, Action <string, string, ICreationScope> setErrorFlag, IGetTimeFactory timeFactory, ICreationScope scope, ILogProvider logProvider) where TTransportInit : ITransportInit, new() where TJobQueueCreator : class, IJobQueueCreation { _timeFactory = timeFactory; _logProvider = logProvider; using (var jobQueueCreation = new JobQueueCreationContainer <TTransportInit>()) { using ( var createQueue = jobQueueCreation.GetQueueCreation <TJobQueueCreator>(queueName, connectionString) ) { RunEnqueueTest <TTransportInit>(queueName, connectionString, addInterceptors, verify, setErrorFlag, (x, name) => x.AddUpdateJob <TTransportInit>(createQueue, name, queueName, connectionString, "min(*)", new LinqExpressionToRun( "(message, workerNotification) => Console.WriteLine(DateTime.Now.Ticks)")), (x, name, time) => x.AddUpdateJob <TTransportInit>(createQueue, name, queueName, connectionString, "min(*)", new LinqExpressionToRun( "(message, workerNotification) => Console.WriteLine(DateTime.Now.Ticks)"), null, null, true, time), timeFactory, scope, logProvider ); } } }
static void Main(string[] args) { //we are using serilog for sample purposes var log = new LoggerConfiguration() .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}") .MinimumLevel.Debug() .CreateLogger(); Log.Logger = log; log.Information("Startup"); log.Information(SharedConfiguration.AllSettings); //verify that the queue exists var queueName = ConfigurationManager.AppSettings.ReadSetting("QueueName"); var connectionString = ConfigurationManager.AppSettings.ReadSetting("Database"); var queueConnection = new QueueConnection(queueName, connectionString); using (var jobQueueCreation = new JobQueueCreationContainer <SqlServerMessageQueueInit>(serviceRegister => Injectors.AddInjectors(Helpers.CreateForSerilog(), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "SQLServerScheduler", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var createQueue = jobQueueCreation.GetQueueCreation <SqlServerJobQueueCreation>(queueConnection)) { //queue options createQueue.Options.EnableDelayedProcessing = true; createQueue.Options.EnableHeartBeat = true; createQueue.Options.EnableMessageExpiration = false; createQueue.Options.EnableStatus = true; createQueue.Options.EnableStatusTable = true; var result = createQueue.CreateJobSchedulerQueue(serviceRegister => Injectors.AddInjectors(Helpers.CreateForSerilog(), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "SQLServerScheduler", serviceRegister), queueConnection, options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos), false); log.Information(result.Status.ToString()); } } using (var jobContainer = new JobSchedulerContainer(serviceRegister => Injectors.AddInjectors(Helpers.CreateForSerilog(), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "SQLServerScheduler", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var scheduler = jobContainer.CreateJobScheduler(serviceRegister => Injectors.AddInjectors(Helpers.CreateForSerilog(), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "SQLServerScheduler", serviceRegister), serviceRegister => Injectors.AddInjectors(Helpers.CreateForSerilog(), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "SQLServerScheduler", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { //start may be called before or after adding jobs scheduler.Start(); var keepRunning = true; IScheduledJob job1 = null; IScheduledJob job2 = null; IScheduledJob job3 = null; while (keepRunning) { Console.WriteLine(@"a) Schedule job1 b) Schedule job2 c) Schedule job3 d) View scheduled jobs e) Remove job1 f) Remove job2 g) Remove job3 q) Quit"); var key = char.ToLower(Console.ReadKey(true).KeyChar); try { switch (key) { case 'a': job1 = scheduler.AddUpdateJob <SqlServerMessageQueueInit, SqlServerJobQueueCreation>("test job1", queueConnection, "sec(0,5,10,15,20,25,30,35,40,45,50,55)", (message, workerNotification) => Console.WriteLine("test job1 " + message.MessageId.Id.Value)); log.Information("job scheduled"); break; case 'b': job2 = scheduler.AddUpdateJob <SqlServerMessageQueueInit, SqlServerJobQueueCreation>("test job2", queueConnection, "min(*)", (message, workerNotification) => Console.WriteLine("test job2 " + message.MessageId.Id.Value)); log.Information("job scheduled"); break; case 'c': job3 = scheduler.AddUpdateJob <SqlServerMessageQueueInit, SqlServerJobQueueCreation>("test job3", queueConnection, "sec(30)", (message, workerNotification) => Console.WriteLine("test job3 " + message.MessageId.Id.Value)); log.Information("job scheduled"); break; case 'd': var jobs = scheduler.GetAllJobs(); foreach (var job in jobs) { Log.Information("Job: {@job}", job); } break; case 'e': if (job1 != null) { job1.StopSchedule(); if (scheduler.RemoveJob(job1.Name)) { job1 = null; log.Information("job removed"); } } break; case 'f': if (job2 != null) { job2.StopSchedule(); if (scheduler.RemoveJob(job2.Name)) { job2 = null; log.Information("job removed"); } } break; case 'g': if (job3 != null) { job3.StopSchedule(); if (scheduler.RemoveJob(job3.Name)) { job3 = null; log.Information("job removed"); } } break; case 'q': Console.WriteLine("Quitting"); keepRunning = false; break; } } catch (Exception e) { log.Error(e, "Failed"); } } } } }
void RunTestMultipleProducers <TTransportInit, TJobQueueCreator>(string queueName, string connectionString, bool addInterceptors, long producerCount, IGetTimeFactory timeFactory, ILogProvider logProvider) where TTransportInit : ITransportInit, new() where TJobQueueCreator : class, IJobQueueCreation { var enqueued = 0; Exception lastError = null; _queueStarted = false; _timeFactory = timeFactory; _logProvider = logProvider; using (var jobQueueCreation = new JobQueueCreationContainer <TTransportInit>()) { using ( var createQueue = jobQueueCreation.GetQueueCreation <TJobQueueCreator>(queueName, connectionString) ) { createQueue.CreateJobSchedulerQueue(null, queueName, connectionString); //always run a consumer to clear out jobs using (var queueContainer = new QueueContainer <TTransportInit>(QueueContainer)) { using (var queue = queueContainer.CreateMethodConsumer(queueName, connectionString)) { queue.Configuration.Worker.WorkerCount = 4; WaitForRollover(timeFactory); Thread.Sleep(10000); Parallel.For(0, producerCount, (i, loopState) => { using (var jobContainer = new JobSchedulerContainer()) { using (var scheduler = CreateScheduler(jobContainer, addInterceptors)) { scheduler.OnJobQueue += (job, message) => Interlocked.Increment(ref enqueued); scheduler.OnJobQueueException += (job, exception) => lastError = exception; scheduler.Start(); scheduler.AddUpdateJob <TTransportInit, TJobQueueCreator>(Job1, queueName, connectionString, "min(*)", (message, workerNotification) => Console.Write("")); scheduler.AddUpdateJob <TTransportInit, TJobQueueCreator>(Job2, queueName, connectionString, "min(*)", (message, workerNotification) => Console.Write("")); WaitForRollover(timeFactory); StartConsumer(queue); WaitForEnQueue(); } } }); ValidateEnqueueMultipleProducer(enqueued, lastError, 2); } } } } }
static void Main(string[] args) { //we are using serilog for sample purposes; any https://github.com/damianh/LibLog provider can be used var log = new LoggerConfiguration() .WriteTo.Console() .MinimumLevel.Debug() .CreateLogger(); Log.Logger = log; log.Information("Startup"); log.Information(SharedConfiguration.AllSettings); //verify that the queue exists var fileLocation = Path.Combine(Environment.ExpandEnvironmentVariables("%userprofile%"), "Documents"); var queueName = ConfigurationManager.AppSettings.ReadSetting("QueueName"); var connectionString = $"Data Source={fileLocation}{ConfigurationManager.AppSettings.ReadSetting("Database")};Version=3;"; using (var jobQueueCreation = new JobQueueCreationContainer <SqLiteMessageQueueInit>(serviceRegister => Injectors.AddInjectors(log, SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "SQLiteScheduler", serviceRegister), options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var createQueue = jobQueueCreation.GetQueueCreation <SqliteJobQueueCreation>(queueName, connectionString)) { //queue options createQueue.Options.EnableDelayedProcessing = true; createQueue.Options.EnableHeartBeat = true; createQueue.Options.EnableMessageExpiration = true; createQueue.Options.EnableStatus = true; createQueue.Options.EnableStatusTable = true; var result = createQueue.CreateJobSchedulerQueue(serviceRegister => Injectors.AddInjectors(log, SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "SQLiteScheduler", serviceRegister), queueName, connectionString, options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos), false); log.Information(result.Status.ToString()); } } using (var jobContainer = new JobSchedulerContainer(serviceRegister => Injectors.AddInjectors(log, SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "SQLiteScheduler", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var scheduler = jobContainer.CreateJobScheduler(serviceRegister => Injectors.AddInjectors(log, SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "SQLiteScheduler", serviceRegister), serviceRegister => Injectors.AddInjectors(log, SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "SQLiteScheduler", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { //start may be called before or after adding jobs scheduler.Start(); var keepRunning = true; IScheduledJob job1 = null; IScheduledJob job2 = null; IScheduledJob job3 = null; while (keepRunning) { Console.WriteLine(@"a) Schedule job1 b) Schedule job2 c) Schedule job3 d) View scheduled jobs e) Remove job1 f) Remove job2 g) Remove job3 q) Quit"); var key = char.ToLower(Console.ReadKey(true).KeyChar); try { switch (key) { case 'a': job1 = scheduler.AddUpdateJob <SqLiteMessageQueueInit, SqliteJobQueueCreation>("test job1", queueName, connectionString, "sec(0,5,10,15,20,25,30,35,40,45,50,55)", (message, workerNotification) => Console.WriteLine("test job1 " + message.MessageId.Id.Value)); log.Information("job scheduled"); break; case 'b': job2 = scheduler.AddUpdateJob <SqLiteMessageQueueInit, SqliteJobQueueCreation>("test job2", queueName, connectionString, "min(*)", (message, workerNotification) => Console.WriteLine("test job2 " + message.MessageId.Id.Value)); log.Information("job scheduled"); break; case 'c': job3 = scheduler.AddUpdateJob <SqLiteMessageQueueInit, SqliteJobQueueCreation>("test job3", queueName, connectionString, "sec(30)", (message, workerNotification) => Console.WriteLine("test job3 " + message.MessageId.Id.Value)); log.Information("job scheduled"); break; case 'd': var jobs = scheduler.GetAllJobs(); foreach (var job in jobs) { Log.Information("Job: {@job}", job); } break; case 'e': if (job1 != null) { job1.StopSchedule(); if (scheduler.RemoveJob(job1.Name)) { job1 = null; log.Information("job removed"); } } break; case 'f': if (job2 != null) { job2.StopSchedule(); if (scheduler.RemoveJob(job2.Name)) { job2 = null; log.Information("job removed"); } } break; case 'g': if (job3 != null) { job3.StopSchedule(); if (scheduler.RemoveJob(job3.Name)) { job3 = null; log.Information("job removed"); } } break; case 'q': Console.WriteLine("Quitting"); keepRunning = false; break; } } catch (Exception e) { log.Error(e, "Failed"); } } } } }