[somfytahoma] Retry command submission when tahoma gateway is busy. (#10023)

* Retry command submission when tahome gateway is busy.
* Changed log level, cosmetic changes
* Store list of scheduled retries; cancelled when handler is disposed.
* Made retryFutures thread-safe

Signed-off-by: Georg Siebke <github@georgsiebke.de>
This commit is contained in:
Georg Siebke 2021-02-09 22:03:22 +01:00 committed by GitHub
parent 18e028a632
commit 95259b1095
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 3 deletions

View File

@ -26,6 +26,8 @@ public class SomfyTahomaConfig {
private String password = "";
private int refresh = 30;
private int statusTimeout = 300;
private int retries = 10;
private int retryDelay = 1000;
public String getEmail() {
return email;
@ -43,6 +45,14 @@ public class SomfyTahomaConfig {
return statusTimeout;
}
public int getRetries() {
return retries;
}
public int getRetryDelay() {
return retryDelay;
}
public void setEmail(String email) {
this.email = email;
}
@ -50,4 +60,12 @@ public class SomfyTahomaConfig {
public void setPassword(String password) {
this.password = password;
}
public void setRetries(int retries) {
this.retries = retries;
}
public void setRetryDelay(int retryDelay) {
this.retryDelay = retryDelay;
}
}

View File

@ -18,6 +18,7 @@ import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@ -78,6 +79,9 @@ public class SomfyTahomaBridgeHandler extends BaseBridgeHandler {
*/
private @Nullable ScheduledFuture<?> reconciliationFuture;
// List of futures used for command retries
private Collection<ScheduledFuture<?>> retryFutures = new ConcurrentLinkedQueue<ScheduledFuture<?>>();
/**
* List of executions
*/
@ -275,6 +279,9 @@ public class SomfyTahomaBridgeHandler extends BaseBridgeHandler {
logger.debug("Doing cleanup");
stopPolling();
executions.clear();
// cancel all scheduled retries
retryFutures.forEach(x -> x.cancel(false));
try {
httpClient.stop();
} catch (Exception e) {
@ -561,13 +568,23 @@ public class SomfyTahomaBridgeHandler extends BaseBridgeHandler {
return;
}
Boolean result = sendCommandInternal(io, command, params, url);
removeFinishedRetries();
boolean result = sendCommandInternal(io, command, params, url);
if (!result) {
sendCommandInternal(io, command, params, url);
scheduleRetry(io, command, params, url, thingConfig.getRetries());
}
}
private Boolean sendCommandInternal(String io, String command, String params, String url) {
private void repeatSendCommandInternal(String io, String command, String params, String url, int retries) {
logger.debug("Retrying command, retries left: {}", retries);
boolean result = sendCommandInternal(io, command, params, url);
if (!result && (retries > 0)) {
scheduleRetry(io, command, params, url, retries - 1);
}
}
private boolean sendCommandInternal(String io, String command, String params, String url) {
String value = params.equals("[]") ? command : params.replace("\"", "");
String urlParameters = "{\"label\":\"" + getThingLabelByURL(io) + " - " + value
+ " - OH2\",\"actions\":[{\"deviceURL\":\"" + io + "\",\"commands\":[{\"name\":\"" + command
@ -587,6 +604,17 @@ public class SomfyTahomaBridgeHandler extends BaseBridgeHandler {
return false;
}
private void removeFinishedRetries() {
retryFutures.removeIf(x -> x.isDone());
logger.debug("Currently {} retries are scheduled.", retryFutures.size());
}
private void scheduleRetry(String io, String command, String params, String url, int retries) {
retryFutures.add(scheduler.schedule(() -> {
repeatSendCommandInternal(io, command, params, url, retries);
}, thingConfig.getRetryDelay(), TimeUnit.MILLISECONDS));
}
private String getThingLabelByURL(String io) {
Thing th = getThingByDeviceUrl(io);
if (th != null) {

View File

@ -45,5 +45,17 @@
<description>Specifies the timeout in seconds after which the status is got from Tahoma cloud</description>
<default>300</default>
</parameter>
<parameter name="retries" type="integer" required="false">
<label>Retries</label>
<description>Specifies the number of retries when command execution</description>
<default>10</default>
</parameter>
<parameter name="retryDelay" type="integer" required="false" min="100">
<label>Retry delay</label>
<description>Specifies the delay in milliseconds between subsequent retries after a command failure</description>
<default>1000</default>
</parameter>
</config-description>
</config-description:config-descriptions>