/// <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
                                                    );
                }
            }
        }
Example #3
0
        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);
                        }
                    }
                }
            }
        }
Example #5
0
        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");
                        }
                    }
                }
            }
        }