/// <summary>
        /// Costruisce una rappresentazione in formato stringa delle informazioni principali sul task specificato.
        /// </summary>
        /// <param name="tm">le informazioni relative al task</param>
        /// <returns>una rappresentazione in formato stringa delle informazioni principali sul task</returns>
        private string BuildTaskDescriptionString(TaskMetadata tm)
        {
            StringBuilder str = new StringBuilder();

            if (tm != null)
            {
                str.Append("Source: " + tm.PathToSourceFile);
                str.Append(Environment.NewLine);
                str.Append("Target: " + tm.PathToTargetFile);
                str.Append(Environment.NewLine);
                str.Append("Component: class = " + tm.TaskPerformerClassName + ", version = " + tm.TaskPerformerClassVersion);
                str.Append(Environment.NewLine);
                str.Append("Ready: " + tm.ReadyTime.ToString());
                str.Append(Environment.NewLine);
                str.Append("Starting: " + tm.StartingTime.ToString());
                str.Append(Environment.NewLine);
                str.Append("Completion: " + tm.CompletionTime.ToString());
                str.Append(Environment.NewLine);
                str.Append("State: " + tm.State.ToString());
                str.Append(Environment.NewLine);
                str.Append("Errors: " + tm.Errors.Count);
            }

            return(str.ToString());
        }
Пример #2
0
        /// <summary>
        /// Restituisce una copia di questo oggetto.
        /// </summary>
        /// <returns>una copia di questo oggetto</returns>
        public static TaskMetadata Copy(TaskMetadata tm)
        {
            TaskMetadata copy = new TaskMetadata(null, null, null, null)
            {
                TaskPerformerClassName    = string.Copy(tm.TaskPerformerClassName),
                TaskPerformerClassVersion = string.Copy(tm.TaskPerformerClassVersion),
                PathToSourceFile          = string.Copy(tm.PathToSourceFile),
                PathToTargetFile          = string.Copy(tm.PathToTargetFile),

                State = tm.State,

                ReadyTime      = tm.ReadyTime,
                StartingTime   = tm.StartingTime,
                CompletionTime = tm.CompletionTime,

                Errors = new List <TaskErrorInfo>(tm.Errors.Count)
            };

            foreach (TaskErrorInfo error in tm.Errors)
            {
                copy.Errors.Add(TaskErrorInfo.Copy(error));
            }

            return(copy);
        }
        /// <summary>
        /// Restituisce il tempo impiegato per elaborare il task descritto dai metadati specificati.
        /// </summary>
        /// <param name="tm">i metadati relativi al task</param>
        /// <returns>il tempo impiegato per elaborare il task</returns>
        /// <remarks>
        /// Se l'oggetto contenente i metadati è null oppure se in essi non sono stati impostati l'istante
        /// di completamento dell'elaborazione e/o l'istante di inizio dell'elaborazione, viene restituito
        /// il valore TimeSpan.Zero.
        /// </remarks>
        public TimeSpan GetProcessingTime(TaskMetadata tm)
        {
            if (tm != null && tm.CompletionTime.HasValue && tm.StartingTime.HasValue)
            {
                DateTime t1 = tm.StartingTime.Value;
                DateTime t2 = tm.CompletionTime.Value;

                if (t2 > t1)
                {
                    return t2.Subtract(t1);
                }
            }
            return TimeSpan.Zero;
        }
        /// <summary>
        /// Prova ad ottenere l'oggetto contenente i metadati del task associati all'identificativo specificato.
        /// Restituisce true se tale identificativo specificato esiste ed in tal caso assegna in output l'oggetto
        /// con i metadati richiesti. Altrimenti, se l'identificativo specificato non esiste, restituisce false e
        /// imposta l'output a null.
        /// </summary>
        /// <param name="id">l'identificativo associato al task richiesto</param>
        /// <param name="tm">l'oggetto contenente i metadati richiesti</param>
        /// <returns>true, se esiste l'oggetto con i metadati cercati, altrimenti false</returns>
        /// <remarks>
        /// I metadati del task specificato vengono copiati nell'oggetto restituito.
        /// </remarks>
        public bool TryGetUserTask(string id, out TaskMetadata tm)
        {
            lock (m_PendingTasksLocker)
            {
                TaskMetadata temp;
                if (m_PendingTasks.TryGetTask(id, out temp) && temp != null)
                {
                    tm = TaskMetadata.Copy(temp);
                    return(true);
                }
            }

            tm = null;
            return(false);
        }
        /// <summary>
        /// Schedula il task specificato per l'esecuzione e imposta in output l'identificativo assegnato,
        /// restituendo true se l'oggetto contenente i metadati specificati è diverso da null. Altrimenti,
        /// cioè se l'oggetto specificato è null, l'identificativo viene impostato a null e questo metodo
        /// restituisce false, non potendo schedulare un task null.
        /// </summary>
        /// <param name="tm">i metadati del task da schedulare per l'elaborazione</param>
        /// <param name="id">l'identificativo assegnato al task</param>
        /// <returns>true se il task specificato è stato schedulato, altrimenti false</returns>
        public bool InsertUserTask(TaskMetadata tm, out string id)
        {
            if (tm != null)
            {
                string newId;
                lock (m_PendingTasksLocker)
                {
                    m_PendingTasks.InsertTask(tm, out newId);
                }
                id = newId;

                Task.Factory.StartNew(() => ExecuteTask(newId),
                                      CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);

                return(true);
            }

            id = null;
            return(false);
        }
        /// <summary>
        /// Schedula il task specificato per l'esecuzione e imposta in output l'identificativo assegnato,
        /// restituendo true se l'oggetto contenente i metadati specificati è diverso da null. Altrimenti,
        /// cioè se l'oggetto specificato è null, l'identificativo viene impostato a null e questo metodo
        /// restituisce false, non potendo schedulare un task null.
        /// </summary>
        /// <param name="tm">i metadati del task da schedulare per l'elaborazione</param>
        /// <param name="id">l'identificativo assegnato al task</param>
        /// <returns>true se il task specificato è stato schedulato, altrimenti false</returns>
        public bool InsertUserTask(TaskMetadata tm, out string id)
        {
            if (tm != null)
            {
                string newId;
                lock (m_PendingTasksLocker)
                {
                    m_PendingTasks.InsertTask(tm, out newId);
                }
                id = newId;

                Task.Factory.StartNew(() => ExecuteTask(newId),
                    CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);

                return true;
            }

            id = null;
            return false;
        }
        /// <summary>
        /// Prova a mettere il task specificato in coda per l'elaborazione associandolo all'identificativo specificato
        /// e restituisce true se l'inserimento viene completate con successo. In caso contrario, restituisce false ed
        /// imposta l'errore esplicativo.
        /// </summary>
        /// <param name="tm">i metadati relativi al task di cui è stata richiesta l'elaborazione</param>
        /// <param name="taskRequestId">l'identificativo univoco della richiesta di elaborazione</param>
        /// <param name="error">l'eventuale errore impostato qualora si dovessero verificare dei problemi</param>
        /// <returns>true se non si verificano errori durante l'accodamento del task, altrimenti false</returns>
        /// <remarks>
        /// Se il task viene accodato con successo, l'oggetto dedicato all'eventuale errore è impostato al valore null,
        /// altrimenti al suo interno vengono impostati il codice d'errore e un identificativo univoco sul server,
        /// oltre ad effettuare il logging dell'errore.
        /// </remarks>
        public bool TryQueueTask(TaskMetadata tm, string taskRequestId, out ServiceFault error)
        {
            bool result;

            string taskProcId;
            if (m_TaskScheduler.InsertUserTask(tm, out taskProcId))
            {
                if (TryInsertIdPair(taskRequestId, taskProcId))
                {
                    WriteToLog("TryQueueTask: task scheduled with request id = {0}, processing id = {1}.",
                        taskRequestId, taskProcId);
                    error = null;
                    result = true;
                }
                else
                {
                    string errorDetails = "TryQueueTask: unable to insert task identifiers within table: " +
                        string.Format("request id = {0}, processing id = {1}.", taskRequestId, taskProcId);
                    HandleError(errorDetails, ServiceFaultCode.InternalError, out error);
                    result = false;
                }
            }
            else
            {
                HandleError("TryQueueTask: unable to queue a new task.", ServiceFaultCode.InternalError, out error);
                result = false;
            }

            return result;
        }
        /// <summary>
        /// Verifica che i metadati del task associato all'identificativo specificato siano esistenti ed eventualmente
        /// li copia in output e restituisce true. In caso contrario restituisce false ed imposta i metadati in output
        /// al valore null e un errore esplicativo.
        /// </summary>
        /// <param name="taskRequestId">l'identificativo univoco della richiesta di elaborazione</param>
        /// <param name="tm">la copia dei metadati relativi al task di cui è stata richiesta l'elaborazione</param>
        /// <param name="error">l'eventuale errore impostato qualora si dovessero verificare dei problemi</param>
        /// <returns>true se non si verificano errori durante il recupero dei metadati, altrimenti false</returns>
        /// <remarks>
        /// Se i metadati richiesti vengono trovati, l'oggetto dedicato all'eventuale errore è impostato al valore null,
        /// altrimenti al suo interno vengono impostati il codice d'errore e un identificativo univoco sul server, oltre
        /// ad effettuare il logging dell'errore.
        /// </remarks>
        public bool TryGetUserTask(string taskRequestId, out TaskMetadata tm, out ServiceFault error)
        {
            string taskProcId;
            if (!TryGetProcessingId(taskRequestId, out taskProcId))
            {
                string errorDetails = string.Format("TryGetUserTask: unable to find processing id for request id = {0}.", taskRequestId);
                HandleError(errorDetails, ServiceFaultCode.TaskResultsNotFound, out error);

                tm = null;
                return false;
            }

            if (!m_TaskScheduler.TryGetUserTask(taskProcId, out tm))
            {
                string errorDetails = "TryGetUserTask: unable to find task for " +
                    string.Format("request id = {0}, processing id = {1}.", taskRequestId, taskProcId);
                HandleError(errorDetails, ServiceFaultCode.TaskResultsNotFound, out error);

                tm = null;
                return false;
            }

            error = null;
            return true;
        }
        /// <summary>
        /// Costruisce una rappresentazione in formato stringa delle informazioni principali sul task specificato.
        /// </summary>
        /// <param name="tm">le informazioni relative al task</param>
        /// <returns>una rappresentazione in formato stringa delle informazioni principali sul task</returns>
        private string BuildTaskDescriptionString(TaskMetadata tm)
        {
            StringBuilder str = new StringBuilder();

            if (tm != null)
            {
                str.Append("Source: " + tm.PathToSourceFile);
                str.Append(Environment.NewLine);
                str.Append("Target: " + tm.PathToTargetFile);
                str.Append(Environment.NewLine);
                str.Append("Component: class = " + tm.TaskPerformerClassName + ", version = " + tm.TaskPerformerClassVersion);
                str.Append(Environment.NewLine);
                str.Append("Ready: " + tm.ReadyTime.ToString());
                str.Append(Environment.NewLine);
                str.Append("Starting: " + tm.StartingTime.ToString());
                str.Append(Environment.NewLine);
                str.Append("Completion: " + tm.CompletionTime.ToString());
                str.Append(Environment.NewLine);
                str.Append("State: " + tm.State.ToString());
                str.Append(Environment.NewLine);
                str.Append("Errors: " + tm.Errors.Count);
            }

            return str.ToString();
        }
        /// <summary>
        /// Prova ad ottenere l'oggetto contenente i metadati del task associati all'identificativo specificato.
        /// Restituisce true se tale identificativo specificato esiste ed in tal caso assegna in output l'oggetto
        /// con i metadati richiesti. Altrimenti, se l'identificativo specificato non esiste, restituisce false e
        /// imposta l'output a null.
        /// </summary>
        /// <param name="id">l'identificativo associato al task richiesto</param>
        /// <param name="tm">l'oggetto contenente i metadati richiesti</param>
        /// <returns>true, se esiste l'oggetto con i metadati cercati, altrimenti false</returns>
        /// <remarks>
        /// I metadati del task specificato vengono copiati nell'oggetto restituito.
        /// </remarks>
        public bool TryGetUserTask(string id, out TaskMetadata tm)
        {
            lock (m_PendingTasksLocker)
            {
                TaskMetadata temp;
                if (m_PendingTasks.TryGetTask(id, out temp) && temp != null)
                {
                    tm = TaskMetadata.Copy(temp);
                    return true;
                }
            }

            tm = null;
            return false;
        }
        /// <summary>
        /// Restituisce una copia di questo oggetto.
        /// </summary>
        /// <returns>una copia di questo oggetto</returns>
        public static TaskMetadata Copy(TaskMetadata tm)
        {
            TaskMetadata copy = new TaskMetadata(null, null, null, null)
            {
                TaskPerformerClassName = string.Copy(tm.TaskPerformerClassName),
                TaskPerformerClassVersion = string.Copy(tm.TaskPerformerClassVersion),
                PathToSourceFile = string.Copy(tm.PathToSourceFile),
                PathToTargetFile = string.Copy(tm.PathToTargetFile),

                State = tm.State,

                ReadyTime = tm.ReadyTime,
                StartingTime = tm.StartingTime,
                CompletionTime = tm.CompletionTime,

                Errors = new List<TaskErrorInfo>(tm.Errors.Count)
            };

            foreach (TaskErrorInfo error in tm.Errors) { copy.Errors.Add(TaskErrorInfo.Copy(error)); }

            return copy;
        }
        /// <summary>
        /// Permette il trasferimento dei dati relativi al task da elaborare ed imposta una stringa contenente
        /// l'identificativo univoco associato alla richiesta di elaborazione, necessario per ottenere in seguito
        /// i risultati dell'elaborazione.
        /// </summary>
        /// <param name="data">i dati relativi al task di cui si richiede l'elaborazione</param>
        /// <param name="id">l'identificativo associato alla richiesta di elaborazione</param>
        public void SubmitData(TaskData data, out string id)
        {
            m_Container.WriteToLog("SubmitData: receiving data, name = {0}.", data.Name);

            ServiceFault fault = null;

            // Genera un ID univoco da associare alla richiesta.
            string taskRequestId;
            if (!m_Container.TryGetRandomId(out taskRequestId, out fault))
            {
                throw new FaultException<ServiceFault>(fault);
            }

            m_Container.WriteToLog("SubmitData: task request id = {0}.", taskRequestId);

            string tdFilePath = m_Container.GetTaskDataFilePath();   // task data file path

            // Salva i dati ricevuti sul task da elaborare.
            if (!m_Container.TrySaveDataToFile(data.Contents, tdFilePath, out fault))
            {
                throw new FaultException<ServiceFault>(fault);
            }

            m_Container.WriteToLog("SubmitData: task request id = {0}, file saved to {1}.", taskRequestId, tdFilePath);

            // Verifica che la risorsa sia disponibile.
            string className, classVersion;
            if (!m_Container.TrySearchResource(tdFilePath, out className, out classVersion, out fault))
            {
                throw new FaultException<ServiceFault>(fault);
            }

            string trFilePath = m_Container.GetTaskResultsFilePath(); // task results file path

            // Prepara il task da elaborare.
            TaskMetadata tm = new TaskMetadata(className, classVersion, tdFilePath, trFilePath);
            tm.UpdateOnReady(DateTime.Now);

            // Inserisce il task in coda allo scheduler.
            if (!m_Container.TryQueueTask(tm, taskRequestId, out fault))
            {
                throw new FaultException<ServiceFault>(fault);
            }

            m_Container.WriteToLog("SubmitData: task scheduled with request id = {0}, target file = {1}.",
                taskRequestId, trFilePath);

            id = taskRequestId;
        }