예제 #1
0
        //---------------------------------------------------------------------------------------//

        /// <summary>
        /// Get the length of the queue and estimated queue wait time.
        /// </summary>
        /// <returns></returns>
        public WaitEstimate GetWaitEstimate()
        {
            const string STRLOG_MethodName = "GetWaitEstimate";

            Logfile.WriteCalled(STRLOG_ClassName, STRLOG_MethodName);

            WaitEstimate waitEstimate;

            //
            // Get the queued experiment information for non-existent experiment
            //
            QueuedExperimentInfo queuedExperimentInfo = GetQueuedExperimentInfo(0, null);

            //
            // Save the wait estimate information
            //
            if (queuedExperimentInfo != null)
            {
                waitEstimate = new WaitEstimate(queuedExperimentInfo.queueLength, queuedExperimentInfo.waitTime);
            }
            else
            {
                // Should never occur, but anyway...
                waitEstimate = new WaitEstimate();
            }

            Logfile.WriteCompleted(STRLOG_ClassName, STRLOG_MethodName);

            return(waitEstimate);
        }
        //---------------------------------------------------------------------------------------//
        public bool Submitted(QueuedExperimentInfo queuedExperimentInfo, DateTime timeSubmitted)
        {
            const string STRLOG_MethodName = "Submitted";

            string logMessage = null;
            if (queuedExperimentInfo != null)
            {
                logMessage = STRLOG_experimentId + queuedExperimentInfo.experimentId.ToString() +
                    Logfile.STRLOG_Spacer + STRLOG_sbName + Logfile.STRLOG_Quote + queuedExperimentInfo.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.statisticsLock)
            {
                try
                {
                    //
                    // Check that the queued experiment info exists
                    //
                    if (queuedExperimentInfo == null)
                    {
                        throw new ArgumentNullException(STRERR_QueuedExperimentInfoIsNull);
                    }

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

                    sqlCommand.Parameters.Add(new SqlParameter(STRSQL_ExperimentId, queuedExperimentInfo.experimentId));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQL_SbName, queuedExperimentInfo.sbName));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQL_UserGroup, queuedExperimentInfo.userGroup));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQL_PriorityHint, queuedExperimentInfo.priorityHint));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQL_EstimatedExecTime, queuedExperimentInfo.estExecutionTime));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQL_TimeSubmitted, timeSubmitted));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQL_QueueLength, queuedExperimentInfo.position - 1));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQL_EstimatedWaitTime, queuedExperimentInfo.waitTime));

                    try
                    {
                        this.sqlConnection.Open();

                        if (sqlCommand.ExecuteNonQuery() == 0)
                        {
                            throw new Exception(STRERR_FailedToSubmitStatistics);
                        }
                    }
                    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;
        }
        //---------------------------------------------------------------------------------------//

        public bool Submitted(QueuedExperimentInfo queuedExperimentInfo, DateTime timeSubmitted)
        {
            const string STRLOG_MethodName = "Submitted";

            string logMessage = null;

            if (queuedExperimentInfo != null)
            {
                logMessage = STRLOG_experimentId + queuedExperimentInfo.experimentId.ToString() +
                             Logfile.STRLOG_Spacer + STRLOG_sbName + Logfile.STRLOG_Quote + queuedExperimentInfo.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.statisticsLock)
            {
                try
                {
                    //
                    // Check that the queued experiment info exists
                    //
                    if (queuedExperimentInfo == null)
                    {
                        throw new ArgumentNullException(STRERR_QueuedExperimentInfoIsNull);
                    }

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

                    sqlCommand.Parameters.Add(new SqlParameter(STRSQL_ExperimentId, queuedExperimentInfo.experimentId));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQL_SbName, queuedExperimentInfo.sbName));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQL_UserGroup, queuedExperimentInfo.userGroup));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQL_PriorityHint, queuedExperimentInfo.priorityHint));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQL_EstimatedExecTime, queuedExperimentInfo.estExecutionTime));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQL_TimeSubmitted, timeSubmitted));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQL_QueueLength, queuedExperimentInfo.position - 1));
                    sqlCommand.Parameters.Add(new SqlParameter(STRSQL_EstimatedWaitTime, queuedExperimentInfo.waitTime));

                    try
                    {
                        this.sqlConnection.Open();

                        if (sqlCommand.ExecuteNonQuery() == 0)
                        {
                            throw new Exception(STRERR_FailedToSubmitStatistics);
                        }
                    }
                    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);
        }
        //---------------------------------------------------------------------------------------//
        /// <summary>
        /// Get the queued experiment information for the specified experiment. If the experiment is
        /// not waiting on the queue, 'experimentId' is set to zero and 'sbName' is set to null.
        /// In either case, the queue length and estimated queue wait are returned.
        /// </summary>
        /// <param name="experimentId"></param>
        /// <param name="sbName"></param>
        /// <returns></returns>
        public QueuedExperimentInfo GetQueuedExperimentInfo(int experimentId, string sbName)
        {
            const string STRLOG_MethodName = "GetQueuedExperimentInfo";

            string logMessage = STRLOG_experimentId + experimentId.ToString() +
                Logfile.STRLOG_Spacer + STRLOG_sbName + Logfile.STRLOG_Quote + sbName + Logfile.STRLOG_Quote;

            Logfile.WriteCalled(STRLOG_ClassName, STRLOG_MethodName, logMessage);

            QueuedExperimentInfo queuedExperimentInfo = null;
            int queueLength = 0;
            int position = 1;
            int waitTime = 0;

            lock (this.queueLock)
            {
                try
                {
                    //
                    // Scan through all experiments waiting in the queue
                    //
                    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();
                        while (sqlDataReader.Read() == true)
                        {
                            int _experimentId = -1;
                            string _sbName = string.Empty;
                            int estExecutionTime = -1;

                            //
                            // Get the experiment ID, ServiceBroker's name and execution time for this experiment
                            //
                            object sdrObject = null;
                            if ((sdrObject = sqlDataReader[STRSQL_ExperimentId]) != System.DBNull.Value)
                                _experimentId = (int)sdrObject;
                            if ((sdrObject = sqlDataReader[STRSQL_SbName]) != System.DBNull.Value)
                                _sbName = (string)sdrObject;
                            if ((sdrObject = sqlDataReader[STRSQL_EstimatedExecTime]) != System.DBNull.Value)
                                estExecutionTime = (int)sdrObject;

                            //
                            // Check the experiment ID and ServiceBroker's name for a match
                            //
                            if (_experimentId == experimentId && _sbName.Equals(sbName, StringComparison.OrdinalIgnoreCase) &&
                                queuedExperimentInfo == null)
                            {
                                //
                                // Found the experiment, save experiment information
                                //
                                queuedExperimentInfo = new QueuedExperimentInfo(experimentId, sbName);
                                queuedExperimentInfo.estExecutionTime = estExecutionTime;

                                if ((sdrObject = sqlDataReader[STRSQL_QueueId]) != System.DBNull.Value)
                                    queuedExperimentInfo.queueId = (int)sdrObject;
                                if ((sdrObject = sqlDataReader[STRSQL_UserGroup]) != System.DBNull.Value)
                                    queuedExperimentInfo.userGroup = (string)sdrObject;
                                if ((sdrObject = sqlDataReader[STRSQL_PriorityHint]) != System.DBNull.Value)
                                    queuedExperimentInfo.priorityHint = (int)sdrObject;
                                if ((sdrObject = sqlDataReader[STRSQL_XmlSpecification]) != System.DBNull.Value)
                                    queuedExperimentInfo.xmlSpecification = (string)sdrObject;
                                if ((sdrObject = sqlDataReader[STRSQL_Status]) != System.DBNull.Value)
                                    queuedExperimentInfo.status = (StatusCodes)Enum.Parse(typeof(StatusCodes), (string)sdrObject);
                                if ((sdrObject = sqlDataReader[STRSQL_UnitId]) != System.DBNull.Value)
                                    queuedExperimentInfo.unitId = (int)sdrObject;
                                if ((sdrObject = sqlDataReader[STRSQL_Cancelled]) != System.DBNull.Value)
                                    queuedExperimentInfo.cancelled = (bool)sdrObject;

                                queuedExperimentInfo.position = position;
                                queuedExperimentInfo.waitTime = waitTime;
                            }

                            // Add the wait time for this experiment
                            waitTime += estExecutionTime;

                            //
                            // Increment queue length and position
                            //
                            queueLength++;
                            position++;
                        }
                        sqlDataReader.Close();

                        //
                        // Check if the experiment was found
                        //
                        if (queuedExperimentInfo == null)
                        {
                            //
                            // Not found, only provide the queue length and estimated wait time
                            //
                            queuedExperimentInfo = new QueuedExperimentInfo(0, null);
                            queuedExperimentInfo.waitTime = waitTime;
                        }
                        queuedExperimentInfo.queueLength = queueLength;
                    }
                    catch (SqlException ex)
                    {
                        throw new Exception(STRERR_SqlException + ex.Message);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(STRERR_Exception + ex.Message);
                    }
                    finally
                    {
                        this.sqlConnection.Close();
                    }

                    logMessage = STRLOG_position + queuedExperimentInfo.position.ToString() +
                        Logfile.STRLOG_Spacer + STRLOG_queueLength + queuedExperimentInfo.queueLength +
                        Logfile.STRLOG_Spacer + STRLOG_waitTime + queuedExperimentInfo.waitTime.ToString() + STRLOG_seconds +
                        Logfile.STRLOG_Spacer + STRLOG_estExecutionTime + queuedExperimentInfo.estExecutionTime.ToString() + STRLOG_seconds;
                }
                catch (Exception ex)
                {
                    Logfile.WriteError(ex.Message);
                }
            }

            Logfile.WriteCompleted(STRLOG_ClassName, STRLOG_MethodName, logMessage);

            return queuedExperimentInfo;
        }
예제 #5
0
        //---------------------------------------------------------------------------------------//

        /// <summary>
        /// Get the queued experiment information for the specified experiment. If the experiment is
        /// not waiting on the queue, 'experimentId' is set to zero and 'sbName' is set to null.
        /// In either case, the queue length and estimated queue wait are returned.
        /// </summary>
        /// <param name="experimentId"></param>
        /// <param name="sbName"></param>
        /// <returns></returns>
        public QueuedExperimentInfo GetQueuedExperimentInfo(int experimentId, string sbName)
        {
            const string STRLOG_MethodName = "GetQueuedExperimentInfo";

            string logMessage = STRLOG_experimentId + experimentId.ToString() +
                                Logfile.STRLOG_Spacer + STRLOG_sbName + Logfile.STRLOG_Quote + sbName + Logfile.STRLOG_Quote;

            Logfile.WriteCalled(STRLOG_ClassName, STRLOG_MethodName, logMessage);

            QueuedExperimentInfo queuedExperimentInfo = null;
            int queueLength = 0;
            int position    = 1;
            int waitTime    = 0;

            lock (this.queueLock)
            {
                try
                {
                    //
                    // Scan through all experiments waiting in the queue
                    //
                    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();
                        while (sqlDataReader.Read() == true)
                        {
                            int    _experimentId    = -1;
                            string _sbName          = string.Empty;
                            int    estExecutionTime = -1;

                            //
                            // Get the experiment ID, ServiceBroker's name and execution time for this experiment
                            //
                            object sdrObject = null;
                            if ((sdrObject = sqlDataReader[STRSQL_ExperimentId]) != System.DBNull.Value)
                            {
                                _experimentId = (int)sdrObject;
                            }
                            if ((sdrObject = sqlDataReader[STRSQL_SbName]) != System.DBNull.Value)
                            {
                                _sbName = (string)sdrObject;
                            }
                            if ((sdrObject = sqlDataReader[STRSQL_EstimatedExecTime]) != System.DBNull.Value)
                            {
                                estExecutionTime = (int)sdrObject;
                            }

                            //
                            // Check the experiment ID and ServiceBroker's name for a match
                            //
                            if (_experimentId == experimentId && _sbName.Equals(sbName, StringComparison.OrdinalIgnoreCase) &&
                                queuedExperimentInfo == null)
                            {
                                //
                                // Found the experiment, save experiment information
                                //
                                queuedExperimentInfo = new QueuedExperimentInfo(experimentId, sbName);
                                queuedExperimentInfo.estExecutionTime = estExecutionTime;

                                if ((sdrObject = sqlDataReader[STRSQL_QueueId]) != System.DBNull.Value)
                                {
                                    queuedExperimentInfo.queueId = (int)sdrObject;
                                }
                                if ((sdrObject = sqlDataReader[STRSQL_UserGroup]) != System.DBNull.Value)
                                {
                                    queuedExperimentInfo.userGroup = (string)sdrObject;
                                }
                                if ((sdrObject = sqlDataReader[STRSQL_PriorityHint]) != System.DBNull.Value)
                                {
                                    queuedExperimentInfo.priorityHint = (int)sdrObject;
                                }
                                if ((sdrObject = sqlDataReader[STRSQL_XmlSpecification]) != System.DBNull.Value)
                                {
                                    queuedExperimentInfo.xmlSpecification = (string)sdrObject;
                                }
                                if ((sdrObject = sqlDataReader[STRSQL_Status]) != System.DBNull.Value)
                                {
                                    queuedExperimentInfo.status = (StatusCodes)Enum.Parse(typeof(StatusCodes), (string)sdrObject);
                                }
                                if ((sdrObject = sqlDataReader[STRSQL_UnitId]) != System.DBNull.Value)
                                {
                                    queuedExperimentInfo.unitId = (int)sdrObject;
                                }
                                if ((sdrObject = sqlDataReader[STRSQL_Cancelled]) != System.DBNull.Value)
                                {
                                    queuedExperimentInfo.cancelled = (bool)sdrObject;
                                }

                                queuedExperimentInfo.position = position;
                                queuedExperimentInfo.waitTime = waitTime;
                            }

                            // Add the wait time for this experiment
                            waitTime += estExecutionTime;

                            //
                            // Increment queue length and position
                            //
                            queueLength++;
                            position++;
                        }
                        sqlDataReader.Close();

                        //
                        // Check if the experiment was found
                        //
                        if (queuedExperimentInfo == null)
                        {
                            //
                            // Not found, only provide the queue length and estimated wait time
                            //
                            queuedExperimentInfo          = new QueuedExperimentInfo(0, null);
                            queuedExperimentInfo.waitTime = waitTime;
                        }
                        queuedExperimentInfo.queueLength = queueLength;
                    }
                    catch (SqlException ex)
                    {
                        throw new Exception(STRERR_SqlException + ex.Message);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(STRERR_Exception + ex.Message);
                    }
                    finally
                    {
                        this.sqlConnection.Close();
                    }

                    logMessage = STRLOG_position + queuedExperimentInfo.position.ToString() +
                                 Logfile.STRLOG_Spacer + STRLOG_queueLength + queuedExperimentInfo.queueLength +
                                 Logfile.STRLOG_Spacer + STRLOG_waitTime + queuedExperimentInfo.waitTime.ToString() + STRLOG_seconds +
                                 Logfile.STRLOG_Spacer + STRLOG_estExecutionTime + queuedExperimentInfo.estExecutionTime.ToString() + STRLOG_seconds;
                }
                catch (Exception ex)
                {
                    Logfile.WriteError(ex.Message);
                }
            }

            Logfile.WriteCompleted(STRLOG_ClassName, STRLOG_MethodName, logMessage);

            return(queuedExperimentInfo);
        }
예제 #6
0
        //---------------------------------------------------------------------------------------//

        /// <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);
        }
예제 #7
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);
        }
예제 #8
0
        //-------------------------------------------------------------------------------------------------//

        public LabExperimentStatus GetExperimentStatus(int experimentId, string sbName)
        {
            const string STRLOG_MethodName = "GetExperimentStatus";

            LabExperimentStatus labExperimentStatus = null;

            lock (this.managerLock)
            {
                string logMessage = STRLOG_experimentId + experimentId.ToString() +
                                    Logfile.STRLOG_Spacer + STRLOG_sbName + Logfile.STRLOG_Quote + sbName + Logfile.STRLOG_Quote;

                Logfile.WriteCalled(STRLOG_ClassName, STRLOG_MethodName, logMessage);

                labExperimentStatus = new LabExperimentStatus();
                logMessage          = string.Empty;

                //
                // Get the status of the experiment from the queue table
                //
                StatusCodes status = this.experimentQueue.GetExperimentStatus(experimentId, sbName);
                if (status == StatusCodes.Unknown)
                {
                    //
                    // The experiment never existed
                    //
                }
                else if (status == StatusCodes.Waiting)
                {
                    //
                    // Experiment is waiting on the queue
                    //
                    QueuedExperimentInfo queuedExperimentInfo = this.experimentQueue.GetQueuedExperimentInfo(experimentId, sbName);
                    if (queuedExperimentInfo != null && queuedExperimentInfo.position > 0)
                    {
                        // Set the experiment status
                        labExperimentStatus.statusReport.statusCode = (int)queuedExperimentInfo.status;

                        // Get the queue position and wait time
                        labExperimentStatus.statusReport.wait =
                            new WaitEstimate(queuedExperimentInfo.position, queuedExperimentInfo.waitTime);

                        // Add in time for any currently running experiment ????
                        labExperimentStatus.statusReport.wait.estWait += GetMinRemainingRuntime();

                        // Get the time it takes to run the experiment
                        labExperimentStatus.statusReport.estRuntime          = queuedExperimentInfo.estExecutionTime;
                        labExperimentStatus.statusReport.estRemainingRuntime = queuedExperimentInfo.estExecutionTime;

                        logMessage =
                            Logfile.STRLOG_Spacer + STRLOG_QueuePosition + labExperimentStatus.statusReport.wait.effectiveQueueLength.ToString() +
                            Logfile.STRLOG_Spacer + STRLOG_QueueWaitTime + labExperimentStatus.statusReport.wait.estWait.ToString() +
                            Logfile.STRLOG_Spacer + STRLOG_estRuntime + labExperimentStatus.statusReport.estRuntime.ToString() +
                            Logfile.STRLOG_Spacer + STRLOG_remainingRuntime + labExperimentStatus.statusReport.estRemainingRuntime.ToString();
                    }
                }
                else if (status == StatusCodes.Running)
                {
                    //
                    // Experiment is currently running
                    //
                    labExperimentStatus = this.GetLabExperimentStatus(experimentId, sbName);
                }
                else
                {
                    //
                    // Experiment has completed, cancelled or failed
                    //
                    ResultReport resultReport = this.experimentResults.Load(experimentId, sbName);

                    // Set the experiment status
                    labExperimentStatus.statusReport.statusCode = resultReport.statusCode;
                }

                logMessage = STRLOG_statusCode + ((StatusCodes)labExperimentStatus.statusReport.statusCode).ToString() +
                             Logfile.STRLOG_Spacer + logMessage;

                Logfile.WriteCompleted(STRLOG_ClassName, STRLOG_MethodName, logMessage);
            }

            return(labExperimentStatus);
        }