<commit_before><?php

namespace CronModule\Service;

use Cron\Cron;
use Cron\Job\ShellJob;
use Cron\Resolver\ArrayResolver;
use Cron\Schedule\CrontabSchedule;
use CronModule\Configuration;
use CronModule\Exception\TimeoutException;
use CronModule\Executor\Executor;

class CronService
{
    /**
     * @var Configuration
     */
    protected $configuration = null;

    /**
     * @var ArrayResolver
     */
    protected $resolver = null;

    /**
     * @var Cron
     */
    protected $cron = null;

    /**
     * @var Executor
     */
    protected $executor = null;

    /**
     * @var int
     */
    protected $startTime = null;

    public function __construct(Configuration $configuration)
    {
        $this->setConfiguration($configuration);
    }

    public function setConfiguration(Configuration $configuration)
    {
        $this->configuration = $configuration;

        return $this;
    }

    public function run()
    {
        $this->initResolver();
        $this->initExecutor();
        $this->initCron();
        $this->addJobs();

        $this->startTime = time();

        $this->cron->run();
        $this->wait();
        $this->throwErrorIfTimeout();
    }

    protected function initResolver()
    {
        $this->resolver = new ArrayResolver();
    }

    protected function initExecutor()
    {
        $this->executor = new Executor();
    }

    protected function initCron()
    {
        $this->cron = new Cron();
        $this->cron->setResolver($this->resolver);
        $this->cron->setExecutor($this->executor);
    }

    protected function addJobs()
    {
        foreach ($this->configuration->getJobs() as $jobArray) {
            $job = new ShellJob();
            $job->setCommand($this->assembleShellJobString($jobArray['command']));
            $job->setSchedule(new CrontabSchedule($jobArray['schedule']));

            $this->resolver->addJob($job);
        }
    }

    protected function assembleShellJobString($command)
    {
        return $this->configuration->getPhpPath() . ' ' . $this->configuration->getScriptPath() . $command;
    }

    protected function wait()
    {
        while ($this->cron->isRunning() && $this->checkTimeout()) {
            sleep(1);
        }
    }

    protected function checkTimeout()
    {
        $timeout = $this->configuration->getTimeout();
        if ($timeout !== null && $timeout > (time() - $this->startTime)) {
            return false;
        }

        return true;
    }

    protected function throwErrorIfTimeout()
    {
        if ($this->checkTimeout()) {

            $this->executor->getRunningJobs();

            throw new TimeoutException();
        }
    }

    protected function assembleErrorString()
    {
        $string = 'Jobs: ';
        $i = 1;
        foreach ($this->executor->getRunningJobs() as $job) {
            $string .= $i . '. ' . $job->getProcess()->getCommandLine() . ' ';
            $i++;
        }

        return $string . ' have taken over ' . $this->configuration->getTimeout() . ' seconds to execute.';
    }
}<commit_msg>Fixes for timeout<commit_after><?php

namespace CronModule\Service;

use Cron\Cron;
use Cron\Job\ShellJob;
use Cron\Resolver\ArrayResolver;
use Cron\Schedule\CrontabSchedule;
use CronModule\Configuration;
use CronModule\Exception\TimeoutException;
use CronModule\Executor\Executor;

class CronService
{
    /**
     * @var Configuration
     */
    protected $configuration = null;

    /**
     * @var ArrayResolver
     */
    protected $resolver = null;

    /**
     * @var Cron
     */
    protected $cron = null;

    /**
     * @var Executor
     */
    protected $executor = null;

    /**
     * @var int
     */
    protected $startTime = null;

    public function __construct(Configuration $configuration)
    {
        $this->setConfiguration($configuration);
    }

    public function setConfiguration(Configuration $configuration)
    {
        $this->configuration = $configuration;

        return $this;
    }

    public function run()
    {
        $this->initResolver();
        $this->initExecutor();
        $this->initCron();
        $this->addJobs();

        $this->startTime = time();

        $this->cron->run();
        $this->wait();
        $this->throwErrorIfTimeout();
    }

    protected function initResolver()
    {
        $this->resolver = new ArrayResolver();
    }

    protected function initExecutor()
    {
        $this->executor = new Executor();
    }

    protected function initCron()
    {
        $this->cron = new Cron();
        $this->cron->setResolver($this->resolver);
        $this->cron->setExecutor($this->executor);
    }

    protected function addJobs()
    {
        foreach ($this->configuration->getJobs() as $jobArray) {
            $job = new ShellJob();
            $job->setCommand($this->assembleShellJobString($jobArray['command']));
            $job->setSchedule(new CrontabSchedule($jobArray['schedule']));

            $this->resolver->addJob($job);
        }
    }

    protected function assembleShellJobString($command)
    {
        return $this->configuration->getPhpPath() . ' ' . $this->configuration->getScriptPath() . $command;
    }

    protected function wait()
    {
        do  {
            sleep(1);
        }
        while ($this->cron->isRunning() && !$this->checkTimeout());
    }

    protected function checkTimeout()
    {
        $timeout = $this->configuration->getTimeout();
        if ($timeout !== null && $timeout > (time() - $this->startTime)) {
            return false;
        }

        return true;
    }

    protected function throwErrorIfTimeout()
    {
        if ($this->checkTimeout()) {
            throw new TimeoutException($this->assembleErrorString());
        }
    }

    protected function assembleErrorString()
    {
        $string = 'Jobs: ';
        $i = 1;
        foreach ($this->executor->getRunningJobs() as $job) {
            $string .= $i . '. ' . $job->getProcess()->getCommandLine() . ' ';
            $i++;
        }

        return $string . ' have taken over ' . $this->configuration->getTimeout() . ' seconds to execute.';
    }
}
{'fraction_non_alphanumeric': 0.14667100765098487, 'fraction_numerical': 0.0006511476477291225, 'mean_word_length': 2.162120432321153, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 96, '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': '115930', 'n_tokens_mistral': 1783, 'n_tokens_neox': 1709, 'n_words': 332}