/// <summary> /// Schedules work for the executors loaded, if possible /// </summary> public void ScheduleWork() { List <IExecutor> interested = new List <IExecutor>(); List <ExecutionProtocol> protocols = NewProtocols(); List <ExecutorWorkload> availableWork = new List <ExecutorWorkload>(); using (ExecutionContext context = new ExecutionContext()) { ExecutorState[] execuorStates = (from state in context.ExecutorStates select state).ToArray(); foreach (IExecutor exec in executors.Values) { ExecutorState state = execuorStates.Where(st => st.ExecutorId == exec.ExecutorId).FirstOrDefault(); if (state != null) { if (state.HasWork == true) { continue; } exec.SetState(state); } ExecutorWorkload newWorkload; List <ExecutionProtocol> relevantProtocols = (from p in protocols where exec.ExecutorsFollowed.Contains(p.ExecutorId) select p).ToList(); ExecutorState newState = exec.ViewNewProtocols(relevantProtocols, out newWorkload); state = newState; if (newState.HasWork) { availableWork.Add(newWorkload); } } OptimizeTimeForWork(availableWork, context); context.SaveChanges(); } }
public void SetState(ExecutorState configuration) { if (configuration.ExecutorId != ExecutorId) { throw new Exception(String.Format ("Sate of a different executor ({0}) used to set state of {1} (ID = {2})", configuration.ExecutorId, ExecutorName, ExecutorId)); } _state = configuration; }
public object Clone() { ExecutorState clone = (ExecutorState)this.MemberwiseClone(); if (clone.Settings != null) { // recursive copy of XDocument clone.Settings = new XDocument(Settings); } return(clone); }
public ExecutorBase() { _state = new ExecutorState { Broken = false, ExecutorId = ExecutorId, HasWork = false, IsActive = true, LastExecuted = DateTime.MinValue, TimeCovered = new TimeSpan(0), TotalExecutionTime = 0, TotalExecutions = 0, TotalOutputProduced = 0, Settings = new XDocument(new XDeclaration("1.0", "utf-8", "yes"), new XElement("ExecutorState")) }; Connstring = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString; }
/// <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(); } }