<commit_before>package top.quantic.sentry.job;

import com.codahale.metrics.Gauge;
import com.codahale.metrics.MetricRegistry;
import com.ibasco.agql.protocols.valve.steam.webapi.pojos.SteamPlayerProfile;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import top.quantic.sentry.service.GameQueryService;

import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class SteamProfilePoller implements Job {

    private static final Logger log = LoggerFactory.getLogger(SteamProfilePoller.class);

    @Autowired
    private GameQueryService gameQueryService;

    @Autowired
    private MetricRegistry metricRegistry;

    private final Map<Long, SteamPlayerProfile> profileMap = new ConcurrentHashMap<>();

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        JobDataMap dataMap = context.getMergedJobDataMap();
        String keys = dataMap.getString("keys");
        if (keys == null) {
            throw new JobExecutionException("Data map key 'keys' is missing");
        }

        Set<Long> checked = new LinkedHashSet<>();

        for (String key : keys.split(";")) {
            Long id = gameQueryService.getSteamId64(key).exceptionally(t -> {
                log.warn("Could not get profile ID from key {}", key, t);
                return null;
            }).join();
            if (id != null) {
                profileMap.remove(id);
                registerGauges(id);
                checked.add(id);
            }
        }

        // clean up removed ids
        metricRegistry.removeMatching((name, metric) -> name.startsWith("steam.profile") && !checked.contains(extractId(name)));
    }

    private Long extractId(String name) {
        return Long.valueOf(name.replaceAll("^steam\\.profile\\..+\\[steamId:([0-9]+)]$", "$1"));
    }

    private void registerGauges(Long id) {
        if (metricRegistry.getGauges((name, metric) -> name.contains("steamId:" + id)).isEmpty()) {
            metricRegistry.register("steam.profile.status[steamId:" + id + "]", (Gauge<Integer>) () -> profileMap.computeIfAbsent(id, this::getPlayerProfile).getPersonaState());
            metricRegistry.register("steam.profile.lastLogOff[steamId:" + id + "]", (Gauge<Long>) () -> profileMap.computeIfAbsent(id, this::getPlayerProfile).getLastLogOff());
        }
    }

    private SteamPlayerProfile getPlayerProfile(Long id) {
        return gameQueryService.getPlayerProfile(id).exceptionally(t -> {
            log.warn("Could not retrieve profile info for {}", id, t);
            SteamPlayerProfile dummy = new SteamPlayerProfile();
            dummy.setPersonaState(0);
            dummy.setLastLogOff(0);
            return dummy;
        }).join();
    }
}<commit_msg>Fix usage of cached profiles<commit_after>package top.quantic.sentry.job;

import com.codahale.metrics.Gauge;
import com.codahale.metrics.MetricRegistry;
import com.ibasco.agql.protocols.valve.steam.webapi.pojos.SteamPlayerProfile;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import top.quantic.sentry.service.GameQueryService;

import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class SteamProfilePoller implements Job {

    private static final Logger log = LoggerFactory.getLogger(SteamProfilePoller.class);

    @Autowired
    private GameQueryService gameQueryService;

    @Autowired
    private MetricRegistry metricRegistry;

    private final Map<Long, SteamPlayerProfile> profileMap = new ConcurrentHashMap<>();

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        JobDataMap dataMap = context.getMergedJobDataMap();
        String keys = dataMap.getString("keys");
        if (keys == null) {
            throw new JobExecutionException("Data map key 'keys' is missing");
        }

        Set<Long> checked = new LinkedHashSet<>();

        for (String key : keys.split(";")) {
            Long id = gameQueryService.getSteamId64(key).exceptionally(t -> {
                log.warn("Could not get profile ID from key {}", key, t);
                return null;
            }).join();
            if (id != null) {
                profileMap.put(id, getPlayerProfile(id));
                registerGauges(id);
                checked.add(id);
            }
        }

        // clean up removed ids
        metricRegistry.removeMatching((name, metric) -> name.startsWith("steam.profile") && !checked.contains(extractId(name)));
    }

    private Long extractId(String name) {
        return Long.valueOf(name.replaceAll("^steam\\.profile\\..+\\[steamId:([0-9]+)]$", "$1"));
    }

    private void registerGauges(Long id) {
        if (metricRegistry.getGauges((name, metric) -> name.contains("steamId:" + id)).isEmpty()) {
            metricRegistry.register("steam.profile.status[steamId:" + id + "]", (Gauge<Integer>) () -> profileMap.get(id).getPersonaState());
            metricRegistry.register("steam.profile.lastLogOff[steamId:" + id + "]", (Gauge<Long>) () -> profileMap.get(id).getLastLogOff());
        }
    }

    private SteamPlayerProfile getPlayerProfile(Long id) {
        return gameQueryService.getPlayerProfile(id).exceptionally(t -> {
            log.warn("Could not retrieve profile info for {}", id, t);
            SteamPlayerProfile dummy = new SteamPlayerProfile();
            dummy.setPersonaState(0);
            dummy.setLastLogOff(0);
            return dummy;
        }).join();
    }
}
{'fraction_non_alphanumeric': 0.1247911794186435, 'fraction_numerical': 0.003007016371533578, 'mean_word_length': 3.106310013717421, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 27, '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': '5998677', 'n_tokens_mistral': 1715, 'n_tokens_neox': 1695, 'n_words': 339}