//---------------------------------------------------------------------------------------// /// <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; }
//---------------------------------------------------------------------------------------// /// <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); }
//---------------------------------------------------------------------------------------// /// <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); }
//-------------------------------------------------------------------------------------------------// 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 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); }