private void doStart() { if (!started.get()) { try { dataRecorderDriver.start(); } finally { try { strictExecutor.start(); } finally { try { dsPacketExecutor.start(); } finally { started.set(true); } } } } }
private void doRestart() { if (started.get()) { // Kill any remaining commands ... scheduler.killAll(); } else { try { dataRecorderDriver.start(); } finally { try { strictExecutor.start(); } finally { try { dsPacketExecutor.start(); } finally { started.set(true); } } } } }
private void doShutdown() { try { // First stop executing immediately; at this point, no Executables // will run ... strictExecutor.stop(); } finally { try { dsPacketExecutor.stop(); } finally { try { // Kill any remaining commands ... scheduler.killAll(); } finally { try { // Finally flush the data recorder ... dataRecorderDriver.stop(); } finally { started.set(false); } } } } }
private Strongback(Configurator config, Strongback previousInstance) { boolean start = false; if (previousInstance != null) { start = previousInstance.started.get(); // Terminates all currently-scheduled commands and stops the executor's thread (if running) // ... previousInstance.doShutdown(); strictExecutables = previousInstance.strictExecutables; executables = previousInstance.executables; switchReactor = previousInstance.switchReactor; executables.unregister(previousInstance.dataRecorderDriver); executables.unregister(previousInstance.eventRecorder); executables.unregister(previousInstance.scheduler); dataRecorderChannels = previousInstance.dataRecorderChannels; excessiveExecutionHandler = previousInstance.excessiveExecutionHandler; } else { executables = new Executables(); strictExecutables = new Executables(); switchReactor = new AsyncSwitchReactor(); executables.register(switchReactor); dataRecorderChannels = new DataRecorderChannels(); excessiveExecutionHandler = config.excessiveExecutorDelayHandler; } loggers = config.loggersSupplier.get(); clock = config.timeSystemSupplier.get(); // Create a new executor ... strictExecutor = PeriodicExecutor.roboRIONotifierWithFallback( "strictExecutor", config.executionPeriodInMilliseconds, TimeUnit.MILLISECONDS, strictExecutables, clock, loggers.apply("strictExecutor"), monitorDelay("strictExecutor", 100, TimeUnit.MILLISECONDS)); dsPacketExecutor = PeriodicExecutor.waitForDSPacketWithFallback( "dsPacketExecutor", config.driverstationExecutorTimeoutInMilliseconds, TimeUnit.MILLISECONDS, executables, clock, loggers.apply("dsPacketExecutor"), monitorDelay("dsPacketExecutor", 100, TimeUnit.MILLISECONDS)); // Create a new event recorder ... if (config.eventWriterFactory != null) { eventRecorder = new AsyncEventRecorder(config.eventWriterFactory.get(), clock); executables.register(eventRecorder); } else { eventRecorder = EventRecorder.noOp(); } // Create a new scheduler that optionally records command state // transitions. Note that we ignore everything in // the previous instance's scheduler, since all commands would have been // terminated (as intended) ... CommandListener commandListener = config.recordCommandStateChanges ? this::recordCommand : this::recordNoCommands; scheduler = new Scheduler(loggers.apply("scheduler"), commandListener); executables.register(scheduler); // Create a new data recorder driver ... dataRecorderDriver = new DataRecorderDriver(dataRecorderChannels, config.dataWriterFactory); executables.register(dataRecorderDriver); // Start this if the previous was already started ... if (previousInstance != null && start) { doStart(); } }