Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,59 @@
import com.azuriom.azlink.common.data.UserInfo;
import com.azuriom.azlink.common.data.WebsiteResponse;

import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

public class FetcherTask implements Runnable {

private static final Duration MIN_REQUEST_INTERVAL = Duration.ofSeconds(5);

private final AzLinkPlugin plugin;

private Instant lastFullDataSent = Instant.MIN;
private Instant lastRequest = Instant.MIN;
private CompletableFuture<Void> scheduledFetch;

public FetcherTask(AzLinkPlugin plugin) {
this.plugin = plugin;
}

@Override
public void run() {
if (Instant.now().isBefore(nextRequestTime())) {
return;
}

fetch().exceptionally(ex -> {
this.plugin.getLogger().error("Unable to send data to the website: " + ex.getMessage());

return null;
});
}

public CompletableFuture<Void> fetch() {
public synchronized CompletableFuture<Void> fetch() {
Instant now = Instant.now();

if (!this.plugin.getConfig().isValid()
|| this.lastRequest.isAfter(now.minusSeconds(5))) {
if (!this.plugin.getConfig().isValid()) {
return CompletableFuture.completedFuture(null);
}

Instant nextRequest = nextRequestTime();

if (now.isBefore(nextRequest)) {
// The request in progress may already have missed what the caller is waiting for,
// like commands the website just queued, so send another one as soon as possible
return scheduleFetch(Duration.between(now, nextRequest).toMillis() + 1);
}

this.plugin.getPlatform().prepareDataAsync();
this.lastRequest = now;

Expand All @@ -57,6 +73,35 @@ public CompletableFuture<Void> fetch() {
.thenAcceptAsync(res -> handleResponse(res, sendFullData), sync);
}

private Instant nextRequestTime() {
return this.lastRequest.plus(MIN_REQUEST_INTERVAL);
}

private CompletableFuture<Void> scheduleFetch(long delayMillis) {
if (this.scheduledFetch != null) {
return this.scheduledFetch;
}

CompletableFuture<Void> future = new CompletableFuture<>();
this.scheduledFetch = future;

this.plugin.getScheduler().scheduleAsyncLater(() -> {
synchronized (this) {
this.scheduledFetch = null;
}

fetch().whenComplete((result, ex) -> {
if (ex != null) {
future.completeExceptionally(ex);
} else {
future.complete(null);
}
});
}, delayMillis, TimeUnit.MILLISECONDS);

return future;
}

private void handleResponse(WebsiteResponse response, boolean sendFullData) {
if (response == null) {
return;
Expand Down
Loading