예제 #1
0
        private void DeleteFilesInEssence(Essence essence)
        {
            if (!Directory.Exists(essence.Path))
            {
                Logging.LogWarning(essence.Path + " already deleted.");
                return;
            }
            var sb = new StringBuilder("Deleting Tempory files and directory:\n");

            foreach (var file in essence.Files)
            {
                var absFineName = Path.Combine(essence.Path, file.Value);
                if (File.Exists(absFineName))
                {
                    File.Delete(absFineName);
                    sb.AppendLine(absFineName);
                }
            }

            if (!Directory.EnumerateFiles(essence.Path).Any()) //temp dir is empty, safe to delete
            {
                Directory.Delete(essence.Path);
                sb.AppendLine(essence.Path);
            }
            Logging.LogInfo(sb.ToString());
        }
예제 #2
0
        public JobStatus Order(Order order)
        {
            try
            {
                order.Validate(_mediaInfoFacade, _timeProvider);
            }
            catch
            {
                _logging.LogWarning("Failed to validate order", order);
                throw;
            }
            var job = Mapper.Map <Job>(order);

            if (order.Format == StateFormat.custom)
            {
                _logging.LogWarning($"Custom format received : {order.CustomFormat}", job.Urn);
            }
            _jobRepository.Add(job);
            _logging.LogInfo($"Received valid order.", job);
            return(Mapper.Map <JobStatus>(job));
        }
예제 #3
0
 public void warningMessage(string message)
 {
     _logService.LogWarning(message);
 }
예제 #4
0
        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
        }