<commit_before>package stream.flarebot.flarebot.tasks;

import com.arsenarsen.lavaplayerbridge.player.Player;
import net.dv8tion.jda.core.audio.hooks.ConnectionStatus;
import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.Member;
import net.dv8tion.jda.core.entities.VoiceChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import stream.flarebot.flarebot.FlareBot;
import stream.flarebot.flarebot.Getters;
import stream.flarebot.flarebot.metrics.Metrics;
import stream.flarebot.flarebot.scheduler.FlareBotTask;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

public class VoiceChannelCleanup extends FlareBotTask {

    private static final AtomicBoolean ENABLED = new AtomicBoolean(true);

    private static final Logger logger = LoggerFactory.getLogger(VoiceChannelCleanup.class);
    public static final Map<Long, Long> VC_LAST_USED = new HashMap<>();
    private static final long CLEANUP_THRESHOLD = TimeUnit.MINUTES.toMillis(20);

    private static final int WEBSOCKET_THRESHOLD = 50;
    private static final AtomicInteger closedConnections = new AtomicInteger(0);

    public VoiceChannelCleanup(String taskName) {
        super(taskName, TimeUnit.MINUTES.toMillis(20), TimeUnit.MINUTES.toMillis(5));
    }

    @Override
    public void run() {
        if (!ENABLED.get()) {
            cancel();
            return;
        }

        closedConnections.set(0);

        cleanupVoiceChannels();
        try {
            Thread.sleep(60_000); // WebSocket is 120 events in 60 second period. Let's wait till it's reset before possibly sending a large amount more
        } catch (InterruptedException e) {
            logger.error("Failed to sleep till the websocket reset", e);
            return;
        }
        cleanupPlayers();
    }

    private void cleanupVoiceChannels() {
        logger.info("Checking for guilds with an inactive voice channel");
        final AtomicInteger totalGuilds = new AtomicInteger(0);
        final AtomicInteger totalVcs = new AtomicInteger(0);
        final AtomicInteger killedVcs = new AtomicInteger(0);

        Getters.getGuildCache().forEach(guild -> {
            try {
                totalGuilds.incrementAndGet();

                if (guild != null && guild.getSelfMember() != null && guild.getSelfMember().getVoiceState() != null
                        && guild.getSelfMember().getVoiceState().getChannel() != null) {
                    totalVcs.incrementAndGet();

                    VoiceChannel vc = guild.getSelfMember().getVoiceState().getChannel();

                    if (getHumansInChannel(vc) == 0) {
                        killedVcs.incrementAndGet();
                        cleanup(guild, FlareBot.instance().getMusicManager().getPlayer(guild.getId()), vc.getIdLong());
                    } else if (isPlayingMusic(vc)) {
                        VC_LAST_USED.put(vc.getIdLong(), System.currentTimeMillis());
                    } else {
                        if (!VC_LAST_USED.containsKey(vc.getIdLong())) {
                            VC_LAST_USED.put(vc.getIdLong(), System.currentTimeMillis());
                            return;
                        }

                        long lastUsed = VC_LAST_USED.get(vc.getIdLong());

                        if (System.currentTimeMillis() - lastUsed >= CLEANUP_THRESHOLD) {
                            killedVcs.incrementAndGet();
                            cleanup(guild, FlareBot.instance().getMusicManager().getPlayer(guild.getId()), vc.getIdLong());
                        }
                    }
                }
            } catch (Exception e) {
                logger.error("Failed to check {} for inactive voice connection!", guild.getIdLong(), e);
            }
        });

        logger.info("Checked {} guilds for inactive voice channels.", totalGuilds.get());
        logger.info("Killed {} out of {} voice connections!", killedVcs.get(), totalVcs.get());
        Metrics.voiceChannelsCleanedUp.inc(killedVcs.get());
    }

    private void cleanupPlayers() {<commit_msg>Oops, this needs to be per-cleanup not global.<commit_after>package stream.flarebot.flarebot.tasks;

import com.arsenarsen.lavaplayerbridge.player.Player;
import net.dv8tion.jda.core.audio.hooks.ConnectionStatus;
import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.Member;
import net.dv8tion.jda.core.entities.VoiceChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import stream.flarebot.flarebot.FlareBot;
import stream.flarebot.flarebot.Getters;
import stream.flarebot.flarebot.metrics.Metrics;
import stream.flarebot.flarebot.scheduler.FlareBotTask;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

public class VoiceChannelCleanup extends FlareBotTask {

    private static final AtomicBoolean ENABLED = new AtomicBoolean(true);

    private static final Logger logger = LoggerFactory.getLogger(VoiceChannelCleanup.class);
    public static final Map<Long, Long> VC_LAST_USED = new HashMap<>();
    private static final long CLEANUP_THRESHOLD = TimeUnit.MINUTES.toMillis(20);

    private static final int WEBSOCKET_THRESHOLD = 50;
    private static final AtomicInteger closedConnections = new AtomicInteger(0);

    public VoiceChannelCleanup(String taskName) {
        super(taskName, TimeUnit.MINUTES.toMillis(20), TimeUnit.MINUTES.toMillis(5));
    }

    @Override
    public void run() {
        if (!ENABLED.get()) {
            cancel();
            return;
        }

        cleanupVoiceChannels();
        try {
            Thread.sleep(60_000); // WebSocket is 120 events in 60 second period. Let's wait till it's reset before possibly sending a large amount more
        } catch (InterruptedException e) {
            logger.error("Failed to sleep till the websocket reset", e);
            return;
        }
        cleanupPlayers();
    }

    private void cleanupVoiceChannels() {
        closedConnections.set(0);
        logger.info("Checking for guilds with an inactive voice channel");
        final AtomicInteger totalGuilds = new AtomicInteger(0);
        final AtomicInteger totalVcs = new AtomicInteger(0);
        final AtomicInteger killedVcs = new AtomicInteger(0);

        Getters.getGuildCache().forEach(guild -> {
            try {
                totalGuilds.incrementAndGet();

                if (guild != null && guild.getSelfMember() != null && guild.getSelfMember().getVoiceState() != null
                        && guild.getSelfMember().getVoiceState().getChannel() != null) {
                    totalVcs.incrementAndGet();

                    VoiceChannel vc = guild.getSelfMember().getVoiceState().getChannel();

                    if (getHumansInChannel(vc) == 0) {
                        killedVcs.incrementAndGet();
                        cleanup(guild, FlareBot.instance().getMusicManager().getPlayer(guild.getId()), vc.getIdLong());
                    } else if (isPlayingMusic(vc)) {
                        VC_LAST_USED.put(vc.getIdLong(), System.currentTimeMillis());
                    } else {
                        if (!VC_LAST_USED.containsKey(vc.getIdLong())) {
                            VC_LAST_USED.put(vc.getIdLong(), System.currentTimeMillis());
                            return;
                        }

                        long lastUsed = VC_LAST_USED.get(vc.getIdLong());

                        if (System.currentTimeMillis() - lastUsed >= CLEANUP_THRESHOLD) {
                            killedVcs.incrementAndGet();
                            cleanup(guild, FlareBot.instance().getMusicManager().getPlayer(guild.getId()), vc.getIdLong());
                        }
                    }
                }
            } catch (Exception e) {
                logger.error("Failed to check {} for inactive voice connection!", guild.getIdLong(), e);
            }
        });

        logger.info("Checked {} guilds for inactive voice channels.", totalGuilds.get());
        logger.info("Killed {} out of {} voice connections!", killedVcs.get(), totalVcs.get());
        Metrics.voiceChannelsCleanedUp.inc(killedVcs.get());
    }

    private void cleanupPlayers() {
        closedConnections.set(0);
{'fraction_non_alphanumeric': 0.10632523011564786, 'fraction_numerical': 0.0069624734481944775, 'mean_word_length': 2.3859368757491013, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3751776', 'n_tokens_mistral': 2435, 'n_tokens_neox': 2287, 'n_words': 470}