public void Test_CanCompare_ExpectedNotEqual_WithError(bool isRecoverable) { Faker faker = new Faker(); Exception exc = faker.System.Exception(); TaskExecutionResultInfo failedWithErrorInfo1 = TaskExecutionResultInfo .ExecutedWithError(new QueuedTaskError(exc), isRecoverable); TaskExecutionResultInfo failedWithErrorInfo2 = TaskExecutionResultInfo .ExecutedWithError(new QueuedTaskError(exc), isRecoverable); TimeSpan sampleDuration1 = faker.Date.Timespan(); DateTimeOffset sampleRetryAt1 = faker.Date.SoonOffset(); int sampleFaultErrorThresholdCount1 = faker.Random.Int(1, 5); TimeSpan sampleDuration2 = faker.Date.Timespan(); DateTimeOffset sampleRetryAt2 = faker.Date.SoonOffset(); int sampleFaultErrorThresholdCount2 = faker.Random.Int(1, 5); TaskExecutionResult failedWithError1 = new TaskExecutionResult(failedWithErrorInfo1, duration: sampleDuration1, retryAt: sampleRetryAt1, faultErrorThresholdCount: sampleFaultErrorThresholdCount1); TaskExecutionResult failedWithError2 = new TaskExecutionResult(failedWithErrorInfo2, duration: sampleDuration2, retryAt: sampleRetryAt2, faultErrorThresholdCount: sampleFaultErrorThresholdCount2); Assert.AreNotEqual(failedWithError1, failedWithError2); }
public void Test_CanCompare_ExpectedNotEqual_Cancelled() { Faker faker = new Faker(); TaskExecutionResultInfo cancelledInfo1 = TaskExecutionResultInfo.Cancelled(); TimeSpan sampleDuration1 = faker.Date.Timespan(); DateTimeOffset sampleRetryAt1 = faker.Date.RecentOffset(); int sampleFaultErrorThresholdCount1 = faker.Random.Int(1, 5); TaskExecutionResultInfo cancelledInfo2 = TaskExecutionResultInfo.Cancelled(); TimeSpan sampleDuration2 = faker.Date.Timespan(); DateTimeOffset sampleRetry2 = faker.Date.PastOffset(); int sampleFaultErrorThresholdCount2 = faker.Random.Int(1, 5); TaskExecutionResult cancelled1 = new TaskExecutionResult(cancelledInfo1, duration: sampleDuration1, retryAt: sampleRetryAt1, faultErrorThresholdCount: sampleFaultErrorThresholdCount1); TaskExecutionResult cancelled2 = new TaskExecutionResult(cancelledInfo2, duration: sampleDuration2, retryAt: sampleRetry2, faultErrorThresholdCount: sampleFaultErrorThresholdCount2); Assert.AreNotEqual(cancelled1, cancelled2); }
public void Execute_ShouldLaunchProcessAndWaitForExitEvent() { var task = AutoFixture.Create <Task>(); var expectedTaskResult = new TaskExecutionResult(TaskExecutionResult.TaskExecutionStatus.Failed, task.WorkItemId, null); expectedTaskResult.AddLogEntry(TaskExecutor.RunnerNotFoundOnAgent.FormatWith(new { task.Runner })); const int millisecondsBeforeExit = 3000; Action <ProcessStartInfo, EventHandler <string>, EventHandler <string> > startProcess = (info, exitHandler, outputHandler) => { var process = CreateProcess(millisecondsBeforeExit); process.Exited += exitHandler; process.Start(); }; _processRunner.Setup(p => p.Start(It.IsAny <ProcessStartInfo>(), It.IsAny <EventHandler <string> >(), It.IsAny <EventHandler <string> >())).Callback(startProcess); _fileSystemMock.Setup(s => s.Exists(It.IsAny <string>())).Returns(true); var ms = TimeExecution(() => _taskExecutor.Execute(task)); _processRunner.Verify(p => p.Start(It.IsAny <ProcessStartInfo>(), It.IsAny <EventHandler <string> >(), It.IsAny <EventHandler <string> >()), Times.Once()); ms.Should().BeGreaterOrEqualTo(TimeSpan.FromMilliseconds(millisecondsBeforeExit - 100)); }
public void Test_CanCompare_ExpectedNotEqual_Successful() { Faker faker = new Faker(); TaskExecutionResultInfo successfulInfo1 = TaskExecutionResultInfo.Successful(); TimeSpan sampleDuration1 = faker.Date.Timespan(); DateTimeOffset sampleRetryAt1 = faker.Date.RecentOffset(); int sampleFaultErrorThresholdCount1 = faker.Random.Int(1, 5); TaskExecutionResultInfo successfulInfo2 = TaskExecutionResultInfo.Successful(); TimeSpan sampleDuration2 = faker.Date.Timespan(); DateTimeOffset sampleRetryAt2 = faker.Date.RecentOffset(); int sampleFaultErrorThresholdCount2 = faker.Random.Int(1, 5); TaskExecutionResult successful1 = new TaskExecutionResult(successfulInfo1, duration: sampleDuration1, retryAt: sampleRetryAt1, faultErrorThresholdCount: sampleFaultErrorThresholdCount1); TaskExecutionResult successful2 = new TaskExecutionResult(successfulInfo2, duration: sampleDuration2, retryAt: sampleRetryAt2, faultErrorThresholdCount: sampleFaultErrorThresholdCount2); Assert.AreNotEqual(successful1, successful2); }
public QueuedTaskInfo UdpateFromExecutionResult(TaskExecutionResult result) { QueuedTaskInfo repostTask = null; //Task processing lifecycle ends with one of these statuses // Hence, if the result reaches one of these points, // no more updates can be performed if (Status == QueuedTaskStatus.Fatal || Status == QueuedTaskStatus.Cancelled || Status == QueuedTaskStatus.Processed) { throw new InvalidOperationException($"A result with {Status} status can no longer be updated"); } if (result.ExecutedSuccessfully) { Processed(result); } else if (result.ExecutionFailed) { repostTask = HadError(result); } else if (result.ExecutionCancelled) { Cancelled(result); } return(repostTask); }
public void Test_CanUpdateFromExecutionResult_Successful() { Faker faker = new Faker(); DateTimeOffset now = DateTimeOffset .UtcNow; Faker <QueuedTask> taskFaker = GetQueuedTaskFaker(); QueuedTask task = taskFaker .Generate(); QueuedTaskResult result = new QueuedTaskResult(task); TaskExecutionResult successful = new TaskExecutionResult(TaskExecutionResultInfo.Successful(), duration: faker.Date.Timespan(), retryAt: faker.Date.FutureOffset(), faultErrorThresholdCount: faker.Random.Int(1, 5)); QueuedTaskInfo repostWithInfo = result.UdpateFromExecutionResult(successful); Assert.Null(repostWithInfo); Assert.IsNull(result.LastError); Assert.AreEqual(QueuedTaskStatus.Processed, result.Status); Assert.AreEqual(successful.ProcessingTimeMilliseconds, result.ProcessingTimeMilliseconds); Assert.GreaterOrEqual(result.ProcessingFinalizedAtTs, now); Assert.GreaterOrEqual(result.FirstProcessingAttemptedAtTs, now); Assert.GreaterOrEqual(result.LastProcessingAttemptedAtTs, now); }
private async Task ExecuteAndProcessResultAsync ( IQueuedTaskToken queuedTaskToken, CancellationToken stopToken ) { mLogger.DebugFormat( "New task to execute retrieved from buffer: task id = {0}.", queuedTaskToken.DequeuedTask.Id ); //Prepare execution context TaskExecutionContext executionContext = new TaskExecutionContext( queuedTaskToken, stopToken ); //Execute task TaskExecutionResult executionResult = await ExecuteTaskAsync( executionContext ); //We will not observe cancellation token // during result processing: // if task executed till the end, we must at least // attempt to set the result if (executionResult != null) await ProcessResultAsync( queuedTaskToken, executionResult ); mLogger.DebugFormat( "Done executing task with id = {0}.", queuedTaskToken.DequeuedTask.Id ); }
public void Test_CanCreate_WithError(bool isRecoverable) { Faker faker = new Faker(); Exception exc = faker.System.Exception(); TaskExecutionResultInfo failedWithErrorInfo = TaskExecutionResultInfo .ExecutedWithError(new QueuedTaskError(exc), isRecoverable); TimeSpan sampleDuration = faker.Date.Timespan(); DateTimeOffset sampleRetryAt = faker.Date.RecentOffset(); int sampleFaultErrorThresholdCount = faker.Random.Int(1, 5); TaskExecutionResult failedWithError = new TaskExecutionResult(failedWithErrorInfo, duration: sampleDuration, retryAt: sampleRetryAt, faultErrorThresholdCount: sampleFaultErrorThresholdCount); Assert.IsFalse(failedWithError.ExecutedSuccessfully); Assert.IsFalse(failedWithError.ExecutionCancelled); Assert.IsTrue(failedWithError.ExecutionFailed); Assert.NotNull(failedWithError.Error); Assert.AreEqual(failedWithErrorInfo.Error, failedWithError.Error); Assert.AreEqual(( long )(Math.Ceiling(sampleDuration.TotalMilliseconds)), failedWithError.ProcessingTimeMilliseconds); Assert.AreEqual(sampleRetryAt, failedWithError.RetryAt); Assert.AreEqual(sampleFaultErrorThresholdCount, failedWithError.FaultErrorThresholdCount); }
public ActionResult Complete(TaskExecutionResult executionResult) { return(Json(_taskService.WorkComplete(new WorkerRequest <TaskExecutionResult>(_context.Token) { Body = executionResult }))); }
private QueuedTaskInfo HadError(TaskExecutionResult result) { LastError = result.Error; LastErrorIsRecoverable = result.IsRecoverable; ErrorCount += 1; if (!FirstProcessingAttemptedAtTs.HasValue) { FirstProcessingAttemptedAtTs = DateTimeOffset.UtcNow; } LastProcessingAttemptedAtTs = DateTimeOffset.UtcNow; //If the error is recoverable, work out the status transition // from the current error count if (result.IsRecoverable) { if (ErrorCount > result.FaultErrorThresholdCount + 1) { Status = QueuedTaskStatus.Fatal; } else if (ErrorCount > result.FaultErrorThresholdCount) { Status = QueuedTaskStatus.Faulted; } else { Status = QueuedTaskStatus.Error; } } else { //Otherwise, set it to fatal Status = QueuedTaskStatus.Fatal; } //If status is not fatal, compute the information // necessary to retry task execution if (Status != QueuedTaskStatus.Fatal) { return(new QueuedTaskInfo() { Id = Id, Payload = Payload, Type = Type, Source = Source, Priority = Priority, LockedUntilTs = result.RetryAt }); } else { return(null); } }
private async Task ProcessResultAsync ( IQueuedTaskToken queuedTaskToken, TaskExecutionResult result ) { try { //Update worker execution stats UpdateTaskProcessingStats( result ); //There is no result - most likely, no executor found; // nothing to process, just stop and return if ( !result.HasResult ) { mLogger.Debug( "No result info returned. Task will be discarded." ); return; } //Execution has been cancelled, usually as a response // to a cancellation request; // nothing to process, just stop and return if ( result.ExecutionCancelled ) { mLogger.Debug( "Task execution cancelled. Task will be discarded." ); return; } //Update execution result and see whether // we need to repost the task to retry its execution QueuedTaskInfo repostWithInfo = queuedTaskToken .UdpateFromExecutionResult( result ); //Post result mLogger.Debug( "Will post task execution result." ); await mTaskResultQueue.PostResultAsync( queuedTaskToken ); mLogger.Debug( "Successfully posted task execution result." ); //If the task needs to be reposted, do so if ( repostWithInfo != null ) { mLogger.Debug( "Will repost task for execution." ); await mTaskQueueProducer.EnqueueAsync( repostWithInfo ); mLogger.Debug( "Sucessfully reposted task for execution." ); } else mLogger.Debug( "Will not repost task for execution." ); //Finally, report execution time await mPerformanceMonitor.ReportExecutionTimeAsync( queuedTaskToken, result ); } catch ( Exception exc ) { mLogger.Error( "Failed to set queued task result. Task will be discarded.", exc ); } }
private void TryGetConsoleBuffer(TaskExecutionResult result) { try { result.Console = string.Join(Environment.NewLine, ((ConsolePluginWeb)_consolePlugin).Buffer); } catch (Exception) { // ignore } }
private void Cancelled(TaskExecutionResult result) { Status = QueuedTaskStatus.Cancelled; ProcessingFinalizedAtTs = DateTimeOffset.UtcNow; if (!FirstProcessingAttemptedAtTs.HasValue) { FirstProcessingAttemptedAtTs = DateTimeOffset.UtcNow; } LastProcessingAttemptedAtTs = DateTimeOffset.UtcNow; }
internal static string ToSerializedValue(this TaskExecutionResult value) { switch (value) { case TaskExecutionResult.Success: return("success"); case TaskExecutionResult.Failure: return("failure"); } return(null); }
public void Execute(Task task) { _log.Debug(string.Format("Task Started {0} at {1}", task.WorkItemId, DateTime.Now)); if (!_fileSystem.Exists(task.Runner)) { var taskExecutionResult = new TaskExecutionResult(TaskExecutionResult.TaskExecutionStatus.Failed, task.WorkItemId, null); taskExecutionResult.AddLogEntry(RunnerNotFoundOnAgent.FormatWith(new { task.Runner })); _channel.WorkComplete(taskExecutionResult); return; } CreateWorkingDirectory(task.WorkDirectoryArchive); var startInfo = new ProcessStartInfo { WorkingDirectory = WorkingDirectory, FileName = task.Runner, Arguments = task.Arguments }; var resetEvent = new ManualResetEvent(false); //spawn process on a new thread to prevent take down of main thread ThreadPool.QueueUserWorkItem(state => { try { EventHandler <string> exitEvent = (sender, args) => { //signal to main thread that our work is done resetEvent.Set(); var zip = GetsArtifacts(task); var taskExecutionResult = new TaskExecutionResult(TaskExecutionResult.TaskExecutionStatus.Succeeded, task.WorkItemId, zip); taskExecutionResult.AddLogEntry(args); _channel.WorkComplete(taskExecutionResult); }; EventHandler <string> outputEvent = (sender, output) => _log.WriteToConsole(output); _processRunner.Start(startInfo, exitEvent, outputEvent); } catch (Exception e) { _log.Error(e); resetEvent.Set(); var result = new TaskExecutionResult(TaskExecutionResult.TaskExecutionStatus.Failed, task.WorkItemId, null); result.AddException(e); _channel.WorkComplete(result); } }); resetEvent.WaitOne(); _log.Debug(string.Format("Task Ended {0} at {1}", task.WorkItemId, DateTime.Now)); }
private void Processed(TaskExecutionResult result) { LastError = null; LastErrorIsRecoverable = false; ProcessingFinalizedAtTs = DateTimeOffset.UtcNow; ProcessingTimeMilliseconds = result.ProcessingTimeMilliseconds; if (!FirstProcessingAttemptedAtTs.HasValue) { FirstProcessingAttemptedAtTs = DateTimeOffset.UtcNow; } LastProcessingAttemptedAtTs = DateTimeOffset.UtcNow; Status = QueuedTaskStatus.Processed; }
public void Execute_ShouldSendFailureToServerChannel_WhenProcessStartThrows() { var task = AutoFixture.Create <Task>(); var expectedTaskResult = new TaskExecutionResult(TaskExecutionResult.TaskExecutionStatus.Failed, task.WorkItemId, null); var exception = AutoFixture.Create <System.ComponentModel.Win32Exception>(); expectedTaskResult.AddException(exception); _processRunner.Setup(p => p.Start(It.IsAny <ProcessStartInfo>(), It.IsAny <EventHandler <string> >(), It.IsAny <EventHandler <string> >())).Throws(exception); _fileSystemMock.Setup(fs => fs.Exists(It.IsAny <string>())).Returns(true); _taskExecutor.Execute(task); _serverChannel.Verify(sc => sc.WorkComplete(expectedTaskResult)); }
public ViewResult Index() { try { IApplicationContext integrationService = OwinContext.GetIntegrationService(); var runner = integrationService.Resolve <ITaskRunner>(); var factory = integrationService.Resolve <ITaskFactory>(); TaskExecutionResult result = runner.Execute(factory.Get <WriteDocumentationTask>()); return(View(result)); } catch { return(View(new TaskExecutionResult(new[] { "A" }))); } }
public void WorkComplete_ShouldUpdateWorkItemWithCorrectStatus( TaskExecutionResult.TaskExecutionStatus taskStatus, WorkItemStatus workItemStatus) { var taskResult = new TaskExecutionResult(taskStatus, 1, null); var workItem = AutoFixture.Create <WorkItem>(); workItem.AssignTo(AutoFixture.Create <WorkerRegistration>()); _mockRepository.Setup(r => r.Get <WorkItem>(taskResult.WorkItemId)).Returns(workItem); _mockRepository.Setup(r => r.Put(It.Is <WorkItem>(wi => wi.Status.Equals(workItemStatus)))).Verifiable(); _taskServiceWithMockRepository.WorkComplete(new WorkerRequest <TaskExecutionResult>(Guid.NewGuid()) { Body = taskResult }); _mockRepository.VerifyAll(); }
public void Test_CanUpdateFromExecutionResult_WithError_NotRecoverable(int faultErrorThresholdCount) { Faker faker = new Faker(); DateTimeOffset now = DateTimeOffset .UtcNow; Faker <QueuedTask> taskFaker = GetQueuedTaskFaker(); QueuedTask task = taskFaker .Generate(); QueuedTaskResult result = new QueuedTaskResult(task); TaskExecutionResultInfo failedWithErrorInfo = TaskExecutionResultInfo .ExecutedWithError(new QueuedTaskError(faker.System.Exception()), isRecoverable: false); TaskExecutionResult failedWithError = new TaskExecutionResult(failedWithErrorInfo, duration: faker.Date.Timespan(), retryAt: faker.Date.FutureOffset(), faultErrorThresholdCount: faultErrorThresholdCount); for (int i = 1; i <= faultErrorThresholdCount + 2; i++) { if (i > 1) { Assert.Throws <InvalidOperationException>(() => result.UdpateFromExecutionResult(failedWithError)); } else { Assert.IsNull(result.UdpateFromExecutionResult(failedWithError)); } Assert.AreEqual(1, result.ErrorCount); Assert.AreEqual(failedWithErrorInfo.Error, result.LastError); Assert.IsFalse(result.LastErrorIsRecoverable); Assert.AreEqual(QueuedTaskStatus.Fatal, result.Status); Assert.AreEqual(0, result.ProcessingTimeMilliseconds); Assert.GreaterOrEqual(result.FirstProcessingAttemptedAtTs, now); Assert.GreaterOrEqual(result.LastProcessingAttemptedAtTs, now); } }
private void UpdateTaskProcessingStats ( TaskExecutionResult result ) { mMetrics.UpdateMetric( AppMetricId.WorkerProcessedPayloadCount, m => m.Increment() ); mMetrics.UpdateMetric( AppMetricId.WorkerTotalProcessingTime, m => m.Add( result.ProcessingTimeMilliseconds ) ); if ( result.ExecutedSuccessfully ) mMetrics.UpdateMetric( AppMetricId.WorkerSuccessfulProcessedPayloadCount, m => m.Increment() ); else if ( result.ExecutionFailed ) mMetrics.UpdateMetric( AppMetricId.WorkerFailedProcessedPayloadCount, m => m.Increment() ); else if ( result.ExecutionCancelled ) mMetrics.UpdateMetric( AppMetricId.WorkerProcessingCancelledPayloadCount, m => m.Increment() ); }
public IActionResult Post(string taskName, [FromBody] IDictionary <string, object> parameters) { var taskList = _taskLocator.GetTaskHolderList(); var task = taskList.FirstOrDefault(t => t.Key == taskName); if (task == null) { return(NotFound()); } var definition = task.Task.GetTaskParameterDefinition(); if (definition.Any(d => d.Type == TaskParameterType.CustomConsole)) { return(BadRequest("This task is only enabled for console client")); } _consolePlugin.Flush(); var result = new TaskExecutionResult(); try { task.Task.Execute(parameters); TryGetConsoleBuffer(result); result.Success = true; } catch (Exception ex) { result.Success = false; result.ExceptionMessage = UtilString.GetStringException(ex); TryGetConsoleBuffer(result); var r = new ObjectResult(result) { StatusCode = StatusCodes.Status500InternalServerError }; return(r); } return(Ok(result)); }
public void Test_CanCompare_ExpectedEquals_Successful() { Faker faker = new Faker(); TaskExecutionResultInfo successfulInfo = TaskExecutionResultInfo.Successful(); TimeSpan sampleDuration = faker.Date.Timespan(); DateTimeOffset sampleRetryAt = faker.Date.RecentOffset(); int sampleFaultErrorThresholdCount = faker.Random.Int(1, 5); TaskExecutionResult successful1 = new TaskExecutionResult(successfulInfo, duration: sampleDuration, retryAt: sampleRetryAt, faultErrorThresholdCount: sampleFaultErrorThresholdCount); TaskExecutionResult successful2 = new TaskExecutionResult(successfulInfo, duration: sampleDuration, retryAt: sampleRetryAt, faultErrorThresholdCount: sampleFaultErrorThresholdCount); Assert.AreEqual(successful1, successful2); Assert.AreEqual(successful1, successful1); }
public void Test_CanCompare_ExpectedEquals_Cancelled() { Faker faker = new Faker(); TaskExecutionResultInfo cancelledInfo = TaskExecutionResultInfo.Cancelled(); TimeSpan sampleDuration = faker.Date.Timespan(); DateTimeOffset sampleRetryAt = faker.Date.RecentOffset(); int sampleFaultErrorThresholdCount = faker.Random.Int(1, 5); TaskExecutionResult cancelled1 = new TaskExecutionResult(cancelledInfo, duration: sampleDuration, retryAt: sampleRetryAt, faultErrorThresholdCount: sampleFaultErrorThresholdCount); TaskExecutionResult cancelled2 = new TaskExecutionResult(cancelledInfo, duration: sampleDuration, retryAt: sampleRetryAt, faultErrorThresholdCount: sampleFaultErrorThresholdCount); Assert.AreEqual(cancelled1, cancelled2); Assert.AreEqual(cancelled1, cancelled1); }
public void Execute_ShouldSendSuccessToServerChannel_WhenProcessExecutesSuccessfully() { var task = AutoFixture.Create <Task>(); var expectedTaskResult = new TaskExecutionResult(TaskExecutionResult.TaskExecutionStatus.Succeeded, task.WorkItemId, null); expectedTaskResult.AddLogEntry(string.Empty); Action <ProcessStartInfo, EventHandler <string>, EventHandler <String> > startProcess = (info, exitHandler, handler) => { var process = new FakeProcess(50); process.Exited += exitHandler; process.Start(); }; _processRunner.Setup(p => p.Start(It.IsAny <ProcessStartInfo>(), It.IsAny <EventHandler <string> >(), It.IsAny <EventHandler <string> >())).Callback(startProcess); _fileSystemMock.Setup(fs => fs.Exists(It.IsAny <string>())).Returns(true); _taskExecutor.Execute(task); _serverChannel.Verify(sc => sc.WorkComplete(expectedTaskResult)); }
public void Execute_ShouldLogAndExit_WhenRunnerNotFoundOnFileSystem() { var task = AutoFixture.Create <Task>(); var expectedTaskResult = new TaskExecutionResult(TaskExecutionResult.TaskExecutionStatus.Failed, task.WorkItemId, null); expectedTaskResult.AddLogEntry(TaskExecutor.RunnerNotFoundOnAgent.FormatWith(new { task.Runner })); CreateProcess(2000); _processRunner.Setup(p => p.Start(It.IsAny <ProcessStartInfo>(), It.IsAny <EventHandler <string> >(), It.IsAny <EventHandler <string> >())); _fileSystemMock.Setup(s => s.Exists(It.IsAny <string>())).Returns(false); _serverChannel.Setup(s => s.WorkComplete(expectedTaskResult)) .Returns(new Response(false, "")) .Verifiable(); _taskExecutor.Execute(task); _processRunner.Verify(p => p.Start(It.IsAny <ProcessStartInfo>(), It.IsAny <EventHandler <string> >(), It.IsAny <EventHandler <string> >()), Times.Never()); _serverChannel.Verify(); }
public void Test_CanCompare_ExpectedEquals_WithError(bool isRecoverable) { Faker faker = new Faker(); Exception exc = faker.System.Exception(); TaskExecutionResultInfo failedWithErrorInfo = TaskExecutionResultInfo .ExecutedWithError(new QueuedTaskError(exc), isRecoverable); TimeSpan sampleDuration = faker.Date.Timespan(); DateTimeOffset sampleRetryAt = faker.Date.RecentOffset(); int sampleFaultErrorThresholdCount = faker.Random.Int(1, 5); TaskExecutionResult failedWithError1 = new TaskExecutionResult(failedWithErrorInfo, duration: sampleDuration, retryAt: sampleRetryAt, faultErrorThresholdCount: sampleFaultErrorThresholdCount); TaskExecutionResult failedWithError2 = new TaskExecutionResult(failedWithErrorInfo, duration: sampleDuration, retryAt: sampleRetryAt, faultErrorThresholdCount: sampleFaultErrorThresholdCount); Assert.AreEqual(failedWithError1, failedWithError2); Assert.AreEqual(failedWithError1, failedWithError1); }
public void Test_CanCreate_Cancelled() { Faker faker = new Faker(); TaskExecutionResultInfo cancelledInfo = TaskExecutionResultInfo.Cancelled(); TimeSpan sampleDuration = faker.Date.Timespan(); DateTimeOffset sampleRetryAt = faker.Date.RecentOffset(); int sampleFaultErrorThresholdCount = faker.Random.Int(1, 5); TaskExecutionResult cancelled = new TaskExecutionResult(cancelledInfo, duration: sampleDuration, retryAt: sampleRetryAt, faultErrorThresholdCount: sampleFaultErrorThresholdCount); Assert.IsFalse(cancelled.ExecutedSuccessfully); Assert.IsTrue(cancelled.ExecutionCancelled); Assert.IsFalse(cancelled.ExecutionFailed); Assert.IsNull(cancelled.Error); Assert.AreEqual(( long )(Math.Ceiling(sampleDuration.TotalMilliseconds)), cancelled.ProcessingTimeMilliseconds); Assert.AreEqual(sampleRetryAt, cancelled.RetryAt); Assert.AreEqual(sampleFaultErrorThresholdCount, cancelled.FaultErrorThresholdCount); }
public static async Task ReportExecutionTimeAsync(this IExecutionPerformanceMonitor executionPerformanceMonitor, IQueuedTaskToken queuedTaskToken, TaskExecutionResult result) { if (executionPerformanceMonitor == null) { throw new ArgumentNullException(nameof(executionPerformanceMonitor)); } if (queuedTaskToken == null) { throw new ArgumentNullException(nameof(queuedTaskToken)); } if (result == null) { throw new ArgumentNullException(nameof(result)); } await executionPerformanceMonitor.ReportExecutionTimeAsync( queuedTaskToken.DequeuedTask.Type, result.ProcessingTimeMilliseconds, timeoutMilliseconds : 0); }
public static string ToSerialString(this TaskExecutionResult value) => value switch {