/** * @param experimentId * @param sbName * @return */ public ResultReport RetrieveResult(int experimentId, String sbName) { final String methodName = "RetrieveResult"; Logfile.WriteCalled( logLevel, STR_ClassName, methodName, String.format(STRLOG_ExperimentIdSbName_arg2, experimentId, sbName)); ResultReport resultReport; try { /* * Try getting the result of the completed experiment */ resultReport = this.labManagement.getExperimentResultsDB().RetrieveResultReport(experimentId, sbName); if (resultReport.getStatusCode() == StatusCodes.Unknown) { /* * No results found for the experiment, check the queue to see if it ever existed */ ExperimentQueueInfo experimentQueueInfo = this.labManagement.getExperimentQueueDB().RetrieveByExperimentId(experimentId, sbName); if (experimentQueueInfo != null) { resultReport.setStatusCode(experimentQueueInfo.getStatusCode()); } } } catch (Exception ex) { Logfile.WriteError(ex.toString()); resultReport = new ResultReport(StatusCodes.Unknown, ex.toString()); } Logfile.WriteCompleted( logLevel, STR_ClassName, methodName, String.format(STRLOG_StatusCode_arg, resultReport.getStatusCode())); return resultReport; }
@Override public void run() { final String methodName = "run"; Logfile.WriteCalled(logLevel, STR_ClassName, methodName); /* * Initialise state machine */ States lastState = States.Done; States thisState = States.Init; int nextUnit = this.labManagement.getFarmSize() - 1; this.running = true; /* * Allow other threads to check the state of this thread */ Delay.MilliSeconds(500); /* * State machine loop */ try { boolean success; while (thisState != States.Done) { /* * Display message on each state change */ if (thisState != lastState) { String logMessage = String.format(STRLOG_StateChange_arg2, lastState.toString(), thisState.toString()); if (debugTrace == true) { System.out.println(logMessage); } // Logfile.Write(logLevel, logMessage); lastState = thisState; } switch (thisState) { case Init: /* * Update lab status */ this.online = true; this.labStatusMessage = StatusCodes.Ready.toString(); /* * Revert any 'Running' experiments back to 'Waiting' so that they can be run again */ ArrayList<ExperimentQueueInfo> experimentQueueInfoList = this.labManagement.getExperimentQueueDB().RetrieveByStatusCode(StatusCodes.Running); if (experimentQueueInfoList != null) { for (ExperimentQueueInfo experimentQueueInfo : experimentQueueInfoList) { success = this.labManagement .getExperimentQueueDB() .UpdateStatus(experimentQueueInfo.getId(), StatusCodes.Waiting); /* * Delete the database statistics entry for this experiment */ ExperimentStatisticsInfo experimentStatisticInfo = this.labManagement .getExperimentStatisticsDB() .RetrieveByExperimentId( experimentQueueInfo.getExperimentId(), experimentQueueInfo.getSbName()); if (experimentStatisticInfo != null) { this.labManagement .getExperimentStatisticsDB() .Delete(experimentStatisticInfo.getId()); } /* * Delete the database results entry for this experiment */ ExperimentResultInfo experimentResultInfo = this.labManagement .getExperimentResultsDB() .RetrieveByExperimentId( experimentQueueInfo.getExperimentId(), experimentQueueInfo.getSbName()); if (experimentResultInfo != null) { this.labManagement.getExperimentResultsDB().Delete(experimentResultInfo.getId()); } String logMessage = String.format( STRLOG_RevertToWaiting_arg, experimentQueueInfo.getExperimentId(), experimentQueueInfo.getSbName(), success); Logfile.Write(logMessage); } } /* * Check if any experiments have not notified their ServiceBroker */ thisState = States.CheckNotified; break; case Idle: /* * Wait for an experiment to be submitted or timeout after a certain time. In either case, check * the experiment queue. Maybe an experiment submission signal got missed and it didn't get seen * here. It has happened before. */ if (this.labManagement.getSignalSubmitted().Wait(INT_DelayCheckQueueSeconds * 1000) == true) { /* * Check if shutting down */ if (this.stopRunning == true) { thisState = States.StopRunning; break; } /* * An experiment has been submitted, go check the queue */ this.labManagement.getSignalSubmitted().Reset(); thisState = States.CheckQueue; break; } /* * Timed out, go check some other things */ thisState = States.Maintenance; break; case CheckQueue: /* * Check the queue to see if there are any experiments waiting */ if (this.labManagement.getExperimentQueueDB().GetCountWaiting() > 0) { thisState = States.StartEngine; break; } thisState = States.Idle; break; case StartEngine: /* * Find the available experiment engine to run a waiting experiment */ boolean foundAvailable = false; for (int i = 0; i < this.labManagement.getFarmSize(); i++) { /* * Determine the next experiment engine for running the experiment */ if (++nextUnit == this.labManagement.getFarmSize()) { nextUnit = 0; } if (debugTrace == true) { System.out.println(String.format("[nextUnit: %s]", nextUnit)); } /* * Get the experiment engine and check to see if it is online */ LabExperimentEngine labExperimentEngine = this.labExperimentEngines[nextUnit]; LabStatus labStatus = labExperimentEngine.GetLabStatus(); if (labStatus.isOnline() == false) { /* * This one is not online */ if (debugTrace == true) { System.out.println(String.format("[nextUnit: %s is Offline]", nextUnit)); } continue; } /* * Determine if this experiment engine is currently running */ if (labExperimentEngine.isRunning() == false) { /* * Not running, try starting it */ if (labExperimentEngine.Start() == true) { /* * The available engine has been started, wait a bit before checking the queue */ foundAvailable = true; Delay.MilliSeconds(1000); break; } } } /* * Check if there are any engines available */ if (foundAvailable == false) { /* * No engines available to start running */ thisState = States.Idle; break; } thisState = States.CheckNotified; break; case CheckNotified: /* * Check if any experiments have not notified their ServiceBroker */ success = true; ArrayList<ExperimentResultInfo> allNotNotified = this.labManagement.getExperimentResultsDB().RetrieveAllNotNotified(); if (allNotNotified != null) { Iterator iterator = allNotNotified.iterator(); while (iterator.hasNext() && success == true) { ExperimentResultInfo experimentResultInfo = (ExperimentResultInfo) iterator.next(); success = this.labExperimentEngines[0].NotifyServiceBroker( experimentResultInfo.getExperimentId(), experimentResultInfo.getSbName()); } } thisState = States.CheckQueue; break; case Maintenance: thisState = States.Idle; break; case StopRunning: thisState = States.Done; break; } } } catch (Exception ex) { Logfile.WriteError(ex.toString()); } /* * Thread is no longer running */ this.running = false; Logfile.WriteCompleted(logLevel, STR_ClassName, methodName); }
/** * @param experimentId * @param sbName * @return */ public synchronized LabExperimentStatus GetLabExperimentStatus(int experimentId, String sbName) { final String methodName = "GetLabExperimentStatus"; Logfile.WriteCalled( Level.INFO, STR_ClassName, methodName, String.format(STRLOG_ExperimentIdSbName_arg2, experimentId, sbName)); LabExperimentStatus labExperimentStatus = new LabExperimentStatus(); try { /* * Check that parameters are valid */ if (experimentId <= 0) { throw new RuntimeException(String.format(STRERR_InvalidExperimentId_arg, experimentId)); } if (sbName == null) { throw new NullPointerException(STRERR_SbName); } /* * Get the status of the experiment from the queue */ ExperimentQueueInfo experimentQueueInfo = this.labManagement.getExperimentQueueDB().RetrieveByExperimentId(experimentId, sbName); if (experimentQueueInfo == null) { throw new RuntimeException( String.format(STRERR_UnknownExperimentSbNameExperimentId_arg2, sbName, experimentId)); } System.out.println(String.format("StatusCode: %s", experimentQueueInfo.getStatusCode())); /* * Experiment exists, check status */ switch (experimentQueueInfo.getStatusCode()) { case Waiting: /* * Experiment is waiting on the queue, get the queue position and wait time */ QueuedExperimentInfo queuedExperimentInfo = this.labManagement .getExperimentQueueDB() .GetQueuedExperimentInfo(experimentId, sbName); WaitEstimate waitEstimate = new WaitEstimate(); waitEstimate.setEffectiveQueueLength(queuedExperimentInfo.getPosition()); waitEstimate.setEstWait( queuedExperimentInfo.getWaitTime() + this.GetMinRemainingRuntime()); System.out.println( String.format( "WaitEstimate: QueueLength=%d WaitTime=%f01", waitEstimate.getEffectiveQueueLength(), waitEstimate.getEstWait())); /* * Set the experiment status and time it takes to run the experiment */ ExperimentStatus experimentStatus = new ExperimentStatus(experimentQueueInfo.getStatusCode()); experimentStatus.setEstRuntime(experimentQueueInfo.getEstimatedExecTime()); experimentStatus.setEstRemainingRuntime(experimentQueueInfo.getEstimatedExecTime()); experimentStatus.setWaitEstimate(waitEstimate); labExperimentStatus = new LabExperimentStatus(experimentStatus); Logfile.Write( logLevel, String.format( STRLOG_ExperimentStatus_arg4, waitEstimate.getEffectiveQueueLength(), waitEstimate.getEstWait(), experimentStatus.getEstRuntime(), experimentStatus.getEstRemainingRuntime())); System.out.println( String.format( STRLOG_ExperimentStatus_arg4, waitEstimate.getEffectiveQueueLength(), waitEstimate.getEstWait(), experimentStatus.getEstRuntime(), experimentStatus.getEstRemainingRuntime())); break; case Running: /* * Get the experiment status from the lab experiment engine */ LabExperimentEngine labExperimentEngine = this.labExperimentEngines[experimentQueueInfo.getUnitId()]; labExperimentStatus.setExperimentStatus( labExperimentEngine.GetExperimentStatus(experimentId, sbName)); break; case Cancelled: /* * The experiment was cancelled while waiting on the queue */ labExperimentStatus.setExperimentStatus(new ExperimentStatus(StatusCodes.Cancelled)); break; default: /* * Experiment has completed, cancelled or failed so get the status from the experiment results */ ResultReport resultReport = this.labManagement .getExperimentResultsDB() .RetrieveResultReport(experimentId, sbName); labExperimentStatus.setExperimentStatus( new ExperimentStatus(resultReport.getStatusCode())); break; } } catch (Exception ex) { Logfile.WriteError(ex.toString()); labExperimentStatus.setExperimentStatus(new ExperimentStatus(StatusCodes.Unknown)); } ExperimentStatus experimentStatus = labExperimentStatus.getExperimentStatus(); Logfile.WriteCompleted( Level.INFO, STR_ClassName, methodName, String.format( STRLOG_ExperimentStatus_arg3, experimentStatus.getStatusCode(), experimentStatus.getEstRuntime(), experimentStatus.getEstRemainingRuntime())); return labExperimentStatus; }