public IProcessedEntity GetNext(List <ProcessedEntityType> types) { if (types == null) { throw new ArgumentNullException("types"); } // Filter free projects IOrderedEnumerable <IProcessedEntity> entities = _taskKeeper .GetTasks() .Where(p => types.Contains(p.EntityType) && _validStates.Contains(p.State)) .OrderByDescending(p => p.Created); IProcessedEntity entity; // It should be atomic to prevent reservation of the same task lock (_lockObject) { entity = SelectNextTask(entities.ToList()); if (entity != null) { try { entity.SetState(new ReservedState()); } catch (Exception e) { Trace.TraceError("Failed to change task state: {0}", e); } } } return(entity); }
/// <summary> /// Checks current tasks. /// </summary> public void CheckTasks() { // Check hanged tasks List <IProcessedEntity> hangedTasks = _taskKeeper .GetTasks() .Where(p => !_completedStates.Contains(p.State) && _processingStates.Contains(p.State) && DateTime.UtcNow.Subtract(p.Modified) > TaskProcessingTimeout) .ToList(); foreach (IProcessedEntity entity in hangedTasks) { Trace.TraceInformation("Task {0} hanged up while video {1} processing. Current state: {2}, Attempts: {3}, DestinationFileId: {4}.", entity.TaskId, entity.SourceFileId, entity.State, entity.AttemptsCount, entity.DestinationFileId ?? "null"); entity.AttemptsCount++; try { if (entity.State == TaskState.Reserved) { // Nobody wants to process this entity entity.SetState(new WaitingState()); } else { // Somebody hanged up while entity processing entity.SetState(new FailedState()); } } catch (Exception e) { Trace.TraceError("Failed to change task state: {0}", e); } } // Check failed tasks List <IProcessedEntity> corruptedTasks = _taskKeeper .GetTasks() .Where(p => (p.AttemptsCount >= MaxAttemptsCount && !_completedStates.Contains(p.State))).ToList(); foreach (IProcessedEntity corruptedTask in corruptedTasks) { try { corruptedTask.SetState(new CorruptedState()); } catch (Exception e) { Trace.TraceError("Failed to change task state: {0}", e); } } }