Search code examples
phpcroncommand-line-interfaceat-job

how reliable is "at"


I'm working on a command line scheduler because I need to run several commands a few minutes after each other at different times.

public static function set ($dir, $operation, $arguments = [], $options = [], $timeToWait)
{

    $argumentstring = '';
    $optionstring = '';

    foreach($arguments as $argument)
    {
        $argumentstring .= $argument.' ';
    }

    if ($options) 
    {
        foreach ($options as $key => $option) 
        {
            $optionstring .= '--' . $key . '=\"' . $option . '\" ';
        }
    }

    $command = $operation. ' ' . $argumentstring . ' ' . $optionstring;
    return $string = exec('echo php '.$dir.'/./prices '.$command.' | /usr/bin/at -M now + '.$timeToWait. ' min');
}

Called like

Schedule::set(getcwd(), 'put:acknowledge', ['Customer' => database_connector::getUserId(), 'ReportId' => ReportIdDeclaration::getReportID(), [], 5);

At first, cron runs the first process which thereafter schedules other commands, depending on the API response. I have to run those commands every two minutes, so aswell cron as at are quite often fired. Though I know that cron is working (and the commands in the file are working as supposed when called manually), some of the jobs are failing/not being executed.

As I haven't worked with at with this amount of jobs I'm in question if at is as reliable as I need it to be. Or my code has a lack I don't see.

So that's the point to my question, has at to be considered as reliable on a huge amount of jobs and do I have to control my source code for errors, or is at just not to be considered as reliable enough to work in a purely programaticaly executed environment?


Solution

  • We don't know how reliable you need 'at' to be, however what you describe seems to be something of an anti-pattern for using at.

    If you need the jobs to run in a sequence then then they should be chained in a script with a single entry point.

    While 'at' will typically run tasks with a granularity of 1 second accuracy there are no guarantees over that the task will always be run within 1 second of the schedule. If you need that level of certainty then you need a realtime operating system.

    Some versions of 'cron' and 'at' will not initiate jobs if the load is over a certain threshold. Apart from that scenario, I've never known 'at' to accept a job which wasn't (eventually) run by atd.

    Of course, more recent systems may not be using atd and crond - systemd has support for this functionality (whether that works and whether it is a good idea is a very long argument).

    The code you've shown us here doesn't check for a return code from invoking 'at'.