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); //determine our file path var fileLocation = Path.Combine(Environment.ExpandEnvironmentVariables("%userprofile%"), "Documents"); var queueName = ConfigurationManager.AppSettings.ReadSetting("QueueName"); var connectionString = $"Filename={fileLocation}{ConfigurationManager.AppSettings.ReadSetting("Database")};Connection=shared;"; var queueConnection = new QueueConnection(queueName, connectionString); //create the container for creating a new queue using (var createQueueContainer = new QueueCreationContainer <LiteDbMessageQueueInit>(serviceRegister => Injectors.AddInjectors(Helpers.CreateForSerilog(), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "LiteDbProducer", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var createQueue = createQueueContainer.GetQueueCreation <LiteDbMessageQueueCreation>(queueConnection)) { //Create the queue if it doesn't exist if (!createQueue.QueueExists) { //queue options createQueue.Options.EnableDelayedProcessing = true; createQueue.Options.EnableMessageExpiration = true; createQueue.Options.EnableStatusTable = true; var result = createQueue.CreateQueue(); log.Information(result.Status.ToString()); } else { log.Information("Queue already exists; not creating"); } } } //create the producer using (var queueContainer = new QueueContainer <LiteDbMessageQueueInit>(serviceRegister => Injectors.AddInjectors(Helpers.CreateForSerilog(), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "LiteDbProducer", serviceRegister), options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var queue = queueContainer.CreateProducer <SimpleMessage>(queueConnection)) { RunProducer.RunLoop(queue, ExpiredData, ExpiredDataFuture, DelayedProcessing); } } //if jaeger is using udp, sometimes the messages get lost; there doesn't seem to be a flush() call ? if (SharedConfiguration.EnableTrace) { System.Threading.Thread.Sleep(2000); } }
static void Main(string[] args) { //we are using serilog for sample purposes var log = new LoggerConfiguration() .WriteTo.Console() .MinimumLevel.Debug() .CreateLogger(); Log.Logger = log; log.Information("Startup"); log.Information(SharedConfiguration.AllSettings); var queueName = ConfigurationManager.AppSettings.ReadSetting("QueueName"); var connectionString = ConfigurationManager.AppSettings.ReadSetting("Database"); var queueConnection = new QueueConnection(queueName, connectionString); //create the producer using (var queueContainer = new QueueContainer <RedisQueueInit>(serviceRegister => Injectors.AddInjectors(new SerilogAdapter(log), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "RedisProducer", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var queue = queueContainer.CreateProducer <SimpleMessage>(queueConnection)) { RunProducer.RunLoop(queue, ExpiredData, ExpiredDataFuture, DelayedProcessing); } } //if jaeger is using udp, sometimes the messages get lost; there doesn't seem to be a flush() call ? if (SharedConfiguration.EnableTrace) { System.Threading.Thread.Sleep(2000); } }
private static void RegisterService(IContainer container, Logger log, ICreationScope scope) { Injectors.AddInjectors(new SerilogAdapter(log), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "LiteDbProducerConsumer", container); //scope must be injected to share a direct or memory connection container.RegisterNonScopedSingleton(scope); }
static void Main(string[] args) { //we are using serilog for sample purposes var log = new LoggerConfiguration() .WriteTo.Console() .MinimumLevel.Debug() .CreateLogger(); Log.Logger = log; log.Information("Startup"); log.Information(SharedConfiguration.AllSettings); var queueName = ConfigurationManager.AppSettings.ReadSetting("QueueName"); var connectionString = ConfigurationManager.AppSettings.ReadSetting("Database"); var queueConnection = new QueueConnection(queueName, connectionString); using (var queueContainer = new QueueContainer <RedisQueueInit>(serviceRegister => Injectors.AddInjectors(new SerilogAdapter(log), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "RedisConsumer", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var queue = queueContainer.CreateConsumer(queueConnection)) { //set some processing options and start looking for work queue.Configuration.Worker.WorkerCount = 4; //lets run 4 worker threads queue.Configuration.HeartBeat.UpdateTime = "sec(*%10)"; //set a heartbeat every 10 seconds queue.Configuration.HeartBeat.MonitorTime = TimeSpan.FromSeconds(15); //check for dead records every 15 seconds queue.Configuration.HeartBeat.Time = TimeSpan.FromSeconds(35); //records with no heartbeat after 35 seconds are considered dead //an invalid data exception will be re-tried 3 times, with delays of 3, 6 and then finally 9 seconds queue.Configuration.TransportConfiguration.RetryDelayBehavior.Add(typeof(InvalidDataException), new List <TimeSpan> { TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(9) }); queue.Configuration.MessageExpiration.Enabled = true; queue.Configuration.MessageExpiration.MonitorTime = TimeSpan.FromSeconds(20); //check for expired messages every 20 seconds queue.Start <SimpleMessage>(MessageProcessing.HandleMessages); Console.WriteLine("Processing messages - press any key to stop"); Console.ReadKey((true)); } } //if jaeger is using udp, sometimes the messages get lost; there doesn't seem to be a flush() call ? if (SharedConfiguration.EnableTrace) { System.Threading.Thread.Sleep(2000); } }
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 createQueueContainer = new QueueCreationContainer <PostgreSqlMessageQueueInit>(serviceRegister => Injectors.AddInjectors(Helpers.CreateForSerilog(), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "PostgreSqlConsumerAsync", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var createQueue = createQueueContainer.GetQueueCreation <PostgreSqlMessageQueueCreation>(queueConnection)) { if (!createQueue.QueueExists) { //the consumer can't do anything if the queue hasn't been created Log.Error($"Could not find {connectionString}. Verify that you have run the producer, which will create the queue"); return; } } } using (var schedulerContainer = new SchedulerContainer(serviceRegister => Injectors.AddInjectors(Helpers.CreateForSerilog(), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "PostgreSqlConsumerAsync", serviceRegister), options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var scheduler = schedulerContainer.CreateTaskScheduler()) { var factory = schedulerContainer.CreateTaskFactory(scheduler); factory.Scheduler.Configuration.MaximumThreads = 8; //8 background threads //note - the same factory can be passed to multiple queue instances - don't dispose the scheduler container until all queues have finished factory.Scheduler.Start(); //the scheduler must be started before passing it to a queue using (var queueContainer = new QueueContainer <PostgreSqlMessageQueueInit>(serviceRegister => Injectors.AddInjectors(Helpers.CreateForSerilog(), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "PostgreSqlConsumerAsync", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var queue = queueContainer.CreateConsumerQueueScheduler(queueConnection, factory)) { //set some processing options and start looking for work //in the async model, the worker count is how many threads are querying the queue - the scheduler runs the work queue.Configuration.Worker.WorkerCount = 1; //lets just run 1 thread that queries the database queue.Configuration.HeartBeat.UpdateTime = "sec(*%10)"; //set a heartbeat every 10 seconds queue.Configuration.HeartBeat.MonitorTime = TimeSpan.FromSeconds(15); //check for dead records every 15 seconds queue.Configuration.HeartBeat.Time = TimeSpan.FromSeconds( 35); //records with no heartbeat after 35 seconds are considered dead //an invalid data exception will be re-tried 3 times, with delays of 3, 6 and then finally 9 seconds queue.Configuration.TransportConfiguration.RetryDelayBehavior.Add( typeof(InvalidDataException), new List <TimeSpan> { TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(9) }); queue.Configuration.MessageExpiration.Enabled = true; queue.Configuration.MessageExpiration.MonitorTime = TimeSpan.FromSeconds(20); //check for expired messages every 20 seconds queue.Start <SimpleMessage>(MessageProcessing.HandleMessages); Console.WriteLine("Processing messages - press any key to stop"); Console.ReadKey((true)); } } } } //if jaeger is using udp, sometimes the messages get lost; there doesn't seem to be a flush() call ? if (SharedConfiguration.EnableTrace) { System.Threading.Thread.Sleep(2000); } }
static void Main(string[] args) { //we are using serilog for sample purposes var log = new LoggerConfiguration() .WriteTo.Console() .MinimumLevel.Debug() .CreateLogger(); Log.Logger = log; log.Information("Startup"); log.Information(SharedConfiguration.AllSettings); var queueName = ConfigurationManager.AppSettings.ReadSetting("QueueName"); var connectionString = ConfigurationManager.AppSettings.ReadSetting("Database"); var queueConnection = new QueueConnection(queueName, connectionString); //create the container for creating a new queue using (var createQueueContainer = new QueueCreationContainer <PostgreSqlMessageQueueInit>(serviceRegister => Injectors.AddInjectors(new SerilogAdapter(log), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "PostgreSqlProducer", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var createQueue = createQueueContainer.GetQueueCreation <PostgreSqlMessageQueueCreation>(queueConnection)) { //Create the queue if it doesn't exist if (!createQueue.QueueExists) { //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.CreateQueue(); log.Information(result.Status.ToString()); } else { log.Information("Queue already exists; not creating"); } } } //create the producer using (var queueContainer = new QueueContainer <PostgreSqlMessageQueueInit>(serviceRegister => Injectors.AddInjectors(new SerilogAdapter(log), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "PostgreSqlProducer", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var queue = queueContainer.CreateMethodProducer(queueConnection)) { RunProducer.RunLoop(queue, ExpiredData, ExpiredDataFuture); } } //if jaeger is using udp, sometimes the messages get lost; there doesn't seem to be a flush() call ? if (SharedConfiguration.EnableTrace) { System.Threading.Thread.Sleep(2000); } }
static void Main(string[] args) { //we are using serilog for sample purposes 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 = $"Filename={fileLocation}{ConfigurationManager.AppSettings.ReadSetting("Database")};Connection=shared;"; var queueConnection = new QueueConnection(queueName, connectionString); using (var createQueueContainer = new QueueCreationContainer <LiteDbMessageQueueInit>(serviceRegister => Injectors.AddInjectors(new SerilogAdapter(log), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "LiteDbSchedulerConsumer", serviceRegister), options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var createQueue = createQueueContainer.GetQueueCreation <LiteDbMessageQueueCreation>(queueConnection)) { if (!createQueue.QueueExists) { //the consumer can't do anything if the queue hasn't been created Log.Error($"Could not find {connectionString}. Verify that you have run the producer, which will create the queue"); return; } } } using (var schedulerContainer = new SchedulerContainer(serviceRegister => Injectors.AddInjectors(new SerilogAdapter(log), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "LiteDbSchedulerConsumer", serviceRegister), options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var scheduler = schedulerContainer.CreateTaskScheduler()) { var factory = schedulerContainer.CreateTaskFactory(scheduler); factory.Scheduler.Configuration.MaximumThreads = 8; //8 background threads factory.Scheduler.Configuration.MaxQueueSize = 1; //allow work to be de-queued but held in memory until a thread is free //note - the same factory can be passed to multiple queue instances - don't dispose the scheduler container until all queues have finished factory.Scheduler.Start(); //the scheduler must be started before passing it to a queue using (var queueContainer = new QueueContainer <LiteDbMessageQueueInit>(serviceRegister => Injectors.AddInjectors(new SerilogAdapter(log), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "LiteDbSchedulerConsumer", serviceRegister), options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var queue = queueContainer.CreateConsumerMethodQueueScheduler(queueConnection, factory)) { //set some processing options and start looking for work //in the async model, the worker count is how many threads are querying the queue - the scheduler runs the work queue.Configuration.Worker.WorkerCount = 1; //lets just run 1 thread that queries the database queue.Configuration.HeartBeat.UpdateTime = "sec(*%10)"; //set a heartbeat every 10 seconds queue.Configuration.HeartBeat.MonitorTime = TimeSpan.FromSeconds(15); //check for dead records every 15 seconds queue.Configuration.HeartBeat.Time = TimeSpan.FromSeconds( 35); //records with no heartbeat after 35 seconds are considered dead //an invalid data exception will be re-tried 3 times, with delays of 3, 6 and then finally 9 seconds queue.Configuration.TransportConfiguration.RetryDelayBehavior.Add( typeof(InvalidDataException), new List <TimeSpan> { TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(9) }); queue.Configuration.MessageExpiration.Enabled = true; queue.Configuration.MessageExpiration.MonitorTime = TimeSpan.FromSeconds(20); //check for expired messages every 20 seconds queue.Start(); //when running linq statements, there is no message handler, as the producer tells us what to run Console.WriteLine("Processing messages - press any key to stop"); Console.ReadKey((true)); } } } } //if jaeger is using udp, sometimes the messages get lost; there doesn't seem to be a flush() call ? if (SharedConfiguration.EnableTrace) { System.Threading.Thread.Sleep(2000); } }
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 queueName = ConfigurationManager.AppSettings.ReadSetting("QueueName"); var connectionString = ConfigurationManager.AppSettings.ReadSetting("Database"); using (var createQueueContainer = new QueueCreationContainer <PostgreSqlMessageQueueInit>(serviceRegister => Injectors.AddInjectors(log, SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "PostgreSqlConsumer", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var createQueue = createQueueContainer.GetQueueCreation <PostgreSqlMessageQueueCreation>(queueName, connectionString)) { if (!createQueue.QueueExists) { //the consumer can't do anything if the queue hasn't been created Log.Error($"Could not find {connectionString}. Verify that you have run the producer, which will create the queue"); return; } } } using (var queueContainer = new QueueContainer <PostgreSqlMessageQueueInit>(serviceRegister => Injectors.AddInjectors(log, SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "PostgreSqlConsumer", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var queue = queueContainer.CreateConsumer(queueName, connectionString)) { //set some processing options and start looking for work queue.Configuration.Worker.WorkerCount = 4; //lets run 4 worker threads queue.Configuration.HeartBeat.UpdateTime = "sec(*%10)"; //set a heartbeat every 10 seconds queue.Configuration.HeartBeat.MonitorTime = TimeSpan.FromSeconds(15); //check for dead records every 15 seconds queue.Configuration.HeartBeat.Time = TimeSpan.FromSeconds(35); //records with no heartbeat after 35 seconds are considered dead //an invalid data exception will be re-tried 3 times, with delays of 3, 6 and then finally 9 seconds queue.Configuration.TransportConfiguration.RetryDelayBehavior.Add(typeof(InvalidDataException), new List <TimeSpan> { TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(9) }); queue.Configuration.MessageExpiration.Enabled = true; queue.Configuration.MessageExpiration.MonitorTime = TimeSpan.FromSeconds(20); //check for expired messages every 20 seconds queue.Start <SimpleMessage>(MessageProcessing.HandleMessages); Console.WriteLine("Processing messages - press any key to stop"); Console.ReadKey((true)); } } //if jaeger is using udp, sometimes the messages get lost; there doesn't seem to be a flush() call ? if (SharedConfiguration.EnableTrace) { System.Threading.Thread.Sleep(2000); } }
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"); } } } } }
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); //determine our file path 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;"; //create the container for creating a new queue using (var createQueueContainer = new QueueCreationContainer <SqLiteMessageQueueInit>(serviceRegister => Injectors.AddInjectors(log, SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "SQLiteProducer", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var createQueue = createQueueContainer.GetQueueCreation <SqLiteMessageQueueCreation>(queueName, connectionString)) { //Create the queue if it doesn't exist if (!createQueue.QueueExists) { //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.CreateQueue(); log.Information(result.Status.ToString()); } else { log.Information("Queue already exists; not creating"); } } } //create the producer using (var queueContainer = new QueueContainer <SqLiteMessageQueueInit>(serviceRegister => Injectors.AddInjectors(log, SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "SQLiteProducer", serviceRegister), options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var queue = queueContainer.CreateProducer <SimpleMessage>(queueName, connectionString)) { RunProducer.RunLoop(queue, ExpiredData, ExpiredDataFuture, DelayedProcessing); } } //if jaeger is using udp, sometimes the messages get lost; there doesn't seem to be a flush() call ? if (SharedConfiguration.EnableTrace) { System.Threading.Thread.Sleep(2000); } }
static void Main(string[] args) { //we are using serilog for sample purposes var log = new LoggerConfiguration() .WriteTo.Console() .MinimumLevel.Debug() .CreateLogger(); Log.Logger = log; log.Information("Startup"); log.Information(SharedConfiguration.AllSettings); var userSelection = -1; var selection = @" 1) Direct Connection 2) Shared Connection 3) In-memory Connection "; while (userSelection < 0) { Console.WriteLine(selection); var key = Console.ReadKey(true); switch (key.KeyChar) { case '1': userSelection = 1; break; case '2': userSelection = 2; break; case '3': userSelection = 3; break; } } //determine our file path var fileLocation = Path.Combine(Environment.ExpandEnvironmentVariables("%userprofile%"), "Documents"); var queueName = ConfigurationManager.AppSettings.ReadSetting("QueueName"); string connectionString = string.Empty; switch (userSelection) { case 1: connectionString = $"Filename={fileLocation}{ConfigurationManager.AppSettings.ReadSetting("Database")};Connection=direct;"; break; case 2: connectionString = $"Filename={fileLocation}{ConfigurationManager.AppSettings.ReadSetting("Database")};Connection=shared;"; break; case 3: connectionString = ":memory:"; break; } ICreationScope scope = null; //contains a direct or memory connection that can be passed to other instances var queueConnection = new QueueConnection(queueName, connectionString); //create the container for creating a new queue using (var createQueueContainer = new QueueCreationContainer <LiteDbMessageQueueInit>(serviceRegister => Injectors.AddInjectors(new SerilogAdapter(log), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "LiteDbProducer", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var createQueue = createQueueContainer.GetQueueCreation <LiteDbMessageQueueCreation>(queueConnection)) { scope = createQueue.Scope; //Create the queue if it doesn't exist if (!createQueue.QueueExists) { //queue options createQueue.Options.EnableDelayedProcessing = true; createQueue.Options.EnableMessageExpiration = true; createQueue.Options.EnableStatusTable = true; var result = createQueue.CreateQueue(); log.Information(result.Status.ToString()); } else { log.Information("Queue already exists; not creating"); } } //create the consumer and the producer using (var queueContainer = new QueueContainer <LiteDbMessageQueueInit>( x => RegisterService(x, log, scope), options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var consumeQueue = queueContainer.CreateConsumer(queueConnection)) { //set some processing options and start looking for work consumeQueue.Configuration.Worker.WorkerCount = 4; //lets run 4 worker threads consumeQueue.Configuration.HeartBeat.UpdateTime = "sec(*%10)"; //set a heartbeat every 10 seconds consumeQueue.Configuration.HeartBeat.MonitorTime = TimeSpan.FromSeconds(15); //check for dead records every 15 seconds consumeQueue.Configuration.HeartBeat.Time = TimeSpan.FromSeconds(35); //records with no heartbeat after 35 seconds are considered dead //an invalid data exception will be re-tried 3 times, with delays of 3, 6 and then finally 9 seconds consumeQueue.Configuration.TransportConfiguration.RetryDelayBehavior.Add( typeof(InvalidDataException), new List <TimeSpan> { TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(9) }); consumeQueue.Configuration.MessageExpiration.Enabled = true; consumeQueue.Configuration.MessageExpiration.MonitorTime = TimeSpan.FromSeconds(20); //check for expired messages every 20 seconds consumeQueue.Start <SimpleMessage>(MessageProcessing.HandleMessages); using (var queue = queueContainer.CreateProducer <SimpleMessage>(queueConnection)) { RunProducer.RunLoop(queue, ExpiredData, ExpiredDataFuture, DelayedProcessing); } } } } //dispose of direct or memory connection (if present, noop otherwise) scope?.Dispose(); //if jaeger is using udp, sometimes the messages get lost; there doesn't seem to be a flush() call ? if (SharedConfiguration.EnableTrace) { System.Threading.Thread.Sleep(2000); } }
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 fileLocation = Path.Combine(Environment.ExpandEnvironmentVariables("%userprofile%"), "Documents"); var queueName = ConfigurationManager.AppSettings.ReadSetting("QueueName"); var connectionString = $"Data Source={fileLocation}{ConfigurationManager.AppSettings.ReadSetting("Database")};Version=3;"; var queueConnection = new QueueConnection(queueName, connectionString); using (var createQueueContainer = new QueueCreationContainer <SqLiteMessageQueueInit>(serviceRegister => Injectors.AddInjectors(Helpers.CreateForSerilog(), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "SQLiteConsumer", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var createQueue = createQueueContainer.GetQueueCreation <SqLiteMessageQueueCreation>(queueConnection)) { if (!createQueue.QueueExists) { //the consumer can't do anything if the queue hasn't been created Log.Error($"Could not find {connectionString}. Verify that you have run the producer, which will create the queue"); return; } } } using (var queueContainer = new QueueContainer <SqLiteMessageQueueInit>(serviceRegister => Injectors.AddInjectors(Helpers.CreateForSerilog(), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "SQLiteConsumer", serviceRegister), options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var queue = queueContainer.CreateConsumer(queueConnection)) { //set some processing options and start looking for work queue.Configuration.Worker.WorkerCount = 4; //lets run 4 worker threads queue.Configuration.HeartBeat.UpdateTime = "sec(*%10)"; //set a heartbeat every 10 seconds queue.Configuration.HeartBeat.MonitorTime = TimeSpan.FromSeconds(15); //check for dead records every 15 seconds queue.Configuration.HeartBeat.Time = TimeSpan.FromSeconds(35); //records with no heartbeat after 35 seconds are considered dead //an invalid data exception will be re-tried 3 times, with delays of 3, 6 and then finally 9 seconds queue.Configuration.TransportConfiguration.RetryDelayBehavior.Add(typeof(InvalidDataException), new List <TimeSpan> { TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(9) }); queue.Configuration.MessageExpiration.Enabled = true; queue.Configuration.MessageExpiration.MonitorTime = TimeSpan.FromSeconds(20); //check for expired messages every 20 seconds queue.Start <SimpleMessage>(MessageProcessing.HandleMessages); Console.WriteLine("Processing messages - press any key to stop"); Console.ReadKey((true)); } } //if jaeger is using udp, sometimes the messages get lost; there doesn't seem to be a flush() call ? if (SharedConfiguration.EnableTrace) { System.Threading.Thread.Sleep(2000); } }
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); var queueName = ConfigurationManager.AppSettings.ReadSetting("QueueName"); var connectionString = ConfigurationManager.AppSettings.ReadSetting("Database"); using (var schedulerContainer = new SchedulerContainer(serviceRegister => Injectors.AddInjectors(log, SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "RedisConsumerAsync", serviceRegister), options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var scheduler = schedulerContainer.CreateTaskScheduler()) { var factory = schedulerContainer.CreateTaskFactory(scheduler); factory.Scheduler.Configuration.MaximumThreads = 8; //8 background threads factory.Scheduler.Configuration.MaxQueueSize = 1; //allow work to be de-queued but held in memory until a thread is free //note - the same factory can be passed to multiple queue instances - don't dispose the scheduler container until all queues have finished factory.Scheduler.Start(); //the scheduler must be started before passing it to a queue using (var queueContainer = new QueueContainer <RedisQueueInit>(serviceRegister => Injectors.AddInjectors(log, SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "RedisConsumerAsync", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var queue = queueContainer.CreateConsumerQueueScheduler(queueName, connectionString, factory)) { //set some processing options and start looking for work //in the async model, the worker count is how many threads are querying the queue - the scheduler runs the work queue.Configuration.Worker.WorkerCount = 1; //lets just run 1 thread that queries the database queue.Configuration.HeartBeat.UpdateTime = "sec(*%10)"; //set a heartbeat every 10 seconds queue.Configuration.HeartBeat.MonitorTime = TimeSpan.FromSeconds(15); //check for dead records every 15 seconds queue.Configuration.HeartBeat.Time = TimeSpan.FromSeconds( 35); //records with no heartbeat after 35 seconds are considered dead //an invalid data exception will be re-tried 3 times, with delays of 3, 6 and then finally 9 seconds queue.Configuration.TransportConfiguration.RetryDelayBehavior.Add( typeof(InvalidDataException), new List <TimeSpan> { TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(9) }); queue.Configuration.MessageExpiration.Enabled = true; queue.Configuration.MessageExpiration.MonitorTime = TimeSpan.FromSeconds(20); //check for expired messages every 20 seconds queue.Start <SimpleMessage>(MessageProcessing.HandleMessages); Console.WriteLine("Processing messages - press any key to stop"); Console.ReadKey((true)); } } } } //if jaeger is using udp, sometimes the messages get lost; there doesn't seem to be a flush() call ? if (SharedConfiguration.EnableTrace) { System.Threading.Thread.Sleep(2000); } }
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); var queueName = ConfigurationManager.AppSettings.ReadSetting("QueueName"); var connectionString = ConfigurationManager.AppSettings.ReadSetting("Database"); var queueConnection = new QueueConnection(queueName, connectionString); //create the container for creating a new queue using (var createQueueContainer = new QueueCreationContainer <SqlServerMessageQueueInit>(serviceRegister => Injectors.AddInjectors(Helpers.CreateForSerilog(), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "SQLServerProducer", serviceRegister), options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var createQueue = createQueueContainer.GetQueueCreation <SqlServerMessageQueueCreation>(queueConnection)) { var enabledUserColumns = ConfigurationManager.AppSettings.ReadSetting("UseUserDequeue"); if (bool.Parse(enabledUserColumns)) { _userData = true; } //Create the queue if it doesn't exist if (!createQueue.QueueExists) { //queue options createQueue.Options.EnableDelayedProcessing = true; createQueue.Options.EnableHeartBeat = true; createQueue.Options.EnableMessageExpiration = true; createQueue.Options.EnableStatus = true; createQueue.Options.EnableStatusTable = true; if (!string.IsNullOrEmpty(enabledUserColumns) && bool.Parse(enabledUserColumns)) { createQueue.Options.AdditionalColumnsOnMetaData = true; createQueue.Options.AdditionalColumns.Add(new Column("DayOfWeek", ColumnTypes.Int, true, null)); } var result = createQueue.CreateQueue(); log.Information(result.Status.ToString()); } else { log.Warning("Queue already exists; not creating; note that any setting changes won't be applied"); } } } //create the producer using (var queueContainer = new QueueContainer <SqlServerMessageQueueInit>(serviceRegister => Injectors.AddInjectors(Helpers.CreateForSerilog(), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "SQLServerProducer", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var queue = queueContainer.CreateProducer <SimpleMessage>(queueConnection)) { RunProducer.RunLoop(queue, ExpiredData, ExpiredDataFuture, DelayedProcessing); } } //if jaeger is using udp, sometimes the messages get lost; there doesn't seem to be a flush() call ? if (SharedConfiguration.EnableTrace) { System.Threading.Thread.Sleep(2000); } }
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"); } } } } }
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); var queueName = ConfigurationManager.AppSettings.ReadSetting("QueueName"); var connectionString = ConfigurationManager.AppSettings.ReadSetting("Database"); using (var jobContainer = new JobSchedulerContainer(serviceRegister => Injectors.AddInjectors(log, SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "RedisScheduler", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var scheduler = jobContainer.CreateJobScheduler(serviceRegister => Injectors.AddInjectors(log, SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "RedisScheduler", serviceRegister), serviceRegister => Injectors.AddInjectors(log, SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "RedisScheduler", 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 <RedisQueueInit, RedisJobQueueCreation>("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 <RedisQueueInit, RedisJobQueueCreation>("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 <RedisQueueInit, RedisJobQueueCreation>("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"); } } } } }