TiBeN/CrontabManager

Contab recreate after disable

mdtuyen opened this issue · 6 comments

I want to use crontab to make multi progress so that with each task I only run script in scrontab once.

Example:

I run function A in script A.php with scrontab have comment is A_Comment

function A(){
        disableCronJob(A_Comment)
}

That mean cronjob A_Comment never recall so that function A never recall. But I see that it still recall.

Detail of my code:

    public static function disableCronJob($name, $exact = true)
    {
        $results = $GLOBALS['appcron']->findJobByRegex($exact ? '/#' . $name . '$/' : '/' . $name . '/');
        if (count($results) == 0) {
            self::log("There are not CRON " . $name);
        } else {
            $crontabJob = $results[0];
            $crontabJob->enabled = false;
            $GLOBALS['appcron']->persist();
            self::log("[".getmypid()."] CRON " . $name . " disabled");
        }
    }

Here is function in script call by crontab

function getFeed(\InstagramAPI\Instagram $i, $condition, $type, $min_timestamp = null)
{
    $name = $i->username . ":" . $type . ":" . __FUNCTION__;
    \Ezgram\Utils::disableCronJob($name);
    // PROCESS 
    OUT:
    \Ezgram\Utils::log("[$name] Done and stop");
    \Ezgram\Utils::stopCronJob($name);
}

TiBeN commented

Hi,
Here is what i understood please correct me if i'm wrong.
You have trouble to disable a Cronjob right ?

Can you post the raw content of your crontab, before and after the execution of your code ?
(type crontab -l on a terminal using the same unix user as your script)

Hi, I think the problem because conflict when many process access Crontab.
I see that persist() function will collage all cronjob manage by crontabJobs list and rewrite. If many thread call this function conflict will occur.

TiBeN commented

CrontabRepository class is, like others Repository classes, a service class. It is not intended to be instantiated many times. You should instanciate it once and pass this instance all over the places where you need it in your code. A Dependency injection mechanism is well suited for that.

Concurrent accesses to the underlying crontab (ie by other processes/threads) is not supported and out of the scope of CrontabManager. It is up to you to prevent this to occur.

I have not thought about it but maybe a locking mechanism could be implemented. Contributions are welcome :)

Yest, I think too
But because CrontabRepository only instance once and in script there are many command to edit cronjob so that If when script running other project or user add, remove or delete their cronjob then my script modify it will undo all action of other person (they not use CrontabRepository to manage cronjob)

TiBeN commented

As i said, CrontabManager does not offer any lock/sync mechanism across instances nor has any visibility about externals processes accessing the crontab.

UNIX Cron in itself doesn't seems to offer locking/syncronize mechanism. You can observe that by launching at the same times "crontab -e" in two differents terminals. You'll realize that the last saved will erase any possible modifications made by the first in between.
I think it is because a crontab is attached to only one UNIX user so it has not been designed to be accessed by many users at the same time.

Now, considering CrontabManager a simple frontend of Cron, it can't offer features that the underlaying cron system doesn't support in itself.

I have no clue about your project, but here some tips which maybe could help you to achieve what you want:

  • You can implement some kind of lock each time a crontabManager instance is in use to prevent any other use. Release the lock when the CrontabManager session is finished (by persisting it for example). This will not prevent concurrent access with externals processes but at least inside your project.

  • If your project is multi users, why not use a different crontab for each user. CrontabManager allows you to define the user. This feature is documented here

TiBeN commented

Hi,
Having no activity on this issue i close it. Don't hesitate to reopen it if you still need support on this.