Pass a scan reason for scheduling bus scan, so we can immediately retry when errors may be fixed, but avoid ping-pong while errors persist.
This commit is contained in:
@@ -31,17 +31,33 @@ import java.util.UUID;
|
||||
* @see DeviceBusElement
|
||||
*/
|
||||
public interface DeviceBusController {
|
||||
/**
|
||||
* Reason for a bus scan. Used to determine whether to immediately perform the scan or no, for example.
|
||||
*/
|
||||
enum ScanReason {
|
||||
BUS_CHANGE,
|
||||
BUS_ERROR,
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a scan.
|
||||
* <p>
|
||||
* This will immediately invalidate the current bus, i.e. all {@link DeviceBusElement}s
|
||||
* will be removed from the controller and {@link #getDevices()} will return an empty
|
||||
* list after this call.
|
||||
* Multiple sequential calls to this method do nothing, the actual scan will be performed
|
||||
* in the next update.
|
||||
*
|
||||
* @param reason the reason for the bus scan.
|
||||
*/
|
||||
void scheduleBusScan(ScanReason reason);
|
||||
|
||||
/**
|
||||
* Schedules a scan due to a bus configuration change.
|
||||
* <p>
|
||||
* Multiple sequential calls to this method do nothing, the actual scan will be performed
|
||||
* in the next update.
|
||||
*/
|
||||
void scheduleBusScan();
|
||||
default void scheduleBusScan() {
|
||||
scheduleBusScan(ScanReason.BUS_CHANGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces a device map rebuild.
|
||||
|
||||
@@ -66,8 +66,10 @@ public class CommonDeviceBusController implements DeviceBusController {
|
||||
public void dispose() {
|
||||
for (final DeviceBusElement element : elements) {
|
||||
element.removeController(this);
|
||||
|
||||
// Let other controllers on the bus know we're gone, so they can quickly recover.
|
||||
for (final DeviceBusController controller : element.getControllers()) {
|
||||
controller.scheduleBusScan();
|
||||
controller.scheduleBusScan(ScanReason.BUS_CHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,13 +85,15 @@ public class CommonDeviceBusController implements DeviceBusController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scheduleBusScan() {
|
||||
// For multiple controllers, avoid ping-ponging immediate scans when controllers
|
||||
// detect each other during their scans.
|
||||
if (state != BusState.MULTIPLE_CONTROLLERS) {
|
||||
scanDelay = 0; // scan as soon as possible
|
||||
state = BusState.SCAN_PENDING;
|
||||
public void scheduleBusScan(final ScanReason reason) {
|
||||
// For notification of a bus error, we just keep our old state and delay, if we have one.
|
||||
// Avoids ping-ponging error states causing scans every tick.
|
||||
if (reason == ScanReason.BUS_ERROR && state.ordinal() < BusState.READY.ordinal()) {
|
||||
return;
|
||||
}
|
||||
|
||||
scanDelay = 0; // scan as soon as possible
|
||||
state = BusState.SCAN_PENDING;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -172,7 +176,7 @@ public class CommonDeviceBusController implements DeviceBusController {
|
||||
// Rescan if any bus element gets invalidated. Don't have bus elements keep this instance alive,
|
||||
// only notify us on change if we still exist.
|
||||
LazyOptionalUtils.addWeakListener(optionals.get(element), this,
|
||||
(controller, ignored) -> controller.scheduleBusScan());
|
||||
(controller, ignored) -> controller.scheduleBusScan(ScanReason.BUS_CHANGE));
|
||||
}
|
||||
|
||||
scanDevices();
|
||||
@@ -273,6 +277,11 @@ public class CommonDeviceBusController implements DeviceBusController {
|
||||
|
||||
for (final DeviceBusElement removedElement : removedElements) {
|
||||
removedElement.removeController(this);
|
||||
|
||||
// Let other controllers on the bus know we're gone, so they can quickly recover.
|
||||
for (final DeviceBusController controller : removedElement.getControllers()) {
|
||||
controller.scheduleBusScan(ScanReason.BUS_CHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
final HashSet<DeviceBusElement> addedElements = new HashSet<>(newElements);
|
||||
@@ -302,7 +311,7 @@ public class CommonDeviceBusController implements DeviceBusController {
|
||||
// trigger a scan for those controllers, too, so they may enter error state.
|
||||
|
||||
for (final DeviceBusController controller : controllers) {
|
||||
controller.scheduleBusScan();
|
||||
controller.scheduleBusScan(ScanReason.BUS_ERROR);
|
||||
}
|
||||
|
||||
state = BusState.MULTIPLE_CONTROLLERS;
|
||||
|
||||
Reference in New Issue
Block a user