[homekit] improve bundle deactivation time (#13566)
If you have many instances, it can take a while. So stop all the instances in parallel. Also, fix a race condition where the update debouncer might get called again after being stopped, because the change listener was deregistered _after_ the debouncer was stopped. Signed-off-by: Cody Cutrer <cody@cutrer.us>
This commit is contained in:
parent
77013bca39
commit
91383250d4
|
@ -42,7 +42,7 @@ class Debouncer {
|
||||||
private final Logger logger = LoggerFactory.getLogger(Debouncer.class);
|
private final Logger logger = LoggerFactory.getLogger(Debouncer.class);
|
||||||
|
|
||||||
private volatile Long lastCallAttempt;
|
private volatile Long lastCallAttempt;
|
||||||
private ScheduledFuture<?> feature;
|
private ScheduledFuture<?> future;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Highly performant generic debouncer
|
* Highly performant generic debouncer
|
||||||
|
@ -76,14 +76,14 @@ class Debouncer {
|
||||||
lastCallAttempt = clock.millis();
|
lastCallAttempt = clock.millis();
|
||||||
calls.incrementAndGet();
|
calls.incrementAndGet();
|
||||||
if (pending.compareAndSet(false, true)) {
|
if (pending.compareAndSet(false, true)) {
|
||||||
feature = scheduler.schedule(this::tryActionOrPostpone, delayMs, TimeUnit.MILLISECONDS);
|
future = scheduler.schedule(this::tryActionOrPostpone, delayMs, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
logger.trace("stop debouncer");
|
logger.trace("stop debouncer");
|
||||||
if (feature != null) {
|
if (future != null) {
|
||||||
feature.cancel(true);
|
future.cancel(true);
|
||||||
calls.set(0);
|
calls.set(0);
|
||||||
pending.set(false);
|
pending.set(false);
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ class Debouncer {
|
||||||
// Note: we use Math.max as there's a _very_ small chance lastCallAttempt could advance in another thread,
|
// Note: we use Math.max as there's a _very_ small chance lastCallAttempt could advance in another thread,
|
||||||
// and result in a negative calculation
|
// and result in a negative calculation
|
||||||
long delay = Math.max(1, lastCallAttempt - now + delayMs);
|
long delay = Math.max(1, lastCallAttempt - now + delayMs);
|
||||||
feature = scheduler.schedule(this::tryActionOrPostpone, delay, TimeUnit.MILLISECONDS);
|
future = scheduler.schedule(this::tryActionOrPostpone, delay, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -258,11 +258,6 @@ public class HomekitChangeListener implements ItemRegistryChangeListener {
|
||||||
accessoryRegistry.setBridge(bridge);
|
accessoryRegistry.setBridge(bridge);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void unsetBridge() {
|
|
||||||
applyUpdatesDebouncer.stop();
|
|
||||||
accessoryRegistry.unsetBridge();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUpdater(HomekitAccessoryUpdater updater) {
|
public void setUpdater(HomekitAccessoryUpdater updater) {
|
||||||
this.updater = updater;
|
this.updater = updater;
|
||||||
}
|
}
|
||||||
|
@ -271,9 +266,11 @@ public class HomekitChangeListener implements ItemRegistryChangeListener {
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
public synchronized void stop() {
|
||||||
this.itemRegistry.removeRegistryChangeListener(this);
|
this.itemRegistry.removeRegistryChangeListener(this);
|
||||||
this.metadataRegistry.removeRegistryChangeListener(metadataChangeListener);
|
this.metadataRegistry.removeRegistryChangeListener(metadataChangeListener);
|
||||||
|
applyUpdatesDebouncer.stop();
|
||||||
|
accessoryRegistry.unsetBridge();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, HomekitAccessory> getAccessories() {
|
public Map<String, HomekitAccessory> getAccessories() {
|
||||||
|
|
|
@ -257,12 +257,9 @@ public class HomekitImpl implements Homekit, NetworkAddressChangeListener {
|
||||||
|
|
||||||
private void stopHomekitServer() {
|
private void stopHomekitServer() {
|
||||||
logger.trace("stop HomeKit bridge");
|
logger.trace("stop HomeKit bridge");
|
||||||
for (int i = 0; i < homekitServers.size(); ++i) {
|
changeListeners.parallelStream().forEach(HomekitChangeListener::stop);
|
||||||
changeListeners.get(i).unsetBridge();
|
bridges.parallelStream().forEach(HomekitRoot::stop);
|
||||||
bridges.get(i).stop();
|
homekitServers.parallelStream().forEach(HomekitServer::stop);
|
||||||
homekitServers.get(i).stop();
|
|
||||||
changeListeners.get(i).stop();
|
|
||||||
}
|
|
||||||
homekitServers.clear();
|
homekitServers.clear();
|
||||||
bridges.clear();
|
bridges.clear();
|
||||||
changeListeners.clear();
|
changeListeners.clear();
|
||||||
|
|
Loading…
Reference in New Issue