All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.dv8tion.jda.api.utils.SessionController Maven / Gradle / Ivy

Go to download

Java wrapper for the popular chat & VOIP service: Discord https://discord.com

There is a newer version: 5.1.0
Show newest version
/*
 * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.dv8tion.jda.api.utils;

import net.dv8tion.jda.annotations.ForRemoval;
import net.dv8tion.jda.annotations.ReplaceWith;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.requests.RestRateLimiter;

import javax.annotation.Nonnull;

/**
 * Controls states and behaviour of one or multiple {@link net.dv8tion.jda.api.JDA JDA} instances.
 * 
One instance of this should be used when sharding a bot account in order to keep track of session information * between shards. * *

The {@link net.dv8tion.jda.api.utils.SessionControllerAdapter SessionControllerAdapter} provides * a default implementation that can be extended and overridden. * *

States {@literal &} Behaviour
* Identify Ratelimit Handling *
This will enable handling of (re-)connecting gateway sessions. * *

Global REST Ratelimit *
The global REST ratelimit is not bound to a single session and should be * handled on all JDA instances. This controller will receive updates of this ratelimit through {@link #setGlobalRatelimit(long)} * and should report the last ratelimit information it received through {@link #getGlobalRatelimit()}. * *

Gateway Provider *
This provider can be used to change the gateway retrieval (using cache, http, or static) and * allows to set a custom gateway endpoint. Use carefully. * *

Examples
* * Using {@link net.dv8tion.jda.api.JDABuilder JDABuilder} *
*


 * JDABuilder builder = JDABuilder.createDefault(BOT_TOKEN);
 * builder.setSessionController(new SessionControllerAdapter() {
 *     {@literal @Override}
 *     public void appendSession(SessionConnectNode node) {
 *         System.out.println("[SessionController] Adding SessionConnectNode to Queue!");
 *         super.appendSession(node);
 *     }
 * });
 * builder.addEventListeners(myListener);
 * for (int i = 0; i {@literal <} 10; i++) {
 *     builder.useSharding(i, 10).build();
 * }
 * 
* *

Using {@link net.dv8tion.jda.api.sharding.ShardManager ShardManager} *
*


 * DefaultShardManagerBuilder builder = DefaultShardManagerBuilder.createDefault(BOT_TOKEN);
 * builder.setSessionController(new SessionControllerAdapter() {
 *     {@literal @Override}
 *     public {@literal Pair} getGatewayBot(JDA api) {
 *         return Pair.of(getGateway(), 10);
 *     }
 * });
 * builder.addEventListeners(myListener);
 * builder.build();
 * 
*/ public interface SessionController { /** * The default delay (in seconds) to wait between running {@link net.dv8tion.jda.api.utils.SessionController.SessionConnectNode SessionConnectNodes} */ int IDENTIFY_DELAY = 5; /** * Apply the {@code max_concurrency} for this bot. This property is only useful for very large bots * which get access to higher concurrency when starting their shards. * *

Currently, there are 3 different levels of concurrency 1, 16, and 64. * The concurrency means the bot can connect multiple shards at once without hitting the IDENTIFY rate-limit. * This works by applying the concurrency level as a modulo operand to the shard id: {@code shard_id % concurrency}. * We use one thread per bucket in this implementation. * *

An implementation of this interface is not required to use this concurrency level. * {@link SessionControllerAdapter} does not support this due to backwards compatibility. * * @param level * The concurrency level * * @throws AssertionError * If the provided level is not a valid array length size * * @since 4.2.0 */ default void setConcurrency(int level) {} /** * Called by a JDA session when a WebSocket should be started. (Connecting and Reconnecting) *
This should only add the node to a queue and execute the queue with respect to the {@link #IDENTIFY_DELAY}. * * @param node * The {@link net.dv8tion.jda.api.utils.SessionController.SessionConnectNode SessionConnectNode} */ void appendSession(@Nonnull SessionConnectNode node); /** * Called by a JDA session when a shutdown has been requested. *
When this happened the {@link net.dv8tion.jda.api.utils.SessionController.SessionConnectNode#run(boolean) SessionConnectNode.run(boolean)} * will be a no-op and does not contribute to the {@link #IDENTIFY_DELAY}. * * @param node * The {@link net.dv8tion.jda.api.utils.SessionController.SessionConnectNode SessionConnectNode} to remove from the queue. */ void removeSession(@Nonnull SessionConnectNode node); /** * Provides the cross-session global REST ratelimit it received through {@link #setGlobalRatelimit(long)}. * * @return The current global REST ratelimit or -1 if unset * * @deprecated Use {@link #getRateLimitHandle()} instead */ @Deprecated @ForRemoval(deadline = "5.0.0") @ReplaceWith("getRateLimitHandle().getClassic()") default long getGlobalRatelimit() { return -1; } /** * Called by the RateLimiter if the global rest ratelimit has changed. * * @param ratelimit * The new global ratelimit * * @deprecated Use {@link #getRateLimitHandle()} instead */ @Deprecated @ForRemoval(deadline = "5.0.0") @ReplaceWith("getRateLimitHandle().getClassic()") default void setGlobalRatelimit(long ratelimit) {} /** * The store for global rate-limits of all types. *
This can be used to share the global rate-limit information between shards on the same IP. * * @return The global rate-limiter */ @Nonnull default RestRateLimiter.GlobalRateLimit getRateLimitHandle() { return new GlobalRateLimitAdapter(this); } /** * Discord's gateway URL, which is used to receive events. * *

Called by JDA when starting a new gateway session (Connecting, Reconnecting). * * @return The gateway endpoint */ @Nonnull default String getGateway() { return "wss://gateway.discord.gg/"; } /** * Called by {@link net.dv8tion.jda.api.sharding.DefaultShardManager DefaultShardManager} * when a new shards is starting. *
Should provide a {@link ShardedGateway} with {@code (gateway, shardTotal)}. * * @param api * The current JDA instance (used for RestActions and ShardInfo) * * @return The ShardedGateway instance consisting of the gateway endpoint to connect to and the shardTotal * * @see #getGateway() */ @Nonnull ShardedGateway getShardedGateway(@Nonnull JDA api); /** * POJO containing the gateway endpoint and recommended shard total for a shard manager. */ class ShardedGateway { private final String url; private final int shardTotal; private final int concurrency; /** * Creates a new GatewayBot instance with the provided properties * * @param url * The gateway endpoint (wss) * @param shardTotal * The recommended shard total */ public ShardedGateway(String url, int shardTotal) { this(url, shardTotal, 1); } public ShardedGateway(String url, int shardTotal, int concurrency) { this.url = url; this.shardTotal = shardTotal; this.concurrency = concurrency; } /** * The gateway endpoint * * @return The endpoint */ public String getUrl() { return url; } /** * The recommended shard total * * @return The shard total */ public int getShardTotal() { return shardTotal; } /** * The concurrency level for this bot. *
This should not be a custom value as discord determines the eligible concurrency. * Using a different concurrency value could result in issues and possibly a ban due to login spam. * * @return The concurrency level * * @see #setConcurrency(int) */ public int getConcurrency() { return concurrency; } } /** * Represents a WebSocketClient request to start a session. *
Not implemented by library user. * *

Note: None of the provided session nodes can be resumed, the resume timeframe has already passed */ interface SessionConnectNode { /** * Whether this node is reconnecting. Can be used to setup a priority based system. * * @return True, if this session is reconnecting */ boolean isReconnect(); /** * The {@link net.dv8tion.jda.api.JDA JDA} instance for this request * * @return The JDA instance */ @Nonnull JDA getJDA(); /** * The {@link net.dv8tion.jda.api.JDA.ShardInfo ShardInfo} for this request. *
Can be used for a priority system. * * @return The ShardInfo */ @Nonnull JDA.ShardInfo getShardInfo(); /** * When called, establishes the session. *
This will return once the required payload to start the session has been delivered. * * @param isLast * True, if this is the last node in a queue worker. * When true this will not wait for the payload to be delivered. * * @throws InterruptedException * If the calling thread is interrupted */ void run(boolean isLast) throws InterruptedException; } /** * Wrapper for {@link #getGlobalRatelimit()} and {@link #setGlobalRatelimit(long)}. */ @Deprecated @ForRemoval(deadline = "5.0.0") @ReplaceWith("getRateLimitHandle()") @SuppressWarnings("DeprecatedIsStillUsed") class GlobalRateLimitAdapter implements RestRateLimiter.GlobalRateLimit { private final SessionController controller; public GlobalRateLimitAdapter(@Nonnull SessionController controller) { SessionControllerAdapter.log.warn("Using outdated implementation of global rate-limit handling. It is recommended to use GlobalRateLimit interface instead!"); this.controller = controller; } /** * Forwarding to {@link SessionController#getGlobalRatelimit()} * * @return The current global ratelimit */ @Override public long getClassic() { return controller.getGlobalRatelimit(); } /** * Forwarding to {@link SessionController#setGlobalRatelimit(long)} * * @param ratelimit * The new global ratelimit */ @Override public void setClassic(long ratelimit) { controller.setGlobalRatelimit(ratelimit); } /** * Forwarding to {@link SessionController#getGlobalRatelimit()} * * @return The current global ratelimit */ @Override public long getCloudflare() { return getClassic(); } /** * Forwarding to {@link SessionController#setGlobalRatelimit(long)} * * @param timestamp * The new global ratelimit */ @Override public void setCloudflare(long timestamp) { setClassic(timestamp); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy