Fix / Remove Races in Machine Enabling and Disabling #1414
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
Machine enabling/disabling has been handled outside the regular Machine task threading framework. The reason (as stated in comments in code) was that disabling should act as sort of Emergency Stop, i.e. be immediately effective, even if machine tasks are still running and/or pending in the queue. By tearing down the driver connections, any pending tasks would be indirectly killed through IO exceptions.
(Wikimedia)
When machine enabling/disabling was later expanded to include automatic machine homing and setting/initializing Actuators automatically in the Enabled/Disabled machine state change, this resulted in race conditions, as the generated machine tasks would then overlap with the special enable/disable thread and the command sequences sent there.
This PR refactors machine enabling/disabling to work inside the regular machine task threading framework whenever possible. Only when an Emergency Stop condition is detected will it actually perform as such. In this emergency case, some of the machine state change (disabled) actuations might not work (as before). This is now reported as error messages.
Changes
org.openpnp.spi.Driver.isSyncInitialLocation()
had to be moved to the spi).org.openpnp.util.UiUtils.submitUiMachineTask(Callable<Object>, Consumer<Object>, Consumer<Throwable>, boolean)
had to be added, to expose theignoreEnabled
boolean to allow running the enable task in the disabled machine.SampleJobTest
that is using explicitmachine.setEnable()
and subsequent machine tasks had to be adapted.GcodeServer
connection tear-down had to be made more robust, so a machine can be re-enabled after emergency stop.Justification
Users reported race conditions:
https://groups.google.com/g/desktop-pick-and-place/c/xrl44HcTpHQ/m/0Cn7HVAUAwAJ
Instructions for Use
When the machine is enabled, or when an idle machine is disabled, the enable/disable task is now run in a regular machine task.
Only when a busy machine is disabled, will the old method be used. In this case, the disable task is run in a separate thread and will tear down the connections, indirectly killing running/pending tasks.
Implementation Details
GcodeServer
connections/drivers.org.openpnp.spi.Driver.isSyncInitialLocation()
had to be moved to the spi, and implemented in allDriver
classes.4.Successful
mvn test
before submitting the Pull Request.