public async Task Test_StatsAreCorrectlyUpdated_AfterDequeue_NoTaskType()
        {
            PostgreSqlTaskQueueInfo taskQueueInfo =
                CreateTaskQueueInfo(() => mDataSource.LastPostedAt);

            using (PostgreSqlTaskQueueConsumer taskQueueConsumer =
                       CreateTaskQueueConsumer(() => mDataSource.LastPostedAt))
                using (TaskQueueMetricsDiffChecker diff = new TaskQueueMetricsDiffChecker(async()
                                                                                          => await taskQueueInfo.ComputeMetricsAsync()))
                {
                    await diff.CaptureInitialMetricsAsync();

                    IQueuedTaskToken dequeuedToken = await taskQueueConsumer
                                                     .DequeueAsync();

                    QueuedTaskStatus origStatus = mDataSource
                                                  .GetOriginalTokenData(dequeuedToken.DequeuedTask.Id)
                                                  .LastQueuedTaskResult
                                                  .Status;

                    await diff.CaptureNewMetricsAndAssertCorrectDiff(delta : new TaskQueueMetrics(
                                                                         totalUnprocessed: origStatus == QueuedTaskStatus.Unprocessed ? -1 : 0,
                                                                         totalProcessing: 1,
                                                                         totalErrored: origStatus == QueuedTaskStatus.Error ? -1 : 0,
                                                                         totalFaulted: origStatus == QueuedTaskStatus.Faulted ? -1 : 0,
                                                                         totalFataled: origStatus == QueuedTaskStatus.Fatal ? -1 : 0,
                                                                         totalProcessed: origStatus == QueuedTaskStatus.Processed ? -1 : 0));
                }
        }
        public async Task Test_PeekMatchesDequeuedItem_SingleConsumer()
        {
            IQueuedTask      peekTask          = null;
            IQueuedTaskToken dequeuedTaskToken = null;

            PostgreSqlTaskQueueInfo taskQueueInfo =
                CreateTaskQueueInfo(() => mDataSource.LastPostedAt);

            using (PostgreSqlTaskQueueConsumer taskQueue =
                       CreateTaskQueueConsumer(() => mDataSource.LastPostedAt))
            {
                int expectedDequeueCount = mDataSource
                                           .NumTasksInQueue;

                for (int i = 0; i < expectedDequeueCount; i++)
                {
                    peekTask = await taskQueueInfo.PeekAsync();

                    Assert.NotNull(peekTask);

                    dequeuedTaskToken = await taskQueue.DequeueAsync();

                    Assert.NotNull(dequeuedTaskToken);

                    Assert.AreEqual(peekTask.Id, dequeuedTaskToken
                                    .DequeuedTask
                                    .Id);
                }
            }
        }
        public async Task Test_EnqueueDoesNotChangePeekResult_SingleConsumer()
        {
            int         futureTicks = 1;
            IQueuedTask peekTask    = null,
                        rePeekTask  = null;

            string taskType = typeof(SampleTaskPayload)
                              .FullName;

            PostgreSqlTaskQueueProducer taskQueueProducer = CreateTaskQueueProducer(() => mDataSource
                                                                                    .LastPostedAt
                                                                                    .AddTicks(1));

            PostgreSqlTaskQueueInfo taskQueueInfo = CreateTaskQueueInfo(() => mDataSource
                                                                        .LastPostedAt
                                                                        .AddTicks(futureTicks++));

            peekTask = await taskQueueInfo.PeekAsync();

            Assert.NotNull(peekTask);

            await taskQueueProducer.EnqueueAsync(payload : new SampleTaskPayload(100),
                                                 source : nameof(Test_EnqueueDoesNotChangePeekResult_SingleConsumer),
                                                 priority : 0);

            rePeekTask = await taskQueueInfo.PeekAsync();

            Assert.NotNull(rePeekTask);

            //Placing a new element in a queue occurs at its end,
            //  so peeking must not be affected
            //  if no other operation occurs
            Assert.AreEqual(peekTask.Id,
                            rePeekTask.Id);
        }
        public async Task Test_DequeueChangesPeekResult_SingleConsumer()
        {
            IQueuedTask peekTask   = null,
                        rePeekTask = null;

            IQueuedTaskToken dequeuedTaskToken = null;

            PostgreSqlTaskQueueInfo taskQueueInfo =
                CreateTaskQueueInfo(() => mDataSource.LastPostedAt);

            using (PostgreSqlTaskQueueConsumer taskQueueConsumer =
                       CreateTaskQueueConsumer(() => mDataSource.LastPostedAt))
            {
                peekTask = await taskQueueInfo.PeekAsync();

                Assert.NotNull(peekTask);

                dequeuedTaskToken = await taskQueueConsumer.DequeueAsync();

                Assert.NotNull(dequeuedTaskToken);

                rePeekTask = await taskQueueInfo.PeekAsync();

                Assert.NotNull(rePeekTask);

                //Removing a new element from the queue
                //  occurs at the beginning of the queue,
                //  so peeking must yield a different result
                //  than before dequeue-ing
                Assert.AreNotEqual(rePeekTask.Id,
                                   peekTask.Id);
            }
        }
        public async Task Test_StatsAreUpdatedCorrectly_AfterEnqueue_RepostExistingTask()
        {
            Faker faker =
                new Faker();

            DateTimeOffset postedAt = mDataSource.LastPostedAt
                                      .AddTicks(1);

            PostgreSqlTaskQueueProducer taskQueueProducer =
                CreateTaskQueueProducer(() => postedAt);

            PostgreSqlTaskQueueInfo taskQueueInfo =
                CreateTaskQueueInfo(() => postedAt);

            foreach (IQueuedTaskToken token in mDataSource.CanBeRepostedSeededTaskTokens)
            {
                using (TaskQueueMetricsDiffChecker diff = new TaskQueueMetricsDiffChecker(async()
                                                                                          => await taskQueueInfo.ComputeMetricsAsync()))
                {
                    QueuedTaskStatus prevStatus = token
                                                  .LastQueuedTaskResult
                                                  .Status;

                    await diff.CaptureInitialMetricsAsync();

                    QueuedTaskInfo repostTaskInfo = new QueuedTaskInfo()
                    {
                        Id            = token.DequeuedTask.Id,
                        Priority      = faker.Random.Int(1, 100),
                        Payload       = token.DequeuedTask.Payload,
                        Source        = nameof(Test_StatsAreUpdatedCorrectly_AfterEnqueue_RepostExistingTask),
                        Type          = token.DequeuedTask.Type,
                        LockedUntilTs = postedAt.AddMinutes(faker.Random.Long(1000, 10000))
                    };

                    //Remove task record from DB - only dequeued tasks get reposted
                    await mDataSource.RemoveQueuedTaskFromDbByIdAsync(token
                                                                      .DequeuedTask
                                                                      .Id);

                    await taskQueueProducer.EnqueueAsync(repostTaskInfo);

                    await diff.CaptureNewMetricsAndAssertCorrectDiff(delta : new TaskQueueMetrics(
                                                                         totalUnprocessed: prevStatus != QueuedTaskStatus.Unprocessed ? 1 : 0,
                                                                         totalProcessing: prevStatus == QueuedTaskStatus.Processing ? -1 : 0,
                                                                         totalErrored: prevStatus == QueuedTaskStatus.Error ? -1 : 0,
                                                                         totalFaulted: prevStatus == QueuedTaskStatus.Faulted ? -1 : 0,
                                                                         totalFataled: prevStatus == QueuedTaskStatus.Fatal ? -1 : 0,
                                                                         totalProcessed: prevStatus == QueuedTaskStatus.Processed ? -1 : 0));
                }
            }
        }
コード例 #6
0
        public async Task Test_CanPeek(int futureTicks)
        {
            IQueuedTask actualTopOfQueue;
            IQueuedTask expectedTopOfQueue = ExpectedTopOfQueueTask;

            for (int i = 0; i <= futureTicks; i++)
            {
                PostgreSqlTaskQueueInfo taskQueue = CreateTaskQueue(() => mDataSource
                                                                    .LastPostedAt
                                                                    .AddTicks(futureTicks));

                actualTopOfQueue = await taskQueue.PeekAsync();

                Assert.NotNull(actualTopOfQueue);
                Assert.AreEqual(expectedTopOfQueue.Id,
                                actualTopOfQueue.Id);
            }
        }
コード例 #7
0
        public ITaskEngine BuildTaskEngine()
        {
            ITaskExecutorRegistry executorRegistry = mTaskExecutorRegistrySetup
                                                     .BuildTaskExecutorRegistry();

            IExecutionPerformanceMonitorWriter executionPerfMonWriter = mPerformanceMonitorWriterSetup
                                                                        .BuildWriter();

            ITimestampProvider timestampProvider =
                new UtcNowTimestampProvider();

            TaskQueueConsumerOptions consumerOptions = mTaskQueueConsumerSetup
                                                       .BuildOptions();

            TaskQueueOptions producerOptions = mTaskQueueProducerSetup
                                               .BuildOptions();

            StakhanoviseLogManager.Provider = mLoggingProvider
                                              ?? new NoOpLoggingProvider();

            ITaskQueueProducer taskQueueProducer = new PostgreSqlTaskQueueProducer(producerOptions,
                                                                                   timestampProvider);

            ITaskQueueInfo taskQueueInfo = new PostgreSqlTaskQueueInfo(mTaskQueueInfoSetup.BuildOptions(),
                                                                       timestampProvider);

            if (mRegisterOwnDependencies)
            {
                executorRegistry.LoadDependencies(new Dictionary <Type, object>()
                {
                    { typeof(ITaskQueueProducer),
                      taskQueueProducer },
                    { typeof(ITaskQueueInfo),
                      taskQueueInfo }
                });
            }

            return(mTaskEngineSetup.BuildTaskEngine(consumerOptions,
                                                    producerOptions,
                                                    executorRegistry,
                                                    executionPerfMonWriter,
                                                    timestampProvider));
        }
コード例 #8
0
        public async Task Test_CanComputeQueueMetrics(int futureTicks)
        {
            for (int i = 0; i <= futureTicks; i++)
            {
                PostgreSqlTaskQueueInfo taskQueue = CreateTaskQueue(() => mDataSource
                                                                    .LastPostedAt
                                                                    .AddTicks(futureTicks));

                TaskQueueMetrics metrics = await taskQueue
                                           .ComputeMetricsAsync();

                Assert.NotNull(metrics);
                Assert.AreEqual(mDataSource.NumUnProcessedTasks, metrics.TotalUnprocessed);
                Assert.AreEqual(mDataSource.NumErroredTasks, metrics.TotalErrored);
                Assert.AreEqual(mDataSource.NumFaultedTasks, metrics.TotalFaulted);
                Assert.AreEqual(mDataSource.NumFatalTasks, metrics.TotalFataled);
                Assert.AreEqual(mDataSource.NumProcessedTasks, metrics.TotalProcessed);
            }
        }
        public async Task Test_StatsAreUpdatedCorrectly_AfterEnqueue_NewTask()
        {
            Faker faker =
                new Faker();

            DateTimeOffset postedAt = mDataSource.LastPostedAt
                                      .AddTicks(1);

            PostgreSqlTaskQueueProducer taskQueueProducer =
                CreateTaskQueueProducer(() => postedAt);

            PostgreSqlTaskQueueInfo taskQueueInfo =
                CreateTaskQueueInfo(() => postedAt);

            using (PostgreSqlTaskQueueConsumer taskQueueConsumer =
                       CreateTaskQueueConsumer(() => postedAt))
                using (TaskQueueMetricsDiffChecker diff = new TaskQueueMetricsDiffChecker(async()
                                                                                          => await taskQueueInfo.ComputeMetricsAsync()))
                {
                    await taskQueueConsumer.StartReceivingNewTaskUpdatesAsync();

                    Assert.IsTrue(taskQueueConsumer.IsReceivingNewTaskUpdates);

                    //Capture previous metrics
                    await diff.CaptureInitialMetricsAsync();

                    await taskQueueProducer.EnqueueAsync(payload : new SampleTaskPayload(100),
                                                         source : nameof(Test_StatsAreUpdatedCorrectly_AfterEnqueue_NewTask),
                                                         priority : faker.Random.Int(1, 100));

                    //Check that new metrics differ from the previous ones as expected
                    await diff.CaptureNewMetricsAndAssertCorrectDiff(delta : new TaskQueueMetrics(
                                                                         totalUnprocessed: 1,
                                                                         totalProcessing: 0,
                                                                         totalErrored: 0,
                                                                         totalFaulted: 0,
                                                                         totalFataled: 0,
                                                                         totalProcessed: 0));
                }
        }