Skip to content

Commit db1601d

Browse files
committed
Cache expiration bug fixes and improved factory usage.
1 parent 8c0f3d9 commit db1601d

12 files changed

+88
-85
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# [ID Bot](https://github.com/chrisdenman/id-bot) 0.0.3
1+
# [ID Bot](https://github.com/chrisdenman/id-bot) 0.0.4
22
33
![An stylised image of the project's logo formed of a lower-case i cursively joining a capitalised D](res/img/id-gum-logo.png)
44

VERSIONS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@
55
0.0.2 - `Functionality added to require the identification of emoji and custom (Discord) emoji.`
66

77
0.0.3 - `Cache expiration management.`
8+
9+
0.0.4 - `Cache expiration bug fixes and improved factory usage.`

package-lock.json

Lines changed: 5 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ceilingcat/id-bot",
3-
"version": "0.0.3",
3+
"version": "0.0.4",
44
"description": "A discord bot to remind users to tag uploaded images with identifiers.",
55
"scripts": {
66
"lint": "eslint \"src/*/*.js\"",

src/__tests__/cache.spec.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ describe("Tests for our Cache", () => {
5151
});
5252

5353
it("Newly added cache entries have a 'createdAt' value greater or equal than that sampled before population.", () => {
54-
const then = factory.utcTimeStampNow;
54+
const then = factory.getNowInMilliSeconds;
5555

5656
const meta = setK0V0().getMeta(k0);
5757

@@ -64,7 +64,7 @@ describe("Tests for our Cache", () => {
6464

6565
expect(metaBefore.lastAccessedAt).toEqual(metaBefore.createdAt);
6666

67-
const then = factory.utcTimeStampNow;
67+
const then = factory.getNowInMilliSeconds;
6868
cache.get(k0);
6969
const metaAfter = cache.getMeta(k0);
7070

@@ -78,7 +78,7 @@ describe("Tests for our Cache", () => {
7878

7979
expect(metaBefore.lastUpdatedAt).toBeUndefined();
8080

81-
const then = factory.utcTimeStampNow;
81+
const then = factory.getNowInMilliSeconds;
8282
cache.set(k0, newValue);
8383
const metaAfter = cache.getMeta(k0);
8484

src/js/cache-max-stale-manager.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,12 @@ class CacheMaxStaleManager {
6363
}
6464

6565
#expireStaleCacheEntries() {
66-
const NOW = this.#factory.utcTimeStampNow;
67-
66+
const NOW = this.#factory.getNowInMilliSeconds;
6867
[...this.#cache.metaData]
69-
.filter(it => it.lastAccessedAt + this.#maxStaleLifetimeMilliSeconds > NOW)
70-
.map(it => it.key)
68+
.filter(it => NOW - it.lastAccessedAt > this.#maxStaleLifetimeMilliSeconds)
7169
.map(it => {
72-
this.#cache.remove(it);
73-
this.#logger.debug(`Expired key @ ${NOW}`);
70+
this.#cache.remove(it.key);
71+
this.#logger.debug(`Expired key ${it.key}`);
7472
});
7573
}
7674

src/js/cache.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class Cache {
4545
const value = this.#keyToValue.get(key);
4646

4747
this.#keyToMetaData.set(key, this.#factory.withCacheAccess(this.#keyToMetaData.get(key)));
48-
this.#logger.debug(`<[${key}]`);
48+
this.#logger.debug(`<[${key}=${value}]`);
4949

5050
return value;
5151
} else {

src/js/discord-interface.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,25 +98,22 @@ class DiscordInterface {
9898
/**
9999
* @param {IdBotMessage} received
100100
* @param {string} content
101+
* @return Promise<Message>
101102
*/
102-
replyTo(received, content) {
103+
async replyTo(received, content) {
103104
this._logger.debug(`sending reply to ${received.id} with "${content}"`);
104-
received.reply(content);
105-
}
106-
107-
update = (message, content) => message
108-
.edit(content)
109-
.then(updatedMessage => this._logger.log(`Updated ${message.id} to "${updatedMessage.content}"`))
110-
.catch(e => this._logger.error(`could not delete reply with id=${message.id}`, e));
111105

106+
return received.discordJsMessage.reply(content);
107+
}
112108

113109
/**
114110
* @param {Channel} channel
115111
* @param messageId
116112
*/
117113
deleteMessage(channel, messageId) {
118114
this._logger.debug(`attempting to delete replies to message with id=${messageId}`);
119-
channel
115+
116+
return channel
120117
.messages
121118
.delete(messageId)
122119
.then(() => this._logger.debug(`deleted reply with id=${messageId}`))

src/js/factory.js

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import {GatewayIntentBits} from "discord-api-types/v10";
99
import {DiscordInterface} from "./discord-interface.js";
1010
import {Application} from "./application.js";
1111
import {CacheMaxStaleManager} from "./cache-max-stale-manager.js";
12+
import {numberOfEmojiContained} from "./emoji.js";
13+
import {isImageMediaType} from "./media-type.js";
1214

1315
const CLIENT_OPTIONS = {
1416
intents: [
@@ -20,6 +22,16 @@ const CLIENT_OPTIONS = {
2022

2123
class Factory {
2224

25+
/**
26+
* @type RegExp
27+
*/
28+
#MESSAGE_ID_REGEXP = /(?<=(^|\s|\W)ID:\s*)(\w+)(?!\WID:)/svg;
29+
30+
/**
31+
* @type RegExp
32+
*/
33+
#CUSTOM_EMOJI_REGEX = /<(a)?:(?<name>\w+):(?<id>\d+)>/g;
34+
2335
static get #CLIENT_OPTIONS() {
2436
return CLIENT_OPTIONS;
2537
}
@@ -33,7 +45,8 @@ class Factory {
3345
*/
3446
createCacheExpirator(cache, tickIntervalDurationMilliSeconds = 100, maxStaleLifetimeMilliSeconds = undefined) {
3547
return new CacheMaxStaleManager(
36-
cache, this.createLogger("MaxStaleCacheManager"),
48+
cache,
49+
this.createLogger("MaxStaleCacheManager"),
3750
this,
3851
tickIntervalDurationMilliSeconds,
3952
maxStaleLifetimeMilliSeconds
@@ -96,16 +109,37 @@ class Factory {
96109
*
97110
* @returns {number}
98111
*/
99-
get utcTimeStampNow() {
100-
return new Date().getUTCMilliseconds();
112+
get getNowInMilliSeconds() {
113+
return Date.now();
101114
}
102115

103116
/**
104117
*
105118
* @param discordJsMessage
106119
* @returns {IdBotMessage}
107120
*/
108-
createIdBotMessage = discordJsMessage => new IdBotMessage(this, discordJsMessage);
121+
createIdBotMessage = discordJsMessage => {
122+
const content = discordJsMessage.content;
123+
124+
const contentCustomEmojiMatches = [...content.matchAll(this.#CUSTOM_EMOJI_REGEX)];
125+
126+
const contentStrippedOfCustomEmoji = content.replaceAll(this.#CUSTOM_EMOJI_REGEX, "");
127+
const numberOfEmoji = numberOfEmojiContained(contentStrippedOfCustomEmoji);
128+
129+
const idMatches = [...content.matchAll(this.#MESSAGE_ID_REGEXP)];
130+
131+
const imageIdStats = this.createImageIdStats(
132+
[...discordJsMessage.attachments.values()]
133+
.map(v => v.contentType)
134+
.filter(isImageMediaType)
135+
.length,
136+
numberOfEmoji,
137+
contentCustomEmojiMatches.length,
138+
idMatches.length
139+
);
140+
141+
return new IdBotMessage(imageIdStats, discordJsMessage);
142+
};
109143

110144
/**
111145
* @param {string} [prefix]
@@ -119,23 +153,23 @@ class Factory {
119153
* @returns {CacheMeta}
120154
*/
121155
createCacheMeta = key => {
122-
const now = this.utcTimeStampNow;
123-
156+
const now = this.getNowInMilliSeconds;
157+
124158
return new CacheMeta(key, now, now);
125159
};
126-
160+
127161
withCacheAccess = cacheMeta => new CacheMeta(
128162
cacheMeta.key,
129163
cacheMeta.createdAt,
130-
this.utcTimeStampNow,
164+
this.getNowInMilliSeconds,
131165
cacheMeta.lastUpdatedAt
132166
);
133167

134168
withUpdate = cacheMeta => new CacheMeta(
135169
cacheMeta.key,
136170
cacheMeta.createdAt,
137171
cacheMeta.lastAccessedAt,
138-
this.utcTimeStampNow
172+
this.getNowInMilliSeconds
139173
);
140174

141175
/**

src/js/id-bot-message.js

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import {isImageMediaType} from "./media-type.js";
2-
import {numberOfEmojiContained} from "./emoji.js";
3-
41
/**
52
* @typedef {typeof import('./image-id-stats.js')['ImageIdStats']} ImageIdStats
63
* @typedef {typeof import('discord.js')['Snowflake']} Snowflake
@@ -17,21 +14,16 @@ class IdBotMessage {
1714
*/
1815
#imageIdStats;
1916

20-
/**
21-
* @type RegExp
22-
*/
23-
#MESSAGE_ID_REGEXP = /(?<=(^|\s|\W)ID:\s*)(\w+)(?!\WID:)/svg;
24-
25-
/**
26-
* @type RegExp
27-
*/
28-
#CUSTOM_EMOJI_REGEX = /<(a)?:(?<name>\w+):(?<id>\d+)>/g;
2917

3018
/**
3119
* @type Message
3220
*/
3321
#discordJsMessage;
3422

23+
get discordJsMessage() {
24+
return this.#discordJsMessage;
25+
}
26+
3527
get id() {
3628
return this.#discordJsMessage.id;
3729
}
@@ -49,12 +41,6 @@ class IdBotMessage {
4941
return this.#discordJsMessage.content;
5042
}
5143

52-
/**
53-
* @param {string} content
54-
*/
55-
reply(content) {
56-
return this.#discordJsMessage.reply(content);
57-
}
5844

5945
/**
6046
* @param {Snowflake} authorId
@@ -107,29 +93,12 @@ class IdBotMessage {
10793
}
10894

10995
/**
110-
* @param {Factory} factory
96+
* @param {ImageIdStats} imageIdStats
11197
* @param {Message} discordJsMessage the discord.js sourced discordJsMessage
11298
*/
113-
constructor(factory, discordJsMessage) {
99+
constructor(imageIdStats, discordJsMessage) {
114100
this.#discordJsMessage = discordJsMessage;
115-
116-
const content = discordJsMessage.content;
117-
const contentCustomEmojiMatches = [...content.matchAll(this.#CUSTOM_EMOJI_REGEX)];
118-
119-
const contentStrippedOfCustomEmoji = content.replaceAll(this.#CUSTOM_EMOJI_REGEX, "");
120-
const numberOfEmoji = numberOfEmojiContained(contentStrippedOfCustomEmoji);
121-
122-
const idMatches = [...content.matchAll(this.#MESSAGE_ID_REGEXP)];
123-
124-
this.#imageIdStats = factory.createImageIdStats(
125-
[...discordJsMessage.attachments.values()]
126-
.map(v => v.contentType)
127-
.filter(isImageMediaType)
128-
.length,
129-
numberOfEmoji,
130-
contentCustomEmojiMatches.length,
131-
idMatches.length
132-
);
101+
this.#imageIdStats = imageIdStats;
133102
}
134103
}
135104

0 commit comments

Comments
 (0)