//-------------------------------------------------------------------------------------------------//
        public override ExperimentInfo RunExperiment(ExperimentInfo experimentInfo)
        {
            const string STRLOG_MethodName = "RunExperiment";

            Logfile.WriteCalled(STRLOG_ClassName, STRLOG_MethodName);

            // Create a result report ready to fill in
            experimentInfo.resultReport = new ResultReport();

            try
            {
                //
                // Parse the XML specification string to generate a validation report (should be accepted!)
                //
                Specification specification = new Specification(this.configuration, this.equipmentServiceProxy);
                ValidationReport validationReport = specification.Parse(experimentInfo.xmlSpecification);
                if (validationReport.accepted == false)
                {
                    throw new ArgumentException(validationReport.errorMessage);
                }
                experimentInfo.setupId = specification.SetupId;

                //
                // Create an instance of the driver for the specified setup and then
                // execute the experiment and return the result information
                //
                ResultInfo resultInfo = null;

                //
                // All setups use the equipment driver
                //
                DriverEquipment driver = new DriverEquipment(this.equipmentServiceProxy, this.configuration, this.labExperimentInfo.cancelExperiment);
                resultInfo = (ResultInfo)driver.Execute(specification);

                //
                // Create an instance of LabExperimentResult to convert the experiment results to an XML string
                //
                ExperimentResult experimentResult = new ExperimentResult(
                    experimentInfo.experimentId, experimentInfo.sbName, DateTime.Now,
                    this.unitId, (Configuration)this.labConfiguration, specification, resultInfo);

                //
                // Fill in the result report
                //
                experimentInfo.resultReport.experimentResults = experimentResult.ToString();
                experimentInfo.resultReport.statusCode = (int)resultInfo.statusCode;
                experimentInfo.resultReport.errorMessage = resultInfo.errorMessage;
            }
            catch (Exception ex)
            {
                experimentInfo.resultReport.statusCode = (int)StatusCodes.Failed;
                experimentInfo.resultReport.errorMessage = ex.Message;
                Logfile.WriteError(ex.Message);
            }

            Logfile.WriteCompleted(STRLOG_ClassName, STRLOG_MethodName);

            return experimentInfo;
        }
        //-------------------------------------------------------------------------------------------------//
        private bool ConcludeExperiment(ExperimentInfo experimentInfo)
        {
            const string STRLOG_MethodName = "ConcludeExperiment";

            Logfile.WriteCalled(STRLOG_ClassName, STRLOG_MethodName);

            bool success = false;

            try
            {
                //
                // Update experiment status both here and the queue table
                //
                experimentInfo.status = (StatusCodes)experimentInfo.resultReport.statusCode;
                if (this.experimentQueue.UpdateStatus(experimentInfo.experimentId, experimentInfo.sbName, experimentInfo.status) == false)
                {
                    throw new ArgumentException(STRERR_FailedToUpdateQueueStatus);
                }

                //
                // Save the experiment results
                //
                if (this.experimentResults.Save(experimentInfo) == false)
                {
                    throw new ArgumentException(STRERR_FailedToSaveExperimentResults);
                }

                //
                // Check experiment completion status for updating the statistics
                //
                DateTime now = DateTime.Now;
                if (experimentInfo.status == StatusCodes.Cancelled)
                {
                    // Update statistics for cancelled experiment
                    if (this.experimentStatistics.Cancelled(experimentInfo.experimentId, experimentInfo.sbName, now) == false)
                    {
                        throw new ArgumentException(STRERR_FailedToUpdateStatisticsCancelled);
                    }
                }
                else
                {
                    // Update statistics for completed experiment
                    if (this.experimentStatistics.Completed(experimentInfo.experimentId, experimentInfo.sbName, now) == false)
                    {
                        throw new ArgumentException(STRERR_FailedToUpdateStatisticsCompleted);
                    }

                    //
                    // Determine actual execution time of the experiment
                    //
                    TimeSpan timeSpan = now - this.labExperimentInfo.startDateTime;
                    int executionTime = (int)timeSpan.TotalSeconds;
                    Logfile.Write(STRLOG_ActualExecutionTime + executionTime.ToString() + STRLOG_seconds);
                }

                success = true;
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
            }

            //
            // Experiment is finished
            //
            lock (this.statusLock)
            {
                if (this.labExperimentInfo != null)
                {
                    this.labExperimentInfo.cancelExperiment = null;
                    this.labExperimentInfo = null;
                }
            }

            string logMessage = STRLOG_success + success.ToString();

            Logfile.WriteCompleted(STRLOG_ClassName, STRLOG_MethodName, logMessage);

            return success;
        }
 public LabExperimentInfo(ExperimentInfo experimentInfo, DateTime startDateTime)
 {
     this.experimentInfo = experimentInfo;
     this.cancelExperiment = new CancelExperiment();
     this.startDateTime = startDateTime;
     this.minTimeToLive = 0.0;
     this.errorMessage = null;
 }
        //-------------------------------------------------------------------------------------------------//
        private bool PrepareExperiment(ExperimentInfo experimentInfo)
        {
            const string STRLOG_MethodName = "PrepareExperiment";

            Logfile.WriteCalled(STRLOG_ClassName, STRLOG_MethodName);

            bool success = false;

            //
            // Check if the experiment has been cancelled
            //
            if (experimentInfo.cancelled == true)
            {
                //
                // Experiment was cancelled while waiting on the queue
                //
                experimentInfo.resultReport = new ResultReport((int)StatusCodes.Cancelled, STRLOG_QueuedExperimentCancelled);

                Logfile.Write(STRLOG_QueuedExperimentCancelled);
            }
            else
            {
                //
                // Update the statistics for starting the experiment
                //
                DateTime now = DateTime.Now;
                success = this.experimentStatistics.Started(experimentInfo.experimentId, experimentInfo.sbName, this.unitId, now);

                //
                // Create an instance of LabExperimentInfo to execute the experiment
                //
                lock (this.statusLock)
                {
                    experimentInfo.unitId = this.unitId;
                    experimentInfo.status = StatusCodes.Running;
                    this.labExperimentInfo = new LabExperimentInfo(experimentInfo, now);
                }
            }

            string logMessage = STRLOG_success + success.ToString();

            Logfile.WriteCompleted(STRLOG_ClassName, STRLOG_MethodName, logMessage);

            return success;
        }
        //-------------------------------------------------------------------------------------------------//
        private bool NotifyServiceBroker(ExperimentInfo experimentInfo)
        {
            const string STRLOG_MethodName = "NotifyServiceBroker";

            Logfile.WriteCalled(STRLOG_ClassName, STRLOG_MethodName);

            bool success = false;

            try
            {
                //
                // Notify the ServiceBroker so that the results can be retrieved
                //
                LabServerToSbAPI labServerToSbAPI = new LabServerToSbAPI(this.allowedServiceBrokers);
                if ((success = labServerToSbAPI.Notify(experimentInfo.experimentId, experimentInfo.sbName)) == true)
                {
                    success = this.experimentResults.UpdateNotified(experimentInfo.experimentId, experimentInfo.sbName);
                }
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
            }

            string logMessage = STRLOG_success + success.ToString();

            Logfile.WriteCompleted(STRLOG_ClassName, STRLOG_MethodName, logMessage);

            return success;
        }
        //-------------------------------------------------------------------------------------------------//
        private bool NotifyEmail(ExperimentInfo experimentInfo)
        {
            const string STRLOG_MethodName = "NotifyEmail";

            Logfile.WriteCalled(STRLOG_ClassName, STRLOG_MethodName);

            bool success = false;

            try
            {
                /*
                 * Send an email to the iLab Administrator stating that an experiment has completed.
                 * If the experiment failed, send an email to the email address for reporting failed experiments.
                 */
                MailMessage mailMessage = null;
                string errorMessage = String.Empty;
                StatusCodes statusCode = (StatusCodes)experimentInfo.resultReport.statusCode;

                if (statusCode == StatusCodes.Failed)
                {
                    /*
                     * Email goes to all those listed for when the experiment fails
                     */
                    if (this.emailAddressesExperimentFailed != null && this.emailAddressesExperimentFailed.Length > 0)
                    {
                        if (mailMessage == null)
                        {
                            mailMessage = new MailMessage();
                        }
                        for (int i = 0; i < this.emailAddressesExperimentFailed.Length; i++)
                        {
                            mailMessage.To.Add(new MailAddress(this.emailAddressesExperimentFailed[i]));
                        }
                        errorMessage = String.Format(STRLOG_MailMessageError_arg, experimentInfo.resultReport.errorMessage);
                    }
                }
                else
                {
                    /*
                     * Email goes to all those listed for when the experiment completes successfully or is cancelled
                     */
                    if (this.emailAddressesExperimentCompleted != null && this.emailAddressesExperimentCompleted.Length > 0)
                    {
                        if (mailMessage == null)
                        {
                            mailMessage = new MailMessage();
                        }
                        for (int i = 0; i < this.emailAddressesExperimentCompleted.Length; i++)
                        {
                            mailMessage.To.Add(new MailAddress(this.emailAddressesExperimentCompleted[i]));
                        }
                    }
                }

                /*
                 * Check if recipient email addresses have been specified
                 */
                if (mailMessage != null)
                {
                    mailMessage.From = new MailAddress(this.emailAddressLabServer);
                    mailMessage.Subject = String.Format(STRLOG_MailMessageSubject_arg2, this.labConfiguration.Title, statusCode);
                    mailMessage.Body = String.Format(STRLOG_MailMessageBody_arg7,
                        experimentInfo.sbName, experimentInfo.userGroup, experimentInfo.experimentId, this.unitId, experimentInfo.setupId, statusCode, errorMessage);

                    Logfile.Write(
                        String.Format(STRLOG_SendingEmail_arg3, mailMessage.To.ToString(), mailMessage.From.Address, mailMessage.Subject));

                    /*
                     * Send the email
                     */
                    SmtpClient smtpClient = new SmtpClient(Consts.STR_LocalhostIP);
                    smtpClient.Send(mailMessage);
                }

                success = true;
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
            }

            string logMessage = STRLOG_success + success.ToString();

            Logfile.WriteCompleted(STRLOG_ClassName, STRLOG_MethodName, logMessage);

            return success;
        }
        //---------------------------------------------------------------------------------------//
        public bool Save(ExperimentInfo experimentInfo)
        {
            const string STRLOG_MethodName = "Save";

            string logMessage = null;

            if (experimentInfo != null)
            {
                logMessage = STRLOG_experimentId + experimentInfo.experimentId.ToString() +
                    Logfile.STRLOG_Spacer + STRLOG_sbName + Logfile.STRLOG_Quote + experimentInfo.sbName + Logfile.STRLOG_Quote;
            }

            Logfile.WriteCalled(STRLOG_ClassName, STRLOG_MethodName, logMessage);

            //
            // Catch all exceptions thrown and return false if an error occurred.
            //
            bool success = false;

            lock (this.resultsLock)
            {
                try
                {
                    //
                    // Check that the experiment info exists
                    //
                    if (experimentInfo == null)
                    {
                        throw new ArgumentNullException(STRERR_ExperimentInfoIsNull);
                    }

                    //
                    // Check for null strings and change to empty strings if necessary
                    //
                    string errorMessage = (experimentInfo.resultReport.errorMessage == null) ? string.Empty : experimentInfo.resultReport.errorMessage;
                    string xmlBlobExtension = (experimentInfo.resultReport.xmlBlobExtension == null) ? string.Empty : experimentInfo.resultReport.xmlBlobExtension;
                    string xmlResultExtension = (experimentInfo.resultReport.xmlResultExtension == null) ? string.Empty : experimentInfo.resultReport.xmlResultExtension;
                    string experimentResults = (experimentInfo.resultReport.experimentResults == null) ? string.Empty : experimentInfo.resultReport.experimentResults;
                    string userGroup = (experimentInfo.userGroup == null) ? string.Empty : experimentInfo.userGroup;

                    //
                    // Convert warning messages to XML format
                    //
                    string xmlWarningMessages = string.Empty;
                    if (experimentInfo.resultReport.warningMessages != null)
                    {
                        XmlDocument xmlDocument = XmlUtilities.GetXmlDocument(STRXMLDOC_WarningMessagesTemplate);
                        XmlNode xmlRootNode = XmlUtilities.GetXmlRootNode(xmlDocument, STRXML_warningMessages);
                        XmlUtilities.SetXmlValues(xmlRootNode, STRXML_warningMessage, experimentInfo.resultReport.warningMessages, true);
                        xmlWarningMessages = xmlDocument.OuterXml;
                    }

                    SqlCommand sqlCommand = new SqlCommand(STRSQLCMD_StoreResults, this.sqlConnection);
                    sqlCommand.CommandType = CommandType.StoredProcedure;

                    sqlCommand.Parameters.Add(new SqlParameter(STRSQLPRM_ExperimentId, experimentInfo.experimentId));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQLPRM_SbName, experimentInfo.sbName));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQLPRM_UserGroup, userGroup));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQLPRM_PriorityHint, experimentInfo.priorityHint));
                    StatusCodes status = (StatusCodes)experimentInfo.resultReport.statusCode;
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQLPRM_Status, status.ToString()));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQLPRM_XmlExperimentResult, experimentResults));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQLPRM_XmlResultExtension, xmlResultExtension));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQLPRM_XmlBlobExtension, xmlBlobExtension));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQLPRM_WarningMessages, xmlWarningMessages));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQLPRM_ErrorMessage, errorMessage));

                    try
                    {
                        this.sqlConnection.Open();

                        if (sqlCommand.ExecuteNonQuery() == 0)
                        {
                            throw new Exception(STRERR_FailedToSaveResults);
                        }
                    }
                    catch (SqlException ex)
                    {
                        throw new Exception(STRERR_SqlException + ex.Message);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(STRERR_Exception + ex.Message);
                    }
                    finally
                    {
                        this.sqlConnection.Close();
                    }

                    // Information saved successfully
                    success = true;
                }
                catch (Exception ex)
                {
                    Logfile.WriteError(ex.Message);
                }
            }

            logMessage = STRLOG_success + success.ToString();

            Logfile.WriteCompleted(STRLOG_ClassName, STRLOG_MethodName, logMessage);

            return success;
        }
        //---------------------------------------------------------------------------------------//
        private string ConvertToXml(ExperimentInfo[] experimentInfoArray)
        {
            const string STRLOG_MethodName = "ConvertToXml";

            Logfile.WriteCalled(STRLOG_ClassName, STRLOG_MethodName);

            //
            // Catch all exceptions thrown and return an empty string if an error occurred
            //
            XmlDocument xmlDocument = null;
            string xmlExperimentQueue = string.Empty;
            try
            {
                //
                // Check that the experiment info array exists
                //
                if (experimentInfoArray == null)
                {
                    throw new ArgumentNullException(STRERR_ExperimentInfoArrayIsNull);
                }

                //
                // Take the experiment info  and put into the XML document
                //
                for (int i = 0; i < experimentInfoArray.GetLength(0); i++)
                {
                    ExperimentInfo experimentInfo = experimentInfoArray[i];

                    // Load experiment results XML template string
                    XmlDocument xmlTemplateDocument = XmlUtilities.GetXmlDocument(STRXMLDOC_XmlTemplate);

                    //
                    // Fill in the XML template with values from the experiment information
                    //
                    XmlNode xmlRootNode = XmlUtilities.GetXmlRootNode(xmlTemplateDocument, STRXML_experimentQueue);
                    XmlNode xmlNode = XmlUtilities.GetXmlNode(xmlRootNode, STRXML_experiment);
                    XmlUtilities.SetXmlValue(xmlNode, STRXML_experimentId, experimentInfo.experimentId);
                    XmlUtilities.SetXmlValue(xmlNode, STRXML_sbName, experimentInfo.sbName, false);
                    XmlUtilities.SetXmlValue(xmlNode, STRXML_userGroup, experimentInfo.userGroup, false);
                    XmlUtilities.SetXmlValue(xmlNode, STRXML_priorityHint, experimentInfo.priorityHint);
                    XmlUtilities.SetXmlValue(xmlNode, STRXML_specification, experimentInfo.xmlSpecification, false);
                    XmlUtilities.SetXmlValue(xmlNode, STRXML_estExecutionTime, experimentInfo.estExecutionTime);
                    XmlUtilities.SetXmlValue(xmlNode, STRXML_cancelled, experimentInfo.cancelled);

                    if (xmlDocument == null)
                    {
                        xmlDocument = xmlTemplateDocument;
                    }
                    else
                    {
                        //
                        // Create an XML fragment from the XML template and append to the document
                        //
                        XmlDocumentFragment xmlFragment = xmlDocument.CreateDocumentFragment();
                        xmlFragment.InnerXml = xmlNode.OuterXml;
                        xmlDocument.DocumentElement.AppendChild(xmlFragment);
                    }
                }

                //
                // Check if there were any experiments queued
                //
                if (xmlDocument == null)
                {
                    xmlDocument = XmlUtilities.GetXmlDocument(STRXMLDOC_XmlTemplate);
                    XmlNode xmlRootNode = XmlUtilities.GetXmlRootNode(xmlDocument, STRXML_experimentQueue);
                    XmlNode xmlNode = XmlUtilities.GetXmlNode(xmlRootNode, STRXML_experiment);
                    xmlRootNode.RemoveChild(xmlNode);
                }

                //
                // Convert the XML document to a string
                //
                StringWriter sw = new StringWriter();
                XmlTextWriter xtw = new XmlTextWriter(sw);
                xtw.Formatting = Formatting.Indented;
                xmlDocument.WriteTo(xtw);
                xtw.Flush();
                xmlExperimentQueue = sw.ToString();
            }
            catch (Exception ex)
            {
                Logfile.WriteError(ex.Message);
            }

            Logfile.WriteCompleted(STRLOG_ClassName, STRLOG_MethodName);

            return xmlExperimentQueue;
        }
        //---------------------------------------------------------------------------------------//
        public ExperimentInfo[] RetrieveAllWithStatus(StatusCodes status)
        {
            const string STRLOG_MethodName = "RetrieveAllWithStatus";

            Logfile.WriteCalled(STRLOG_ClassName, STRLOG_MethodName);

            List<ExperimentInfo> experimentInfoList = new List<ExperimentInfo>();

            lock (this.queueLock)
            {
                try
                {
                    SqlCommand sqlCommand = new SqlCommand(STRSQLCMD_RetrieveQueueAllWithStatus, this.sqlConnection);
                    sqlCommand.CommandType = CommandType.StoredProcedure;

                    sqlCommand.Parameters.Add(new SqlParameter(STRSQLPRM_Status, status.ToString()));

                    try
                    {
                        this.sqlConnection.Open();

                        SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
                        while (sqlDataReader.Read() == true)
                        {
                            ExperimentInfo experimentInfo = new ExperimentInfo(0, null);

                            //
                            // Get the experiment information from waiting experiment
                            //
                            object sdrObject = null;
                            if ((sdrObject = sqlDataReader[STRSQL_ExperimentId]) != System.DBNull.Value)
                                experimentInfo.experimentId = (int)sdrObject;
                            if ((sdrObject = sqlDataReader[STRSQL_SbName]) != System.DBNull.Value)
                                experimentInfo.sbName = (string)sdrObject;
                            if ((sdrObject = sqlDataReader[STRSQL_UserGroup]) != System.DBNull.Value)
                                experimentInfo.userGroup = (string)sdrObject;
                            if ((sdrObject = sqlDataReader[STRSQL_PriorityHint]) != System.DBNull.Value)
                                experimentInfo.priorityHint = (int)sdrObject;
                            if ((sdrObject = sqlDataReader[STRSQL_XmlSpecification]) != System.DBNull.Value)
                                experimentInfo.xmlSpecification = (string)sdrObject;
                            if ((sdrObject = sqlDataReader[STRSQL_EstimatedExecTime]) != System.DBNull.Value)
                                experimentInfo.estExecutionTime = (int)sdrObject;
                            if ((sdrObject = sqlDataReader[STRSQL_Cancelled]) != System.DBNull.Value)
                                experimentInfo.cancelled = (bool)sdrObject;

                            //
                            // Add the experiment info to the list
                            //
                            experimentInfoList.Add(experimentInfo);
                        }
                        sqlDataReader.Close();
                    }
                    catch (SqlException ex)
                    {
                        throw new Exception(STRERR_SqlException + ex.Message);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(STRERR_Exception + ex.Message);
                    }
                    finally
                    {
                        this.sqlConnection.Close();
                    }
                }
                catch (Exception ex)
                {
                    Logfile.WriteError(ex.Message);
                }
            }

            string logMessage = STRLOG_count + experimentInfoList.Count.ToString();

            Logfile.WriteCompleted(STRLOG_ClassName, STRLOG_MethodName, logMessage);

            return experimentInfoList.ToArray();
        }
        //---------------------------------------------------------------------------------------//
        /// <summary>
        /// Add an experiment to the end of the queue. Return queue information about the experiment.
        /// </summary>
        /// <param name="experimentInfo"></param>
        /// <returns>Queue information about the experiment.</returns>
        public QueuedExperimentInfo Enqueue(ExperimentInfo experimentInfo)
        {
            const string STRLOG_MethodName = "Enqueue";

            string logMessage = null;
            if (experimentInfo != null)
            {
                logMessage = STRLOG_experimentId + experimentInfo.experimentId.ToString() +
                    Logfile.STRLOG_Spacer + STRLOG_sbName + Logfile.STRLOG_Quote + experimentInfo.sbName + Logfile.STRLOG_Quote;
            }

            Logfile.WriteCalled(STRLOG_ClassName, STRLOG_MethodName, logMessage);

            QueuedExperimentInfo queuedExperimentInfo = null;

            lock (this.queueLock)
            {
                try
                {
                    //
                    // Check that the queued experiment info exists
                    //
                    if (experimentInfo == null)
                    {
                        throw new ArgumentNullException(STRERR_ExperimentInfoIsNull);
                    }

                    SqlCommand sqlCommand = new SqlCommand(STRSQLCMD_StoreQueue, this.sqlConnection);
                    sqlCommand.CommandType = CommandType.StoredProcedure;

                    sqlCommand.Parameters.Add(new SqlParameter(STRSQLPRM_ExperimentId, experimentInfo.experimentId));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQLPRM_SbName, experimentInfo.sbName));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQLPRM_UserGroup, experimentInfo.userGroup));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQLPRM_PriorityHint, experimentInfo.priorityHint));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQLPRM_XmlSpecification, experimentInfo.xmlSpecification));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQLPRM_EstimatedExecTime, experimentInfo.estExecutionTime));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQLPRM_Status, StatusCodes.Waiting.ToString()));

                    try
                    {
                        this.sqlConnection.Open();

                        if (sqlCommand.ExecuteNonQuery() == 0)
                        {
                            throw new Exception(STRERR_FailedToEnqueueExperiment);
                        }
                    }
                    catch (SqlException ex)
                    {
                        throw new Exception(STRERR_SqlException + ex.Message);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(STRERR_Exception + ex.Message);
                    }
                    finally
                    {
                        this.sqlConnection.Close();
                    }

                    //
                    // Get the queued experiment information and update with queue length
                    //
                    queuedExperimentInfo = GetQueuedExperimentInfo(experimentInfo.experimentId, experimentInfo.sbName);
                    queuedExperimentInfo.queueLength--;

                }
                catch (Exception ex)
                {
                    Logfile.WriteError(ex.Message);
                }
            }

            Logfile.WriteCompleted(STRLOG_ClassName, STRLOG_MethodName);

            return queuedExperimentInfo;
        }
        //---------------------------------------------------------------------------------------//
        /// <summary>
        /// Get the experiment information for the experiment waiting at the head of the queue.
        /// </summary>
        /// <returns></returns>
        public ExperimentInfo Dequeue(int unitId)
        {
            const string STRLOG_MethodName = "Dequeue";

            Logfile.WriteCalled(STRLOG_ClassName, STRLOG_MethodName);

            ExperimentInfo experimentInfo = null;

            //
            // Lock the queue so that two processes don't dequeue the same experiment before status is updated
            //
            lock (this.queueLock)
            {
                try
                {
                    SqlCommand sqlCommand = new SqlCommand(STRSQLCMD_RetrieveQueueAllWithStatus, this.sqlConnection);
                    sqlCommand.CommandType = CommandType.StoredProcedure;

                    sqlCommand.Parameters.Add(new SqlParameter(STRSQLPRM_Status, StatusCodes.Waiting.ToString()));

                    try
                    {
                        this.sqlConnection.Open();

                        SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
                        if (sqlDataReader.Read() == true)
                        {
                            experimentInfo = new ExperimentInfo(0, null);

                            //
                            // Get the experiment information from waiting experiment
                            //
                            object sdrObject = null;
                            if ((sdrObject = sqlDataReader[STRSQL_QueueId]) != System.DBNull.Value)
                                experimentInfo.queueId = (int)sdrObject;
                            if ((sdrObject = sqlDataReader[STRSQL_ExperimentId]) != System.DBNull.Value)
                                experimentInfo.experimentId = (int)sdrObject;
                            if ((sdrObject = sqlDataReader[STRSQL_SbName]) != System.DBNull.Value)
                                experimentInfo.sbName = (string)sdrObject;
                            if ((sdrObject = sqlDataReader[STRSQL_UserGroup]) != System.DBNull.Value)
                                experimentInfo.userGroup = (string)sdrObject;
                            if ((sdrObject = sqlDataReader[STRSQL_PriorityHint]) != System.DBNull.Value)
                                experimentInfo.priorityHint = (int)sdrObject;
                            if ((sdrObject = sqlDataReader[STRSQL_XmlSpecification]) != System.DBNull.Value)
                                experimentInfo.xmlSpecification = (string)sdrObject;
                            if ((sdrObject = sqlDataReader[STRSQL_Status]) != System.DBNull.Value)
                                experimentInfo.status = (StatusCodes)Enum.Parse(typeof(StatusCodes), (string)sdrObject);
                            if ((sdrObject = sqlDataReader[STRSQL_EstimatedExecTime]) != System.DBNull.Value)
                                experimentInfo.estExecutionTime = (int)sdrObject;
                            if ((sdrObject = sqlDataReader[STRSQL_Cancelled]) != System.DBNull.Value)
                                experimentInfo.cancelled = (bool)sdrObject;
                        }
                        sqlDataReader.Close();
                    }
                    catch (SqlException ex)
                    {
                        throw new Exception(STRERR_SqlException + ex.Message);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(STRERR_Exception + ex.Message);
                    }
                    finally
                    {
                        this.sqlConnection.Close();
                    }

                    if (experimentInfo != null)
                    {
                        //
                        // Update experiment status to 'Running' and update the unit ID
                        //
                        if (this.UpdateStatusToRunning(experimentInfo.experimentId, experimentInfo.sbName, unitId) == true)
                        {
                            experimentInfo.status = StatusCodes.Running;
                            experimentInfo.unitId = unitId;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logfile.WriteError(ex.Message);
                }
            }

            string logMessage = null;
            if (experimentInfo != null)
            {
                logMessage = STRLOG_experimentId + experimentInfo.experimentId.ToString() +
                    Logfile.STRLOG_Spacer + STRLOG_sbName + experimentInfo.sbName;
            }
            else
            {
                logMessage = STRLOG_NoExperimentsWaiting;
            }

            Logfile.WriteCompleted(STRLOG_ClassName, STRLOG_MethodName, logMessage);

            return experimentInfo;
        }
        //-------------------------------------------------------------------------------------------------//
        public SubmissionReport Submit(int experimentID, string sbName, string experimentSpecification,
            string userGroup, int priorityHint)
        {
            SubmissionReport submissionReport = null;

            //
            // Create a SubmissionReport object ready to fill in and return
            //
            submissionReport = new SubmissionReport(experimentID);

            //
            // Validate the experiment specification before submitting
            //
            ValidationReport validationReport = Validate(experimentSpecification, userGroup);
            if (validationReport.accepted == false)
            {
                // Experiment specification is invalid, cannot submit
                submissionReport.vReport = validationReport;
                return submissionReport;
            }

            //
            // Create an instance of the experiment
            //
            ExperimentInfo experimentInfo = new ExperimentInfo(experimentID, sbName,
                userGroup, priorityHint, experimentSpecification, (int)validationReport.estRuntime);

            //
            // Add the experiment to the queue
            //
            QueuedExperimentInfo queuedExperimentInfo = this.experimentQueue.Enqueue(experimentInfo);
            if (queuedExperimentInfo != null)
            {
                //
                // Update submission report
                //
                submissionReport.vReport.accepted = true;
                submissionReport.vReport.estRuntime = queuedExperimentInfo.estExecutionTime;
                submissionReport.wait = new WaitEstimate(queuedExperimentInfo.queueLength, queuedExperimentInfo.waitTime);

                //
                // Get minimum remaining runtime of any currently running experiments and add into the wait estimate
                //
                int minRemainingRuntime = GetMinRemainingRuntime();
                submissionReport.wait.estWait += minRemainingRuntime;

                //
                // Update the statistics with revised wait estimate
                //
                queuedExperimentInfo.waitTime = (int)submissionReport.wait.estWait;
                this.experimentStatistics.Submitted(queuedExperimentInfo, DateTime.Now);

                // Tell lab experiment manager thread that an experiment has been submitted
                this.SignalSubmitted();
            }
            else
            {
                //
                // Failed to add experiment to the queue
                //
                submissionReport.vReport.accepted = true;
                submissionReport.vReport.errorMessage = STRERR_FailedToQueueExperiment;
            }

            return submissionReport;
        }
        //-------------------------------------------------------------------------------------------------//
        public override ExperimentInfo RunExperiment(ExperimentInfo experimentInfo)
        {
            const string STRLOG_MethodName = "RunExperiment";

            Logfile.WriteCalled(STRLOG_ClassName, STRLOG_MethodName);

            // Create a result report ready to fill in
            experimentInfo.resultReport = new ResultReport();

            try
            {
                //
                // Parse the XML specification string to generate a validation report (should be accepted!)
                //
                Specification specification = new Specification(this.configuration, this.equipmentServiceProxy);
                ValidationReport validationReport = specification.Parse(experimentInfo.xmlSpecification);
                if (validationReport.accepted == false)
                {
                    throw new ArgumentException(validationReport.errorMessage);
                }
                experimentInfo.setupId = specification.SetupId;

                //
                // Create an instance of the driver for the specified setup and then
                // execute the experiment and return the result information
                //
                ResultInfo resultInfo = null;
                if (specification.SetupId.Equals(Consts.STRXML_SetupId_RadioactivityVsTime) ||
                    specification.SetupId.Equals(Consts.STRXML_SetupId_RadioactivityVsDistance))
                {
                    if (this.equipmentServiceProxy != null)
                    {
                        //
                        // Hardware is available to this unit, run it there
                        //
                        DriverRadioactivity driver = new DriverRadioactivity(this.equipmentServiceProxy, this.configuration, this.labExperimentInfo.cancelExperiment);
                        resultInfo = (ResultInfo)driver.Execute(specification);
                    }
                    else
                    {
                        //
                        // This unit does not have hardware available, run the simulation instead
                        //
                        DriverSimActivity driver = new DriverSimActivity(this.configuration, this.labExperimentInfo.cancelExperiment);
                        resultInfo = (ResultInfo)driver.Execute(specification);
                    }
                }
                else if (specification.SetupId.Equals(Consts.STRXML_SetupId_RadioactivityVsAbsorber))
                {
                    DriverAbsorbers driver = new DriverAbsorbers(this.equipmentServiceProxy, this.configuration, this.labExperimentInfo.cancelExperiment);
                    resultInfo = (ResultInfo)driver.Execute(specification);
                }
                else if (specification.SetupId.Equals(Consts.STRXML_SetupId_SimActivityVsTime) ||
                    specification.SetupId.Equals(Consts.STRXML_SetupId_SimActivityVsDistance))
                {
                    DriverSimActivity driver = new DriverSimActivity(this.configuration, this.labExperimentInfo.cancelExperiment);
                    resultInfo = (ResultInfo)driver.Execute(specification);
                }
                else if (specification.SetupId.Equals(Consts.STRXML_SetupId_SimActivityVsTimeNoDelay) ||
                    specification.SetupId.Equals(Consts.STRXML_SetupId_SimActivityVsDistanceNoDelay))
                {
                    DriverSimActivity driver = new DriverSimActivity(this.configuration, this.labExperimentInfo.cancelExperiment, false);
                    resultInfo = (ResultInfo)driver.Execute(specification);
                }

                //
                // Create an instance of LabExperimentResult to convert the experiment results to an XML string
                //
                ExperimentResult experimentResult = new ExperimentResult(
                    experimentInfo.experimentId, experimentInfo.sbName, DateTime.Now,
                    this.unitId, (Configuration)this.labConfiguration, specification, resultInfo);

                //
                // Fill in the result report
                //
                experimentInfo.resultReport.experimentResults = experimentResult.ToString();
                experimentInfo.resultReport.statusCode = (int)resultInfo.statusCode;
                experimentInfo.resultReport.errorMessage = resultInfo.errorMessage;
            }
            catch (Exception ex)
            {
                experimentInfo.resultReport.statusCode = (int)StatusCodes.Failed;
                experimentInfo.resultReport.errorMessage = ex.Message;
                Logfile.WriteError(ex.Message);
            }

            Logfile.WriteCompleted(STRLOG_ClassName, STRLOG_MethodName);

            return experimentInfo;
        }
Esempio n. 14
0
        //-------------------------------------------------------------------------------------------------//

        public SubmissionReport Submit(int experimentID, string sbName, string experimentSpecification,
                                       string userGroup, int priorityHint)
        {
            SubmissionReport submissionReport = null;

            //
            // Create a SubmissionReport object ready to fill in and return
            //
            submissionReport = new SubmissionReport(experimentID);

            //
            // Validate the experiment specification before submitting
            //
            ValidationReport validationReport = Validate(experimentSpecification, userGroup);

            if (validationReport.accepted == false)
            {
                // Experiment specification is invalid, cannot submit
                submissionReport.vReport = validationReport;
                return(submissionReport);
            }

            //
            // Create an instance of the experiment
            //
            ExperimentInfo experimentInfo = new ExperimentInfo(experimentID, sbName,
                                                               userGroup, priorityHint, experimentSpecification, (int)validationReport.estRuntime);

            //
            // Add the experiment to the queue
            //
            QueuedExperimentInfo queuedExperimentInfo = this.experimentQueue.Enqueue(experimentInfo);

            if (queuedExperimentInfo != null)
            {
                //
                // Update submission report
                //
                submissionReport.vReport.accepted   = true;
                submissionReport.vReport.estRuntime = queuedExperimentInfo.estExecutionTime;
                submissionReport.wait = new WaitEstimate(queuedExperimentInfo.queueLength, queuedExperimentInfo.waitTime);

                //
                // Get minimum remaining runtime of any currently running experiments and add into the wait estimate
                //
                int minRemainingRuntime = GetMinRemainingRuntime();
                submissionReport.wait.estWait += minRemainingRuntime;

                //
                // Update the statistics with revised wait estimate
                //
                queuedExperimentInfo.waitTime = (int)submissionReport.wait.estWait;
                this.experimentStatistics.Submitted(queuedExperimentInfo, DateTime.Now);

                // Tell lab experiment manager thread that an experiment has been submitted
                this.SignalSubmitted();
            }
            else
            {
                //
                // Failed to add experiment to the queue
                //
                submissionReport.vReport.accepted     = true;
                submissionReport.vReport.errorMessage = STRERR_FailedToQueueExperiment;
            }

            return(submissionReport);
        }