示例#1
0
        /// <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();
            }
        }