From 3725dcafc0cbb4a40d3ff66d2a9718e986f47c5b Mon Sep 17 00:00:00 2001 From: ckohen Date: Fri, 6 Aug 2021 05:54:19 -0700 Subject: [PATCH] fix(Caching): sweep archived threads in all channel caches (#6312) --- src/managers/ChannelManager.js | 6 +++++- src/managers/GuildChannelManager.js | 6 +++++- src/util/LimitedCollection.js | 2 +- src/util/Options.js | 14 ++++++++++---- src/util/Util.js | 15 +++++++++++++++ typings/index.d.ts | 1 + 6 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/managers/ChannelManager.js b/src/managers/ChannelManager.js index 55ac5fff64ff..1925abdebf02 100644 --- a/src/managers/ChannelManager.js +++ b/src/managers/ChannelManager.js @@ -13,7 +13,11 @@ let cacheWarningEmitted = false; class ChannelManager extends CachedManager { constructor(client, iterable) { super(client, Channel, iterable); - if (!cacheWarningEmitted && this._cache.constructor.name !== 'Collection') { + const defaultCaching = + this._cache.constructor.name === 'Collection' || + ((this._cache.maxSize === undefined || this._cache.maxSize === Infinity) && + (this._cache.sweepFilter === undefined || this._cache.sweepFilter.isDefault)); + if (!cacheWarningEmitted && !defaultCaching) { cacheWarningEmitted = true; process.emitWarning( `Overriding the cache handling for ${this.constructor.name} is unsupported and breaks functionality.`, diff --git a/src/managers/GuildChannelManager.js b/src/managers/GuildChannelManager.js index 36c190af0be1..35e90827f84e 100644 --- a/src/managers/GuildChannelManager.js +++ b/src/managers/GuildChannelManager.js @@ -18,7 +18,11 @@ let cacheWarningEmitted = false; class GuildChannelManager extends CachedManager { constructor(guild, iterable) { super(guild.client, GuildChannel, iterable); - if (!cacheWarningEmitted && this._cache.constructor.name !== 'Collection') { + const defaultCaching = + this._cache.constructor.name === 'Collection' || + ((this._cache.maxSize === undefined || this._cache.maxSize === Infinity) && + (this._cache.sweepFilter === undefined || this._cache.sweepFilter.isDefault)); + if (!cacheWarningEmitted && !defaultCaching) { cacheWarningEmitted = true; process.emitWarning( `Overriding the cache handling for ${this.constructor.name} is unsupported and breaks functionality.`, diff --git a/src/util/LimitedCollection.js b/src/util/LimitedCollection.js index f8ed977bac21..20b4d1fb64f3 100644 --- a/src/util/LimitedCollection.js +++ b/src/util/LimitedCollection.js @@ -15,7 +15,7 @@ const { TypeError } = require('../errors/DJSError.js'); /** * Options for defining the behavior of a LimitedCollection * @typedef {Object} LimitedCollectionOptions - * @property {?number} [maxSize=0] The maximum size of the Collection + * @property {?number} [maxSize=Infinity] The maximum size of the Collection * @property {?Function} [keepOverLimit=null] A function, which is passed the value and key of an entry, ran to decide * to keep an entry past the maximum size * @property {?SweepFilter} [sweepFilter=null] A function ran every `sweepInterval` to determine how to sweep diff --git a/src/util/Options.js b/src/util/Options.js index eb890a2d9a8f..23a0cfde5d09 100644 --- a/src/util/Options.js +++ b/src/util/Options.js @@ -104,12 +104,17 @@ class Options extends null { shardCount: 1, makeCache: this.cacheWithLimits({ MessageManager: 200, + ChannelManager: { + sweepInterval: 3600, + sweepFilter: require('./Util').archivedThreadSweepFilter(), + }, + GuildChannelManager: { + sweepInterval: 3600, + sweepFilter: require('./Util').archivedThreadSweepFilter(), + }, ThreadManager: { sweepInterval: 3600, - sweepFilter: require('./LimitedCollection').filterByLifetime({ - getComparisonTimestamp: e => e.archiveTimestamp, - excludeFromSweep: e => !e.archived, - }), + sweepFilter: require('./Util').archivedThreadSweepFilter(), }, }), messageCacheLifetime: 0, @@ -154,6 +159,7 @@ class Options extends null { * @returns {CacheFactory} * @example * // Store up to 200 messages per channel and discard archived threads if they were archived more than 4 hours ago. + * // Note archived threads will remain in the guild and client caches with these settings * Options.cacheWithLimits({ * MessageManager: 200, * ThreadManager: { diff --git a/src/util/Util.js b/src/util/Util.js index 4f7561f08b70..1865d6b889ce 100644 --- a/src/util/Util.js +++ b/src/util/Util.js @@ -635,6 +635,21 @@ class Util extends null { setTimeout(resolve, ms); }); } + + /** + * Creates a sweep filter that sweeps archived threads + * @param {number} [lifetime=14400] How long a thread has to be archived to be valid for sweeping + * @returns {SweepFilter} + */ + static archivedThreadSweepFilter(lifetime = 14400) { + const filter = require('./LimitedCollection').filterByLifetime({ + lifetime, + getComparisonTimestamp: e => e.archiveTimestamp, + excludeFromSweep: e => !e.archived, + }); + filter.isDefault = true; + return filter; + } } module.exports = Util; diff --git a/typings/index.d.ts b/typings/index.d.ts index fc539f286266..a7ae474076b3 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1852,6 +1852,7 @@ export class UserFlags extends BitField { export class Util extends null { private constructor(); + public static archivedThreadSweepFilter(lifetime?: number): SweepFilter; public static basename(path: string, ext?: string): string; public static binaryToId(num: string): Snowflake; public static cleanContent(str: string, channel: Channel): string;