public DashboardInfo GetDashboardInfo(DateTime?recentlyFilter = null) { if (!recentlyFilter.HasValue) { recentlyFilter = _timeProvider.GetUtcNow().AddHours(-1); } var res = new DashboardInfo { WaitingJobs = _jobRepository.WaitingJobs().Select(Mapper.Map <DashboardJob>), ActiveJobs = _jobRepository.ActiveJobs().Select(Mapper.Map <DashboardJob>), RecentlyDoneJobs = _jobRepository.DoneJobs(recentlyFilter).Select(Mapper.Map <DashboardJob>), RecentlyFailedJobs = _jobRepository.FailedJobs(recentlyFilter).Select(Mapper.Map <DashboardJob>), RecentlyCanceledJobs = _jobRepository.CanceledJobs(recentlyFilter).Select(Mapper.Map <DashboardJob>), Plugins = _plugins.Select(Mapper.Map <DashbaordPlugin>) }; return(res); }
public void InitTest() { Assert.That(JobRepository.ActiveJobs(), Is.Empty); Assert.That(JobRepository.DoneJobs(), Is.Empty); Assert.That(JobRepository.WaitingJobs(), Is.Empty); }
public void Pulse() { lock (_jobRepository) { #region semaphore string currentOwner; var firstCallAfterSemaphore = _firstPulse || !_wasMaster; if (!_semaphoreRepository.Get(nameof(Executor), Utilities.GetCallerId(), out currentOwner)) { if (_firstPulse) { _logging.LogInfo($"Did not get semaphore, current owner : {currentOwner}. Will stand by as slave."); _firstPulse = false; } else if (_wasMaster) { _logging.LogWarning($"Lost semaphore to : {currentOwner}. Will stand by as slave."); _wasMaster = false; } return; } if (_firstPulse) { _logging.LogInfo($"Got semaphore, as : {currentOwner}. Will work as master."); _firstPulse = false; } else if (!_wasMaster) { _logging.LogInfo($"Slave woken, {currentOwner} is now owner. Will work as master."); foreach (var plugin in _plugins) { plugin.Reset(); } } _wasMaster = true; #endregion #region command foreach (var command in _commandRepository.GetAll()) { // ReSharper disable once SwitchStatementMissingSomeCases switch (command.Type) { case CommandType.Cancel: CancelJob(command.Urn, command.Username); break; default: _logging.LogWarning($"Command state {command.Type} is not implemented.", command.Urn); break; } _commandRepository.Remove(command); } #endregion #region planner // TODO: modify existing plans ? :hamburger: :+1: if (!firstCallAfterSemaphore) // skip first pulse to reassign in-progress tasks to plugins. { _planner.Calculate(); } #endregion #region jobs, task and plugins foreach (var job in _jobRepository.ActiveJobs().ToList()) { //TODO: Add support for cancel var plan = job.Plan; startOfJobLoop: var executionTask = plan.GetCurrentTask(); var targetPlugin = _plugins.First(p => p.Urn == executionTask.PluginUrn); switch (executionTask.State) { case ExecutionState.Queued: if (targetPlugin.Busy) { // TODO: log planning warning break; } _logging.LogDebug($"Task {executionTask.Urn} assigned to {targetPlugin.Urn}.", job.Urn); targetPlugin.Assign(executionTask); goto case ExecutionState.Running; case ExecutionState.Running: targetPlugin.Pulse(executionTask); if (executionTask.State == ExecutionState.Done) { goto case ExecutionState.Done; } if (executionTask.State == ExecutionState.Failed) { goto case ExecutionState.Failed; } plan.Tasks[plan.ActiveTaskIndex.Value] = executionTask; break; case ExecutionState.Done: _logging.LogDebug($"Task {executionTask.Urn} done, released from {targetPlugin.Urn}.", job.Urn); targetPlugin.Release(executionTask); plan.Tasks[plan.ActiveTaskIndex.Value] = executionTask; plan.MoveToNextTask(); if (plan.ActiveTaskIndex.HasValue) // has more tasks { _jobRepository.Update(job); // save and... goto startOfJobLoop; //start next task at once } break; case ExecutionState.Failed: if (targetPlugin.CanRetry && executionTask.NumberOfRetries < targetPlugin.RetryMax) { targetPlugin.Retry(executionTask); } break; default: throw new ArgumentOutOfRangeException(); } if (plan.GetState() == ExecutionState.Done) { job.Destination = plan.GetCurrentEssence(); job.EndTime = _timeProvider.GetUtcNow(); _logging.LogInfo("Job done", job.Urn); } if (plan.GetState() == ExecutionState.Failed) { _logging.LogWarning("Job failed", job.Urn); } if ((plan.GetState() == ExecutionState.Failed || plan.GetState() == ExecutionState.Done) && !string.IsNullOrEmpty(job.CallbackUrl)) { MakeCallback(job); } _jobRepository.Update(job); } } #endregion }