public Task <IEnumerable <Command> > GetAll() { return(_repo.GetAll()); }
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 }
public async Task <List <CommandDto> > GetAllCommands() { var commands = await _commandRepository.GetAll(); return(commands.ConvertAll(ConvertModelToDto)); }
public void InitTest() { Assert.That(CommandRepository.GetAll(), Is.Empty); }
public IEnumerable <Command> GetAllCommands() => _commandRepository.GetAll().ToList();