From c793adafaca5cbd956164f9ae7dabf0af909cf17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Sun, 10 Dec 2017 19:16:12 +0100 Subject: [PATCH] Updated for ShardManager changes --- .../jda/bot/sharding/DefaultShardManager.java | 19 +++- .../sharding/DefaultShardManagerBuilder.java | 96 ++++++++++++------- .../jda/core/entities/impl/JDAImpl.java | 7 +- 3 files changed, 77 insertions(+), 45 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/bot/sharding/DefaultShardManager.java b/src/main/java/net/dv8tion/jda/bot/sharding/DefaultShardManager.java index 8827b3d91f..4960a6772f 100644 --- a/src/main/java/net/dv8tion/jda/bot/sharding/DefaultShardManager.java +++ b/src/main/java/net/dv8tion/jda/bot/sharding/DefaultShardManager.java @@ -36,6 +36,7 @@ import net.dv8tion.jda.core.utils.tuple.Pair; import okhttp3.OkHttpClient; import org.slf4j.Logger; +import org.slf4j.MDC; import javax.security.auth.login.LoginException; import java.util.*; @@ -195,6 +196,11 @@ public class DefaultShardManager implements ShardManager */ protected IntFunction statusProvider; + /** + * The MDC context new JDA instances should have on startup. + */ + protected Map contextMap; + /** * Creates a new DefaultShardManager instance. * @param shardsTotal @@ -250,7 +256,8 @@ protected DefaultShardManager(final int shardsTotal, final Collection s final int maxReconnectDelay, final int corePoolSize, final boolean enableVoice, final boolean enableShutdownHook, final boolean enableBulkDeleteSplitting, final boolean autoReconnect, final IntFunction idleProvider, - final boolean retryOnTimeout, boolean useShutdownNow) + final boolean retryOnTimeout, final boolean useShutdownNow, + final Map contextMap) { this.shardsTotal = shardsTotal; this.listeners = listeners; @@ -272,6 +279,7 @@ protected DefaultShardManager(final int shardsTotal, final Collection s this.idleProvider = idleProvider; this.retryOnTimeout = retryOnTimeout; this.useShutdownNow = useShutdownNow; + this.contextMap = contextMap; if (shardsTotal != -1) { @@ -489,7 +497,7 @@ protected JDAImpl buildInstance(final int shardId) throws LoginException, RateLi { final JDAImpl jda = new JDAImpl(AccountType.BOT, this.token, this.httpClientBuilder, this.wsFactory, this.shardedRateLimiter, this.autoReconnect, this.enableVoice, this.enableBulkDeleteSplitting, this.enableBulkDeleteSplitting, retryOnTimeout, - this.corePoolSize, this.maxReconnectDelay); + this.corePoolSize, this.maxReconnectDelay, this.contextMap == null ? null : new ConcurrentHashMap<>(this.contextMap)); jda.asBot().setShardManager(this); @@ -597,7 +605,12 @@ protected ScheduledExecutorService createExecutor(ThreadFactory threadFactory) ThreadFactory factory = threadFactory == null ? r -> { - final Thread t = new Thread(r, "DefaultShardManager"); + final Thread t = new Thread(() -> + { + MDC.setContextMap(contextMap); + r.run(); + }); + t.setName("DefaultShardManager"); t.setDaemon(true); t.setPriority(Thread.NORM_PRIORITY + 1); return t; diff --git a/src/main/java/net/dv8tion/jda/bot/sharding/DefaultShardManagerBuilder.java b/src/main/java/net/dv8tion/jda/bot/sharding/DefaultShardManagerBuilder.java index 2aa31ba46f..fbe856a58c 100644 --- a/src/main/java/net/dv8tion/jda/bot/sharding/DefaultShardManagerBuilder.java +++ b/src/main/java/net/dv8tion/jda/bot/sharding/DefaultShardManagerBuilder.java @@ -16,12 +16,6 @@ package net.dv8tion.jda.bot.sharding; import com.neovisionaries.ws.client.WebSocketFactory; -import java.util.*; -import java.util.concurrent.ThreadFactory; -import java.util.function.IntFunction; -import java.util.stream.Collectors; -import javax.security.auth.login.LoginException; - import net.dv8tion.jda.core.OnlineStatus; import net.dv8tion.jda.core.ShardedRateLimiter; import net.dv8tion.jda.core.audio.factory.IAudioSendFactory; @@ -30,6 +24,12 @@ import net.dv8tion.jda.core.utils.Checks; import okhttp3.OkHttpClient; +import javax.security.auth.login.LoginException; +import java.util.*; +import java.util.concurrent.ThreadFactory; +import java.util.function.IntFunction; +import java.util.stream.Collectors; + /** * Used to create new instances of JDA's default {@link net.dv8tion.jda.bot.sharding.ShardManager ShardManager} implementation. * @@ -41,6 +41,8 @@ */ public class DefaultShardManagerBuilder { + protected final List listeners = new ArrayList<>(); + protected Map mdcContext = null; protected boolean enableBulkDeleteSplitting = true; protected boolean enableShutdownHook = true; protected boolean enableVoice = true; @@ -54,7 +56,6 @@ public class DefaultShardManagerBuilder protected IntFunction idleProvider = null; protected IntFunction gameProvider = null; protected IntFunction statusProvider = null; - protected final List listeners = new ArrayList<>(); protected Collection shards = null; protected IEventManager eventManager = null; protected ShardedRateLimiter shardedRateLimiter = null; @@ -71,6 +72,27 @@ public class DefaultShardManagerBuilder */ public DefaultShardManagerBuilder() {} + /** + * Sets the {@link org.slf4j.MDC MDC} mappings to use in JDA. + *
If sharding is enabled JDA will automatically add a {@code jda.shard} context with the format {@code [SHARD_ID / TOTAL]} + * where {@code SHARD_ID} and {@code TOTAL} are the shard configuration. + * Additionally it will provide context for the id via {@code jda.shard.id} and the total via {@code jda.shard.total}. + * + *

The manager will create a copy of this map for every JDA instance so it is recommended to use a thread-safe map implementation! + * + * @param map + * The modifiable context map to use in JDA, or {@code null} to reset + * + * @return The {@link net.dv8tion.jda.bot.sharding.DefaultShardManagerBuilder DefaultShardManagerBuilder} instance. Useful for chaining. + * + * @see MDC Javadoc + */ + public DefaultShardManagerBuilder setContextMap(Map map) + { + this.mdcContext = map; + return this; + } + /** * Adds all provided listeners to the list of listeners that will be used to populate the {@link DefaultShardManager DefaultShardManager} object. *
This uses the {@link net.dv8tion.jda.core.hooks.InterfacedEventManager InterfacedEventListener} by default. @@ -149,35 +171,6 @@ public DefaultShardManagerBuilder removeEventListeners(final Collection return this; } - /** - * Builds a new {@link net.dv8tion.jda.bot.sharding.ShardManager ShardManager} instance and uses the provided token to start the login process. - *
The login process runs in a different thread, so while this will return immediately, {@link net.dv8tion.jda.bot.sharding.ShardManager ShardManager} has not - * finished loading, thus many {@link net.dv8tion.jda.bot.sharding.ShardManager ShardManager} methods have the chance to return incorrect information. - *
The main use of this method is to start the JDA connect process and do other things in parallel while startup is - * being performed like database connection or local resource loading. - * - *

Note that this method is async and as such will not block until all shards are started. - * - * @throws LoginException - * If the provided token is invalid. - * @throws IllegalArgumentException - * If the provided token is empty or null. - * - * @return A {@link net.dv8tion.jda.bot.sharding.ShardManager ShardManager} instance that has started the login process. It is unknown as - * to whether or not loading has finished when this returns. - */ - public ShardManager build() throws LoginException, IllegalArgumentException - { - final DefaultShardManager manager = new DefaultShardManager(this.shardsTotal, this.shards, this.listeners, this.token, this.eventManager, - this.audioSendFactory, this.gameProvider, this.statusProvider, this.httpClientBuilder, this.wsFactory, this.threadFactory, this.shardedRateLimiter, - this.maxReconnectDelay, this.corePoolSize, this.enableVoice, this.enableShutdownHook, this.enableBulkDeleteSplitting, - this.autoReconnect, this.idleProvider, this.retryOnTimeout, this.useShutdownNow); - - manager.login(); - - return manager; - } - /** * Enables/Disables Voice functionality. *
This is useful, if your current system doesn't support Voice and you do not need it. @@ -453,7 +446,7 @@ public DefaultShardManagerBuilder setThreadFactory(final ThreadFactory threadFac /** * Sets the {@link okhttp3.OkHttpClient.Builder Builder} that will be used by JDA's requester. - * This can be used to set things such as connection timeout and proxy. + * This can be used to set things such as connection timeout and proxy. * * @param builder * The new {@link okhttp3.OkHttpClient.Builder OkHttpClient.Builder} to use. @@ -695,4 +688,33 @@ public DefaultShardManagerBuilder setWebsocketFactory(WebSocketFactory factory) this.wsFactory = factory; return this; } + + /** + * Builds a new {@link net.dv8tion.jda.bot.sharding.ShardManager ShardManager} instance and uses the provided token to start the login process. + *
The login process runs in a different thread, so while this will return immediately, {@link net.dv8tion.jda.bot.sharding.ShardManager ShardManager} has not + * finished loading, thus many {@link net.dv8tion.jda.bot.sharding.ShardManager ShardManager} methods have the chance to return incorrect information. + *
The main use of this method is to start the JDA connect process and do other things in parallel while startup is + * being performed like database connection or local resource loading. + * + *

Note that this method is async and as such will not block until all shards are started. + * + * @throws LoginException + * If the provided token is invalid. + * @throws IllegalArgumentException + * If the provided token is empty or null. + * + * @return A {@link net.dv8tion.jda.bot.sharding.ShardManager ShardManager} instance that has started the login process. It is unknown as + * to whether or not loading has finished when this returns. + */ + public ShardManager build() throws LoginException, IllegalArgumentException + { + final DefaultShardManager manager = new DefaultShardManager(this.shardsTotal, this.shards, this.listeners, this.token, this.eventManager, + this.audioSendFactory, this.gameProvider, this.statusProvider, this.httpClientBuilder, this.wsFactory, this.threadFactory, this.shardedRateLimiter, + this.maxReconnectDelay, this.corePoolSize, this.enableVoice, this.enableShutdownHook, this.enableBulkDeleteSplitting, + this.autoReconnect, this.idleProvider, this.retryOnTimeout, this.useShutdownNow, this.mdcContext); + + manager.login(); + + return manager; + } } diff --git a/src/main/java/net/dv8tion/jda/core/entities/impl/JDAImpl.java b/src/main/java/net/dv8tion/jda/core/entities/impl/JDAImpl.java index f3ea0d9f1d..3bd33d052a 100644 --- a/src/main/java/net/dv8tion/jda/core/entities/impl/JDAImpl.java +++ b/src/main/java/net/dv8tion/jda/core/entities/impl/JDAImpl.java @@ -53,10 +53,7 @@ import javax.security.auth.login.LoginException; import java.util.*; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; import java.util.stream.Collectors; public class JDAImpl implements JDA @@ -121,7 +118,7 @@ public JDAImpl(AccountType accountType, String token, OkHttpClient.Builder httpC this.bulkDeleteSplittingEnabled = bulkDeleteSplittingEnabled; this.pool = new ScheduledThreadPoolExecutor(corePoolSize, new JDAThreadFactory()); this.maxReconnectDelay = maxReconnectDelay; - this.contextMap = contextMap == null ? new HashMap<>() : contextMap; + this.contextMap = contextMap == null ? new ConcurrentHashMap<>() : contextMap; this.presence = new PresenceImpl(this); this.requester = new Requester(this, rateLimiter);