Skip to content

Commit 5e685fb

Browse files
authored
Merge pull request #41 from acmucsd/aaron/challenge-refresh
debounced challenge channel updates
2 parents eec8147 + 5cc3829 commit 5e685fb

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

src/discord/events/interaction/commands/submit.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ApplicationCommandOptionTypes } from 'discord.js/typings/enums';
22
import { ChatInputCommandDefinition, PopulatedCommandInteraction } from '../interaction';
33
import { getCtfByGuildContext } from '../../../util/ResourceManager';
4+
import { debounceChallengeChannelUpdates } from '../../../util/UpdateDebouncer';
45

56
export default {
67
name: 'submit',
@@ -18,7 +19,12 @@ export default {
1819
const ctf = await getCtfByGuildContext(interaction.guild);
1920
if (!ctf) throw new Error('this guild does not belong to a ctf');
2021

21-
const flag = ctf.getFlag(interaction.options.getString('flag', true));
22+
const flag = await ctf.getFlag(interaction.options.getString('flag', true));
23+
if (!flag) throw new Error('Invalid flag. Checking for trailing spaces and typos.');
24+
const challenge = await flag.getChallenge();
25+
26+
// update the challenge channels, but in a debounced fashion
27+
debounceChallengeChannelUpdates(challenge, interaction.client);
2228

2329
return 'to be implemented';
2430
},

src/discord/events/interaction/interaction.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
Client,
66
CommandInteraction,
77
Interaction,
8-
UserContextMenuInteraction,
98
} from 'discord.js';
109
import { category, challenge, ctf } from './commands';
1110
import { embedify, logger } from '../../../log';
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Challenge } from '../../database/models/Challenge';
2+
import { refreshChallenge } from "../hooks/ChallengeHooks";
3+
import { Client } from "discord.js";
4+
5+
// a hashmap from challenge ids to their timeout ID
6+
const mapping = new Map<number, NodeJS.Timeout>();
7+
8+
// this function will trigger an update to challenge channels... but no more than
9+
// once every two minutes
10+
export function debounceChallengeChannelUpdates(challenge: Challenge, client: Client<true>) {
11+
const timeout = mapping.get(challenge.id);
12+
13+
// if there's currently a timeout for this challenge, just ignore for now
14+
if (timeout) return;
15+
16+
// otherwise, kick off the update to happen in two minutes
17+
mapping.set(
18+
challenge.id,
19+
setTimeout(() => {
20+
mapping.delete(challenge.id);
21+
void refreshChallenge(challenge, client);
22+
}, 1000 * 120),
23+
);
24+
}

0 commit comments

Comments
 (0)