/// <summary> /// Runs the execution of unfinished work scheduled to be executed up to the current time. /// </summary> public void RunScheduledExecutors() { List <ExecutorWorkload> workLoads; List <ExecutorState> currentStates; List <ExecutorState> newStates = new List <ExecutorState>(); List <ExecutionProtocol> newProtocols = new List <ExecutionProtocol>(); using (ExecutionContext context = new ExecutionContext()) { workLoads = (from work in context.Workloads where work.Done == false && work.Scheduled >= DateTime.Now orderby work.Scheduled select work).ToList(); currentStates = (from state in context.ExecutorStates where state.IsActive select state).ToList(); } foreach (ExecutorWorkload work in workLoads) { IExecutor executor = executors[work.ExecutorId]; ExecutorState oldState = currentStates.Where(s => s.ExecutorId == executor.ExecutorId).FirstOrDefault(); if (oldState != null) { executor.SetState(oldState); } Stopwatch watch = new System.Diagnostics.Stopwatch(); DateTime lastExecuted = DateTime.MinValue; try { Trace.Write(String.Format("Checking workload by exeutor {0} ({1})", executor.ExecutorName, executor.ExecutorId), TRACE_CATEG); try { executor.Check(); } catch (Exception checkEx) { Trace.Write(String.Format("Executor could not be run: {0}", checkEx.Message), TRACE_CATEG); continue; } lastExecuted = DateTime.Now; watch.Start(); executor.Execute(); watch.Stop(); } catch (Exception executionException) { Trace.Write(String.Format("Error during execution: {0}", executionException.Message), TRACE_CATEG); try { executor.Rollback(); } catch (Exception rollbackEx) { Trace.Write(String.Format("Rollback failed: {0}", rollbackEx.Message), TRACE_CATEG); throw; } } ExecutionProtocol protocol = new ExecutionProtocol(); XDocument protocolExtra; long outputProduced; ExecutorState newState = executor.Conclude(out outputProduced, out protocolExtra); newState.LastExecuted = DateTime.Now; newState.TotalExecutionTime += watch.ElapsedMilliseconds; newState.TotalOutputProduced += protocol.OutputProduced; newState.TotalExecutions++; protocol.Settings = protocolExtra; protocol.OutputProduced = outputProduced; protocol.ExecutorId = executor.ExecutorId; protocol.Workload = work; protocol.ExecutionTime = watch.ElapsedMilliseconds; protocol.StateBefore = oldState; protocol.StateAfter = newState; newState.IsActive = true; oldState.IsActive = false; newStates.Add(newState); newProtocols.Add(protocol); work.Done = true; } // Maybe the Find is not necessary and a reference is kept to the original object. using (ExecutionContext context = new ExecutionContext()) { foreach (var newState in newStates) { context.ExecutorStates.Add(newState); var oldState = context.ExecutorStates.Find(newState.ExecutorId); oldState.IsActive = false; } foreach (var work in workLoads.Where(w => w.Done == true)) { var oldWork = context.Workloads.Find(work.WorkloadId); oldWork.Done = true; } foreach (ExecutionProtocol protocol in newProtocols) { context.ExecutionProtocols.Add(protocol); } context.SaveChanges(); } }