public async Task ProcessJobsForMyDataCenter_TwoInQueue_TakeNextApproach()
        {
            var exampleQueueName = QueueId.Parse("ExampleQueue");

            await RunInMongoLand(async database =>
            {
                // Create two jobs that are relevant for my datacenter
                var creationService = new MongoJobCreationService(database);
                var spinWidgetJobId = await creationService.Create(exampleQueueName, new JobAttributes
                {
                    { "Name", "SpinWidget" },
                    { "DataCenter", "CAL01" }
                }).ConfigureAwait(false);
                var fooBarJobId = await creationService.Create(exampleQueueName, new JobAttributes
                {
                    { "Name", "FooBar" },
                    { "DataCenter", "CAL01" }
                }).ConfigureAwait(false);

                var myDataCenter = new JobAttributes {
                    { "DataCenter", "CAL01" }
                };

                var finished1 = await TryProcessOneJobUsingTakeNext(database, exampleQueueName, myDataCenter).ConfigureAwait(false);
                var finished2 = await TryProcessOneJobUsingTakeNext(database, exampleQueueName, myDataCenter).ConfigureAwait(false);
                var finished3 = await TryProcessOneJobUsingTakeNext(database, exampleQueueName, myDataCenter).ConfigureAwait(false);

                Assert.That(finished1, Is.Not.Null);
                Assert.That(finished2, Is.Not.Null);
                Assert.That(finished3, Is.Null);
            }).ConfigureAwait(false);
        }
예제 #2
0
 /// <summary>
 /// Sets all of the attributes of this <code>JobAttributes</code> to
 /// the same values as the attributes of obj.
 /// </summary>
 /// <param name="obj"> the <code>JobAttributes</code> to copy </param>
 public void Set(JobAttributes obj)
 {
     Copies_Renamed                   = obj.Copies_Renamed;
     DefaultSelection_Renamed         = obj.DefaultSelection_Renamed;
     Destination_Renamed              = obj.Destination_Renamed;
     Dialog_Renamed                   = obj.Dialog_Renamed;
     FileName_Renamed                 = obj.FileName_Renamed;
     FromPage_Renamed                 = obj.FromPage_Renamed;
     MaxPage_Renamed                  = obj.MaxPage_Renamed;
     MinPage_Renamed                  = obj.MinPage_Renamed;
     MultipleDocumentHandling_Renamed = obj.MultipleDocumentHandling_Renamed;
     // okay because we never modify the contents of pageRanges
     PageRanges_Renamed = obj.PageRanges_Renamed;
     PrFirst            = obj.PrFirst;
     PrLast             = obj.PrLast;
     Printer_Renamed    = obj.Printer_Renamed;
     Sides_Renamed      = obj.Sides_Renamed;
     ToPage_Renamed     = obj.ToPage_Renamed;
 }
예제 #3
0
        public async Task Create_ValidInitialData_Persists()
        {
            var exampleQueueId    = QueueId.Parse(Guid.NewGuid().ToString("N"));
            var exampleAttributes = new JobAttributes {
                { "name", "Thing ToDo" }
            };

            await RunInMongoLand(async database =>
            {
                var sut = new MongoJobCreationService(database);

                var newId = await sut.Create(exampleQueueId, exampleAttributes).ConfigureAwait(false);

                Assert.That(newId, Is.Not.Null);
                var collection      = database.GetCollection <Job>(CollectionNames.Job);
                var newlyCreatedJob = await collection.Find(Builders <Job> .Filter.Empty).SingleAsync().ConfigureAwait(false);

                Assert.That(newlyCreatedJob.Id, Is.Not.Null);
                Assert.That(newlyCreatedJob.Id, Is.Not.EqualTo(JobId.Empty()));
                Assert.That(newlyCreatedJob.QueueId, Is.EqualTo(exampleQueueId));
                Assert.That(newlyCreatedJob.Attributes, Is.EqualTo(exampleAttributes));
                Assert.That(newlyCreatedJob.Attributes["name"], Is.EqualTo("Thing ToDo"));
            }).ConfigureAwait(false);
        }
예제 #4
0
        /// <summary>
        /// Determines whether two JobAttributes are equal to each other.
        /// <para>
        /// Two JobAttributes are equal if and only if each of their attributes are
        /// equal. Attributes of enumeration type are equal if and only if the
        /// fields refer to the same unique enumeration object. A set of page
        /// ranges is equal if and only if the sets are of equal length, each range
        /// enumerates the same pages, and the ranges are in the same order.
        ///
        /// </para>
        /// </summary>
        /// <param name="obj"> the object whose equality will be checked. </param>
        /// <returns>  whether obj is equal to this JobAttribute according to the
        ///          above criteria. </returns>
        public override bool Equals(Object obj)
        {
            if (!(obj is JobAttributes))
            {
                return(false);
            }
            JobAttributes rhs = (JobAttributes)obj;

            if (FileName_Renamed == null)
            {
                if (rhs.FileName_Renamed != null)
                {
                    return(false);
                }
            }
            else
            {
                if (!FileName_Renamed.Equals(rhs.FileName_Renamed))
                {
                    return(false);
                }
            }

            if (PageRanges_Renamed == null)
            {
                if (rhs.PageRanges_Renamed != null)
                {
                    return(false);
                }
            }
            else
            {
                if (rhs.PageRanges_Renamed == null || PageRanges_Renamed.Length != rhs.PageRanges_Renamed.Length)
                {
                    return(false);
                }
                for (int i = 0; i < PageRanges_Renamed.Length; i++)
                {
                    if (PageRanges_Renamed[i][0] != rhs.PageRanges_Renamed[i][0] || PageRanges_Renamed[i][1] != rhs.PageRanges_Renamed[i][1])
                    {
                        return(false);
                    }
                }
            }

            if (Printer_Renamed == null)
            {
                if (rhs.Printer_Renamed != null)
                {
                    return(false);
                }
            }
            else
            {
                if (!Printer_Renamed.Equals(rhs.Printer_Renamed))
                {
                    return(false);
                }
            }

            return(Copies_Renamed == rhs.Copies_Renamed && DefaultSelection_Renamed == rhs.DefaultSelection_Renamed && Destination_Renamed == rhs.Destination_Renamed && Dialog_Renamed == rhs.Dialog_Renamed && FromPage_Renamed == rhs.FromPage_Renamed && MaxPage_Renamed == rhs.MaxPage_Renamed && MinPage_Renamed == rhs.MinPage_Renamed && MultipleDocumentHandling_Renamed == rhs.MultipleDocumentHandling_Renamed && PrFirst == rhs.PrFirst && PrLast == rhs.PrLast && Sides_Renamed == rhs.Sides_Renamed && ToPage_Renamed == rhs.ToPage_Renamed);
        }
예제 #5
0
 /// <summary>
 /// Constructs a <code>JobAttributes</code> instance which is a copy
 /// of the supplied <code>JobAttributes</code>.
 /// </summary>
 /// <param name="obj"> the <code>JobAttributes</code> to copy </param>
 public JobAttributes(JobAttributes obj)
 {
     Set(obj);
 }
예제 #6
0
        protected static async Task <Job> TryProcessOneJobUsingTakeNext(IMongoDatabase database, QueueId exampleQueueName, JobAttributes attributesThatShouldWork)
        {
            // Take Next available job
            var takeNextService = new MongoJobTakeNextService(database);
            var standardAck     = new JobAcknowledgment
            {
                { "RunnerId", Guid.NewGuid().ToString("N") }
            };
            var peekQuery = new TakeNextOptions
            {
                QueueId        = exampleQueueName,
                HasAttributes  = attributesThatShouldWork,
                Acknowledgment = standardAck
            };
            var nextJob = await takeNextService.TakeFor(peekQuery).ConfigureAwait(false);

            if (nextJob == null)
            {
                return(null);
            }

            var exampleReportMessage1 = "FooBar";
            var exampleReportMessage2 = "WizBang";
            var exampleReportMessage3 = "PowPop";

            // Send Reports
            var reportService = new MongoJobReportService(database);
            await
            reportService.AddReport(exampleQueueName, nextJob.Id,
                                    new JobReport { { "Timestamp", DateTime.UtcNow.ToString("O") }, { "Message", exampleReportMessage1 } }).ConfigureAwait(false);

            await
            reportService.AddReport(exampleQueueName, nextJob.Id,
                                    new JobReport { { "Timestamp", DateTime.UtcNow.ToString("O") }, { "Message", exampleReportMessage2 } }).ConfigureAwait(false);

            await
            reportService.AddReport(exampleQueueName, nextJob.Id,
                                    new JobReport { { "Timestamp", DateTime.UtcNow.ToString("O") }, { "Message", exampleReportMessage3 } }).ConfigureAwait(false);

            // Send Result
            var completionService = new MongoJobCompletionService(database);
            await completionService.Complete(exampleQueueName, nextJob.Id, new JobResult { { "Result", "Success" } }).ConfigureAwait(false);

            // Finish Job
            var finishedJobFromDb =
                await database.GetJobCollection().Find(Builders <Job> .Filter.Eq(x => x.Id, nextJob.Id)).FirstAsync().ConfigureAwait(false);

            Assert.That(finishedJobFromDb, Is.Not.Null);
            Assert.That(finishedJobFromDb.Acknowledgment, Is.Not.Null);

            Assert.That(finishedJobFromDb.Reports, Has.Length.EqualTo(3));
            var valuesOfReports = finishedJobFromDb.Reports.SelectMany(x => x.Values).ToList();

            Assert.That(valuesOfReports, Contains.Item(exampleReportMessage1));
            Assert.That(valuesOfReports, Contains.Item(exampleReportMessage2));
            Assert.That(valuesOfReports, Contains.Item(exampleReportMessage3));

            Assert.That(finishedJobFromDb.Result, Is.Not.Null);

            return(finishedJobFromDb);
        }
예제 #7
0
        protected static async Task <Job> TryProcessOneJobUsingPeekThanAck(IMongoDatabase database, QueueId exampleQueueName, JobAttributes attributesThatShouldWork)
        {
            // Query for next available a job for my datacenter
            var peekNextService = new MongoJobPeekNextService(new MongoJobQueryService(database));
            var peekQuery       = new PeekNextOptions
            {
                QueueId       = exampleQueueName,
                HasAttributes = attributesThatShouldWork,
                Limit         = 5
            };
            var jobs = (await peekNextService.PeekFor(peekQuery).ConfigureAwait(false)).ToList();

            if (!jobs.Any())
            {
                return(null);
            }

            foreach (var job in jobs)
            {
                // Acknowledge the job
                var acknowledgmentService = new MongoJobAcknowledgmentService(database);
                var standardAck           = new JobAcknowledgment
                {
                    { "RunnerId", Guid.NewGuid().ToString("N") }
                };
                var ackResult = await acknowledgmentService.Ack(exampleQueueName, job.Id, standardAck).ConfigureAwait(false);

                if (!ackResult.Success)
                {
                    continue;
                }

                var exampleReportMessage1 = "FooBar";
                var exampleReportMessage2 = "WizBang";
                var exampleReportMessage3 = "PowPop";

                // Send Reports
                var reportService = new MongoJobReportService(database);
                await
                reportService.AddReport(exampleQueueName, job.Id,
                                        new JobReport { { "Timestamp", DateTime.UtcNow.ToString("O") }, { "Message", exampleReportMessage1 } }).ConfigureAwait(false);

                await
                reportService.AddReport(exampleQueueName, job.Id,
                                        new JobReport { { "Timestamp", DateTime.UtcNow.ToString("O") }, { "Message", exampleReportMessage2 } }).ConfigureAwait(false);

                await
                reportService.AddReport(exampleQueueName, job.Id,
                                        new JobReport { { "Timestamp", DateTime.UtcNow.ToString("O") }, { "Message", exampleReportMessage3 } }).ConfigureAwait(false);

                // Send Result
                var completionService = new MongoJobCompletionService(database);
                await completionService.Complete(exampleQueueName, job.Id, new JobResult { { "Result", "Success" } }).ConfigureAwait(false);

                // Finish Job
                var finishedJobFromDb =
                    await database.GetJobCollection().Find(Builders <Job> .Filter.Eq(x => x.Id, job.Id)).FirstAsync().ConfigureAwait(false);

                Assert.That(finishedJobFromDb, Is.Not.Null);
                Assert.That(finishedJobFromDb.Acknowledgment, Is.Not.Null);

                Assert.That(finishedJobFromDb.Reports, Has.Length.EqualTo(3));
                var valuesOfReports = finishedJobFromDb.Reports.SelectMany(x => x.Values).ToList();
                Assert.That(valuesOfReports, Contains.Item(exampleReportMessage1));
                Assert.That(valuesOfReports, Contains.Item(exampleReportMessage2));
                Assert.That(valuesOfReports, Contains.Item(exampleReportMessage3));

                Assert.That(finishedJobFromDb.Result, Is.Not.Null);

                return(finishedJobFromDb);
            }
            return(null);
        }
        public async Task ProcessJobsForMyDataCenter_XInQueueWithYConsumers_TakeNextApproach(int numberOfJobsToQueue, int numberOfConsumers)
        {
            var testStartTime    = DateTime.Now;
            var exampleQueueName = QueueId.Parse("ExampleQueue");

            await RunInMongoLand(async database =>
            {
                // Create two jobs that are relevant for my datacenter
                var creationService = new MongoJobCreationService(database);
                var jobsInQueue     = new List <JobId>();

                var stopwatch = new Stopwatch();
                stopwatch.Start();

                for (int i = 0; i < numberOfJobsToQueue; i++)
                {
                    var newJobId = await creationService.Create(exampleQueueName, new JobAttributes
                    {
                        { "Name", "SpinWidget" },
                        { "DataCenter", "CAL01" },
                    }).ConfigureAwait(false);

                    jobsInQueue.Add(newJobId);
                }

                stopwatch.Stop();
                Console.WriteLine($"Creating {numberOfJobsToQueue} jobs took: {stopwatch.ElapsedMilliseconds} ms");

                var finishedJobs = new ConcurrentBag <Job>();

                var cancellationSource = new CancellationTokenSource();
                cancellationSource.CancelAfter(MaxTestTime);
                var cancellationToken = cancellationSource.Token;

                stopwatch.Reset();
                stopwatch.Start();

                for (int i = 0; i < numberOfConsumers; i++)
                {
                    var myDataCenter = new JobAttributes {
                        { "DataCenter", "CAL01" }
                    };

                    await SetupTakeNextWorkerWithSubscription(database, exampleQueueName, finishedJobs, myDataCenter, cancellationToken).ConfigureAwait(false);
                }

                do
                {
                    Thread.Sleep(100);
                } while (finishedJobs.Count < jobsInQueue.Count && DateTime.Now < testStartTime.Add(MaxTestTime));

                stopwatch.Stop();
                Console.WriteLine($"{numberOfConsumers} consumers processed {numberOfJobsToQueue} jobs in: {stopwatch.ElapsedMilliseconds} ms");

                cancellationSource.Cancel();

                var finishedJobIds = finishedJobs.Select(x => x.Id).ToList();
                foreach (var jobId in jobsInQueue)
                {
                    Assert.That(finishedJobIds, Contains.Item(jobId));
                }
            }).ConfigureAwait(false);
        }
        private static Task SetupPeekThenAckWorkerWithSubscription(IMongoDatabase database, QueueId queueName, ConcurrentBag <Job> finishedJobs, JobAttributes attributesThatShouldWork, CancellationToken cancellationToken)
        {
            var standardAck = new JobAcknowledgment
            {
                { "RunnerId", Guid.NewGuid().ToString("N") }
            };

            var options = new PeekNextSubscriptionOptions()
            {
                Token           = cancellationToken,
                PeekNextOptions = new PeekNextOptions
                {
                    QueueId       = queueName,
                    HasAttributes = attributesThatShouldWork
                }
            };

            var subscriber = new TaskBasedPeekNextSubscriber(new MongoJobPeekNextService(new MongoJobQueryService(database)));

            return(subscriber.Subscribe(async nextJobs =>
            {
                var nextJob = nextJobs.First();
                // Acknowledge the job
                var acknowledgmentService = new MongoJobAcknowledgmentService(database);

                var ackResult = await acknowledgmentService.Ack(queueName, nextJob.Id, standardAck).ConfigureAwait(false);
                if (!ackResult.Success)
                {
                    return;
                }

                var exampleReportMessage1 = "FooBar";
                var exampleReportMessage2 = "WizBang";
                var exampleReportMessage3 = "PowPop";

                // Send Reports
                var reportService = new MongoJobReportService(database);
                await
                reportService.AddReport(queueName, nextJob.Id,
                                        new JobReport {
                    { "Timestamp", DateTime.UtcNow.ToString("O") }, { "Message", exampleReportMessage1 }
                }).ConfigureAwait(false);
                await
                reportService.AddReport(queueName, nextJob.Id,
                                        new JobReport {
                    { "Timestamp", DateTime.UtcNow.ToString("O") }, { "Message", exampleReportMessage2 }
                }).ConfigureAwait(false);
                await
                reportService.AddReport(queueName, nextJob.Id,
                                        new JobReport {
                    { "Timestamp", DateTime.UtcNow.ToString("O") }, { "Message", exampleReportMessage3 }
                }).ConfigureAwait(false);

                // Send Result
                var completionService = new MongoJobCompletionService(database);
                await completionService.Complete(queueName, nextJob.Id, new JobResult {
                    { "Result", "Success" }
                }).ConfigureAwait(false);

                // Finish Job
                var finishedJobFromDb =
                    await database.GetJobCollection().Find(Builders <Job> .Filter.Eq(x => x.Id, nextJob.Id)).FirstAsync(cancellationToken).ConfigureAwait(false);

                Assert.That(finishedJobFromDb, Is.Not.Null);
                Assert.That(finishedJobFromDb.Acknowledgment, Is.Not.Null);

                Assert.That(finishedJobFromDb.Reports, Has.Length.EqualTo(3));
                var valuesOfReports = finishedJobFromDb.Reports.SelectMany(x => x.Values).ToList();
                Assert.That(valuesOfReports, Contains.Item(exampleReportMessage1));
                Assert.That(valuesOfReports, Contains.Item(exampleReportMessage2));
                Assert.That(valuesOfReports, Contains.Item(exampleReportMessage3));

                Assert.That(finishedJobFromDb.Result, Is.Not.Null);
                finishedJobs.Add(finishedJobFromDb);
            }, options));
        }
        public async Task RollingDeploy_ModelSubJobsOrchestratedByParent()
        {
            var exampleQueueName = QueueId.Parse("Wind");

            await RunInMongoLand(async database =>
            {
                var cancellationSource = new CancellationTokenSource();
                cancellationSource.CancelAfter(MaxTestTime);
                var cancellationToken = cancellationSource.Token;

                var finishedJobs = new ConcurrentBag <Job>();

                await SetupTakeNextWorkerWithSubscription(database, exampleQueueName, finishedJobs, new JobAttributes {
                    { "Name", "DeployServer" },
                }, cancellationToken).ConfigureAwait(false);

                // Create a rolling deploy relevant for my datacenter
                var creationService = new MongoJobCreationService(database);
                await creationService.Create(exampleQueueName, new JobAttributes
                {
                    { "Name", "RollingDeploy" },
                    { "Environment", "Prod" }
                }).ConfigureAwait(false);

                // Take Next available job
                var takeNextSubscriber = new TaskBasedTakeNextSubscriber(new MongoJobTakeNextService(database));
                var standardAck        = new JobAcknowledgment
                {
                    { "RunnerId", Guid.NewGuid().ToString("N") }
                };
                var peekQuery = new TakeNextOptions
                {
                    QueueId       = exampleQueueName,
                    HasAttributes = new JobAttributes {
                        { "Environment", "Prod" }
                    },
                    Acknowledgment = standardAck
                };
                await takeNextSubscriber.Subscribe(async rollingDeployJob =>
                {
                    // Send Reports
                    var reportService = new MongoJobReportService(database);
                    await
                    reportService.AddReport(exampleQueueName, rollingDeployJob.Id,
                                            new JobReport {
                        { "Timestamp", DateTime.UtcNow.ToString("O") }, { "Message", "Starting Rolling Deploy" }
                    }).ConfigureAwait(false);

                    var queryService = new MongoJobQueryService(database);

                    IEnumerable servers = new[] { "PROD2", "PROD1" };
                    foreach (var server in servers)
                    {
                        var deployServer = new JobAttributes
                        {
                            { "Name", "DeployServer" },
                            { "Server", server }
                        };

                        await reportService.AddReport(exampleQueueName, rollingDeployJob.Id,
                                                      new JobReport {
                            { "Timestamp", DateTime.UtcNow.ToString("O") }, { "Message", $"Requesting Deploy on server {server}" }
                        }).ConfigureAwait(false);
                        var deployServerJobId = await creationService.Create(exampleQueueName, deployServer).ConfigureAwait(false);

                        Job hasResult;
                        do
                        {
                            // replace with detail service
                            hasResult = (await queryService.QueryFor(new JobQuery {
                                QueueId = exampleQueueName, JobIds = new[] { deployServerJobId }, HasResult = true
                            }).ConfigureAwait(false)).FirstOrDefault();
                            Thread.Sleep(500);
                        } while (hasResult == null);

                        await reportService.AddReport(exampleQueueName, rollingDeployJob.Id,
                                                      new JobReport {
                            { "Timestamp", DateTime.UtcNow.ToString("O") }, { "Message", $"Deploy on server {server} Completed, {JsonConvert.SerializeObject(hasResult.Result)}" }
                        }).ConfigureAwait(false);
                        // inspect result
                    }

                    // Send Result
                    var completionService = new MongoJobCompletionService(database);
                    await completionService.Complete(exampleQueueName, rollingDeployJob.Id, new JobResult {
                        { "Result", "Success" }
                    }).ConfigureAwait(false);

                    var finalizedRollingDeployJob = await queryService.QueryFor(new JobQuery {
                        QueueId = exampleQueueName, JobIds = new[] { rollingDeployJob.Id }
                    }).ConfigureAwait(false);

                    cancellationSource.Cancel();

                    Console.WriteLine($"Finalized Rolling Deploy Job: {JsonConvert.SerializeObject(finalizedRollingDeployJob)}");

                    Assert.That(finalizedRollingDeployJob.First().Result["Result"], Is.EqualTo("Success"));
                }, new TakeNextSubscriptionOptions
                {
                    TakeNextOptions = peekQuery,
                    Token           = cancellationToken,
                }).ConfigureAwait(false);
            }).ConfigureAwait(false);
        }