Add a time frame that the channel updater will wait before giving up if not connected,

This commit is contained in:
Vankka 2022-01-13 20:35:54 +02:00
parent ad6b7ee583
commit 595146cc5b
No known key found for this signature in database
GPG Key ID: 6E50CB7A29B96AD0
6 changed files with 76 additions and 18 deletions

View File

@ -135,6 +135,17 @@ public interface DiscordSRVApi {
*/
INITIALIZED,
/**
* DiscordSRV is attempting to connect to Discord.
*/
ATTEMPTING_TO_CONNECT,
/**
* DiscordSRV is connected to Discord & is ready.
* @see #isReady()
*/
CONNECTED,
/**
* DiscordSRV failed to load its configuration.
* @see #isError()
@ -149,23 +160,12 @@ public interface DiscordSRVApi {
*/
FAILED_TO_START(true),
/**
* DiscordSRV is attempting to connect to Discord.
*/
ATTEMPTING_TO_CONNECT,
/**
* DiscordSRV failed to connect to Discord.
* @see #isError()
*/
FAILED_TO_CONNECT(true),
/**
* DiscordSRV is connected to Discord & is ready.
* @see #isReady()
*/
CONNECTED,
/**
* DiscordSRV is shutting down.
* @see #isShutdown()

View File

@ -60,6 +60,7 @@ import javax.annotation.OverridingMethodsMustInvokeSuper;
import java.util.Locale;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantLock;
@ -190,7 +191,29 @@ public abstract class AbstractDiscordSRV<C extends MainConfig, CC extends Connec
@Override
public void setStatus(Status status) {
this.status.set(status);
synchronized (this.status) {
this.status.set(status);
this.status.notifyAll();
}
}
@Override
public void waitForStatus(Status statusToWaitFor, long time, TimeUnit unit) throws InterruptedException {
long deadline = time > 0 ? System.currentTimeMillis() + unit.toMillis(time) : Long.MAX_VALUE;
while (status().ordinal() < statusToWaitFor.ordinal()) {
long currentTime = System.currentTimeMillis();
if (currentTime > deadline) {
break;
}
synchronized (this.status) {
if (time > 0) {
this.status.wait(deadline - currentTime);
} else {
this.status.wait();
}
}
}
}
protected CompletableFuture<Void> invokeLifecycle(CheckedRunnable runnable, String message, boolean enable) {

View File

@ -41,6 +41,7 @@ import org.jetbrains.annotations.NotNull;
import java.nio.file.Path;
import java.util.Locale;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public interface DiscordSRV extends DiscordSRVApi {
@ -85,7 +86,13 @@ public interface DiscordSRV extends DiscordSRVApi {
void unregisterModule(AbstractModule module);
Locale locale();
// Status
void setStatus(Status status);
default void waitForStatus(Status status) throws InterruptedException {
waitForStatus(status, -1, TimeUnit.MILLISECONDS);
}
void waitForStatus(Status status, long time, TimeUnit unit) throws InterruptedException;
@SuppressWarnings("unchecked")
@ApiStatus.NonExtendable

View File

@ -23,6 +23,7 @@ import com.discordsrv.common.config.main.ChannelUpdaterConfig;
import com.discordsrv.common.module.type.AbstractModule;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.GuildChannel;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.managers.channel.ChannelManager;
import net.dv8tion.jda.api.managers.channel.concrete.TextChannelManager;
import org.apache.commons.lang3.StringUtils;
@ -36,6 +37,7 @@ import java.util.concurrent.TimeUnit;
public class ChannelUpdaterModule extends AbstractModule {
private final Set<ScheduledFuture<?>> futures = new LinkedHashSet<>();
private boolean firstReload = true;
public ChannelUpdaterModule(DiscordSRV discordSRV) {
super(discordSRV);
@ -55,13 +57,22 @@ public class ChannelUpdaterModule extends AbstractModule {
}
for (ChannelUpdaterConfig config : discordSRV.config().channelUpdaters) {
futures.add(
discordSRV.scheduler().runAtFixedRate(() -> update(config), config.timeMinutes, TimeUnit.MINUTES)
);
futures.add(discordSRV.scheduler().runAtFixedRate(
() -> update(config),
firstReload ? 0 : config.timeMinutes,
config.timeMinutes,
TimeUnit.MINUTES
));
}
firstReload = false;
}
public void update(ChannelUpdaterConfig config) {
try {
// Wait a moment in case we're (re)connecting at the time
discordSRV.waitForStatus(DiscordSRV.Status.CONNECTED, 15, TimeUnit.SECONDS);
} catch (InterruptedException ignored) {}
JDA jda = discordSRV.jda().orElse(null);
if (jda == null) {
return;
@ -84,13 +95,22 @@ public class ChannelUpdaterModule extends AbstractModule {
}
ChannelManager<?, ?> manager = channel.getManager();
if (manager instanceof TextChannelManager && StringUtils.isNotEmpty(topicFormat)) {
boolean anythingChanged = false;
if (manager instanceof TextChannelManager && channel instanceof TextChannel
&& StringUtils.isNotEmpty(topicFormat)
&& !topicFormat.equals(((TextChannel) channel).getTopic())) {
anythingChanged = true;
manager = ((TextChannelManager) manager).setTopic(topicFormat);
}
if (StringUtils.isNotEmpty(nameFormat)) {
if (StringUtils.isNotEmpty(nameFormat) && !nameFormat.equals(channel.getName())) {
anythingChanged = true;
manager = manager.setName(nameFormat);
}
if (!anythingChanged) {
continue;
}
manager.timeout(30, TimeUnit.SECONDS).queue();
}
}

View File

@ -27,7 +27,9 @@ import java.util.List;
@ConfigSerializable
public class ChannelUpdaterConfig {
@Comment("The channel IDs")
@Comment("The channel IDs.\n"
+ "The bot will need the \"View Channel\" and \"Manage Channels\" permissions, "
+ "additionally \"Connect\" is required for voice channels")
public List<Long> channelIds = new ArrayList<>();
@Comment("If this is blank, the name will not be updated")

View File

@ -44,6 +44,7 @@ import java.nio.file.Paths;
import java.util.Locale;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class MockDiscordSRV implements DiscordSRV {
@ -167,6 +168,11 @@ public class MockDiscordSRV implements DiscordSRV {
}
@Override
public void waitForStatus(Status status, long time, TimeUnit unit) throws InterruptedException {
}
@Override
public CompletableFuture<Void> invokeEnable() {
return null;