public virtual async Task RunAsync(TimeSpan executionTimeout) { if (ApplicationBuilder.RegisteredMiddleWares.Count == 0) { return; } try { // generate the middleware stack var stack = new Stack <Func <WorkerApplicationOperation, IWorkerApplicationMiddlewareExecutionController, Task> >(ApplicationBuilder.RegisteredMiddleWares.Reverse()); // generate the worker operation context using (var operation = new WorkerApplicationOperation(ApplicationBuilder.ApplicationServices.CreateScope())) { try { // this executes all the regular middlewares var executionTask = ExecuteNextMiddleWare(stack, operation); // wait for the execution task var waitResult = await timeoutService.WaitForExecution(executionTask, executionTimeout); // handle result if (waitResult == TimoutServiceWaitResult.taskTimedout) { foreach (var timeoutMiddleware in ApplicationBuilder.RegisteredTimeoutMiddleWares) { await timeoutMiddleware(operation); } } else { if (executionTask.Exception != null) { throw executionTask.Exception.InnerException; } } } catch (Exception e) { var logger = LoggerFactory.CreateLogger("WorkerHost"); logger.LogError(new EventId(0), e, "Unhandled exception during middleware execution (with operation)"); foreach (var errorMiddleware in ApplicationBuilder.RegisteredErrorMiddleWares) { await errorMiddleware(operation, e); } } } } catch (Exception e) { var logger = LoggerFactory.CreateLogger("WorkerHost"); logger.LogError(new EventId(0), e, "Unhandled exception during middleware execution"); foreach (var errorMiddleware in ApplicationBuilder.RegisteredErrorMiddleWares) { await errorMiddleware(null, e); } } }
private async Task ExecuteNextMiddleWare(Stack <Func <WorkerApplicationOperation, IWorkerApplicationMiddlewareExecutionController, Task> > stack, WorkerApplicationOperation operation) { if (stack.Count == 0) { return; } var middleware = stack.Pop(); var executionController = new WorkerApplicationMiddlewareExecutionController(); await executionController.Execute(operation, middleware, async() => { await(ExecuteNextMiddleWare(stack, operation)); }, async() => { await Task.CompletedTask; }); }