<commit_before>package io.ifar.skidroad.prepping;

import io.ifar.skidroad.LogFile;
import io.ifar.skidroad.tracking.LogFileTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.Callable;

/**
 * Provides standard LogFileTracker interaction.
 */
public abstract class AbstractPrepWorker implements Callable<Boolean> {

    private final static Logger LOG = LoggerFactory.getLogger(AbstractPrepWorker.class);
    protected final LogFile logFile;
    protected final LogFileTracker tracker;

    protected AbstractPrepWorker(LogFile logFile, LogFileTracker tracker) {
        this.logFile = logFile;
        this.tracker = tracker;
    }

    @Override
    public Boolean call() throws Exception {
        try {
            if (tracker.preparing(logFile) != 1)
                throw new IllegalStateException("Cannot place " + logFile + " into into PREPARING state.");

            final Path inputPath = logFile.getPrepPath() == null ? logFile.getOriginPath() : logFile.getPrepPath();
            logFile.setPrepPath(prepare(inputPath));
            if (tracker.updatePrepPath(logFile) != 1)
                throw new IllegalStateException("Cannot set prep path for " + logFile);


            LOG.debug("Prepared {} to {}", logFile, logFile.getPrepPath());
            tracker.prepared(logFile); //ignore update failures; worker exiting anyway
            return Boolean.TRUE;
        } catch (Exception e) {
            LOG.warn("Preparation for {} failed.", logFile, e);
            tracker.prepError(logFile); //ignore update failures; worker exiting anyway
            throw e;
        }
    }<commit_msg>Fix double-prepare bug when LogFile records are manually moved back to WRITTEN state.<commit_after>package io.ifar.skidroad.prepping;

import io.ifar.skidroad.LogFile;
import io.ifar.skidroad.tracking.LogFileTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.Callable;

/**
 * Provides standard LogFileTracker interaction.
 */
public abstract class AbstractPrepWorker implements Callable<Boolean> {

    private final static Logger LOG = LoggerFactory.getLogger(AbstractPrepWorker.class);
    protected final LogFile logFile;
    protected final LogFileTracker tracker;

    protected AbstractPrepWorker(LogFile logFile, LogFileTracker tracker) {
        this.logFile = logFile;
        this.tracker = tracker;
    }

    @Override
    public Boolean call() throws Exception {
        try {
            if (tracker.preparing(logFile) != 1)
                throw new IllegalStateException("Cannot place " + logFile + " into into PREPARING state.");

            logFile.setPrepPath(prepare(logFile.getOriginPath()));
            if (tracker.updatePrepPath(logFile) != 1)
                throw new IllegalStateException("Cannot set prep path for " + logFile);

            LOG.debug("Prepared {} to {}", logFile, logFile.getPrepPath());
            tracker.prepared(logFile); //ignore update failures; worker exiting anyway
            return Boolean.TRUE;
        } catch (Exception e) {
            LOG.warn("Preparation for {} failed.", logFile, e);
            tracker.prepError(logFile); //ignore update failures; worker exiting anyway
            throw e;
        }
    }
{'fraction_non_alphanumeric': 0.09647824800236757, 'fraction_numerical': 0.0023675643681562593, 'mean_word_length': 2.990554899645809, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '7393698', 'n_tokens_mistral': 954, 'n_tokens_neox': 898, 'n_words': 239}