mirror of
https://github.com/danieldemus/openhab-addons
synced 2026-07-29 12:34:21 +02:00
[froniuswattpilot] Fix disposal and increase thread-safety of reconnectJob scheduling (#20711)
* [froniuswattpilot] Fix concurrency bugs & disposal Signed-off-by: Florian Hotze <dev@florianhotze.com>
This commit is contained in:
+41
-12
@@ -68,6 +68,7 @@ public class FroniusWattpilotHandler extends BaseThingHandler implements Wattpil
|
||||
|
||||
private @Nullable FroniusWattpilotConfiguration config;
|
||||
private @Nullable ScheduledFuture<?> reconnectJob;
|
||||
private volatile boolean isDisposed = false;
|
||||
|
||||
public FroniusWattpilotHandler(Thing thing, HttpClient httpClient) {
|
||||
super(thing);
|
||||
@@ -200,6 +201,10 @@ public class FroniusWattpilotHandler extends BaseThingHandler implements Wattpil
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
if (isDisposed) {
|
||||
logger.debug("Skipping initialization because handler is already disposed.");
|
||||
return;
|
||||
}
|
||||
config = getConfigAs(FroniusWattpilotConfiguration.class);
|
||||
|
||||
FroniusWattpilotConfiguration config = this.config;
|
||||
@@ -231,21 +236,37 @@ public class FroniusWattpilotHandler extends BaseThingHandler implements Wattpil
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
try {
|
||||
client.disconnect().get(3, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException | ExecutionException | TimeoutException e) {
|
||||
logger.error("Failed to disconnect", e);
|
||||
isDisposed = true;
|
||||
synchronized (this) {
|
||||
var reconnectJob = this.reconnectJob;
|
||||
if (reconnectJob != null) {
|
||||
reconnectJob.cancel(false);
|
||||
this.reconnectJob = null;
|
||||
}
|
||||
}
|
||||
client.removeListener(this);
|
||||
try {
|
||||
client.disconnect().get(3, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
logger.error("Failed to disconnect", e);
|
||||
} catch (ExecutionException | TimeoutException e) {
|
||||
logger.error("Failed to disconnect", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connected(WattpilotInfo info) {
|
||||
if (isDisposed) {
|
||||
return;
|
||||
}
|
||||
logger.debug("Connected to Wattpilot.");
|
||||
var reconnectJob = this.reconnectJob;
|
||||
if (reconnectJob != null) {
|
||||
reconnectJob.cancel(false);
|
||||
this.reconnectJob = null;
|
||||
synchronized (this) {
|
||||
var reconnectJob = this.reconnectJob;
|
||||
if (reconnectJob != null) {
|
||||
reconnectJob.cancel(false);
|
||||
this.reconnectJob = null;
|
||||
}
|
||||
}
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
updateDeviceProperties(info);
|
||||
@@ -253,17 +274,25 @@ public class FroniusWattpilotHandler extends BaseThingHandler implements Wattpil
|
||||
|
||||
@Override
|
||||
public void disconnected(String reason, @Nullable Throwable cause) {
|
||||
if (isDisposed) {
|
||||
return;
|
||||
}
|
||||
logger.debug("Disconnected from Wattpilot: {}", reason, cause);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, reason);
|
||||
var reconnectJob = this.reconnectJob;
|
||||
if (cause != null && reconnectJob == null) {
|
||||
logger.debug("Connection to Wattpilot lost, scheduling reconnection job ...", cause);
|
||||
this.reconnectJob = scheduler.scheduleAtFixedRate(this::initialize, 30L, 60L, TimeUnit.SECONDS);
|
||||
synchronized (this) {
|
||||
var reconnectJob = this.reconnectJob;
|
||||
if (cause != null && reconnectJob == null && !isDisposed) {
|
||||
logger.debug("Connection to Wattpilot lost, scheduling reconnection job ...", cause);
|
||||
this.reconnectJob = scheduler.scheduleAtFixedRate(this::initialize, 30L, 60L, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void statusChanged(WattpilotStatus status) {
|
||||
if (isDisposed) {
|
||||
return;
|
||||
}
|
||||
updateChannelsControl(status);
|
||||
updateChannelsStatus(status);
|
||||
updateChannelsMetrics(status);
|
||||
|
||||
Reference in New Issue
Block a user