Cron is not running at specified time in moodle?
1.I just created an cron job like a
function cron(){} in block_plugin and i written an code to insert records in db and i set time $plugin->cron= 1*60; in version.php. its inserting data into db when i am running mysite.com/admin/cron.php.
2.Its not working for every specific time(automatically for every 1 min).I checked db after 1min without running yoursite.com/admin/cron.php file its ideal. please help in it.
If you are not manually running admin/cron.php, then have you set up something to automatically call this on a schedule? (Or admin/cli/cron.php)?
If you have not set up an automatic process to run the Moodle cron and have not called it manually, then none of the cron processes will happen.
Note that specifying 60 seconds is the minimum time between your code running - it will depend on how long the other cron processes take (I've seen large sites where cron can take 30-40 min to run at times) and how often the automated process calls it (could be every 1 min, but many sites set it to every 5-10min, or longer, to reduce server load).
Related
I am using Cakephp.
I want to run scheduled jobs.
Here's the situation:
User set time for some task on UI (say 1 week).
When the time is over, I want to execute some specific task. Meanwhile, the user can also change the time, and the task should be executed at updated time.
What is the best way (and reliable) to achieve this?
PS: Complexity is not the issue. But the task must always run after specific time under all circumstances.
Set the execution date in your table in a field
Set a status (pending) as well
Run a cron job that runs a CakePHP shell every X seconds or minutes, whatever you need OR create a shell that keeps running all time and check the records every X seconds in a loop.
The shell will process tasks that are configure for an execution date lower than the current date
Set the status to success or failed depending on the outcome
It's up to you how you want to handle failed tasks and if it's OK if a task executes 10secs later than configured or 10 minutes. There are multiple factors that play into this: Your interval of the cron job / query against the table. Do they have to processed in parallel? Is it OK to process them after each other? Your information is to vague.
The way to do that in CakePHP is to create a shell and run it with Cronjobs.
I'm in need of a way to create dynamic, one-off cron jobs to execute tasks at different times. Ideally, I would like to achieve this using PHP, so that when a user completes a certain action, the cron job is created and scheduled for a time that is calculated based on the time that the user completes said action. At any one time, there could be multiple cron jobs scheduled at once for different times. These cron jobs also need to be deleted upon completion.
I have tried searching around for something appropriate, however haven't encountered anything that works as I need. If anybody could point me in the right direction, that would be greatly appreciated.
Cheers
A possible solution:
Setting a Cron job that calls to CronJobManager.php every second.
Just make a regular daemon that calls for the CronJobManager.php.
Create a cronjob table in your database
The cron job table should contain these basic fields: path (to php file), run_time(datetime), last run (datetime) and type (like suicidal, if as you explain you want some cron jobs to delete themselves)
Connect CronJobManager.php with the cronjob table
Every time CronJobManager.php runs (that is, every second), loads the cron jobs. Then, comparing "now"'s time with each cron job's run_time you'll get which cron jobs to run.
For example, if cron job "foo" run_time is set to 18/04/2014 22:02:01, CronJobManager will run it when reaching that moment.
Notice that if Cron jobs executing time needs a lot of time, they'll get delayed and eventually a second or two will get lost.
Now, for every cron job that needs an execution, you would execute the related php file of that cron job, indicated in the path.
This is a general idea, and of course you would have to extend it with for example cron job states (idle, running, stop, etc).
In order to delete cron jobs you would implement this feature in the cron job object.
That is: the Cron Job class, once it has executed what it had to do, it would check its type (as defined in database). If it is 'suicidal', then it would delete the database row.
UPDATE
I updated the answer but I want to note something. If what you need is several cron jobs to run at once, in a specific second with 0 delay, then you need a cron job per task out of php that runs a specific file.
To achieve this functionality, you need to have a daemon that is running all the time that checks for these dynamic jobs and launches them. The setup is a tad complicated to put together, but if you are ready for such an endeavor, you can use the project PHP Resque Scheduler.
https://github.com/chrisboulton/php-resque-scheduler
You start up a daemon that runs all the time and then you can add jobs to a dynamic queue to be executed at any specified time in the future. I think you will find this suitable to everything you are looking to do.
I need to run some tasks continuously. These tasks consist, mainly, of retrieving specific records from the DB, analyzing and saving them. This a non-trivial analysis, which might take several seconds (more than a minute, perhaps).
I do not know how frequently will new records be saved in the DB waiting for analysis (there's another cronjob for that).
Should I retrieve records one by one calling the same analysis function again once it finishes (recursively) and try to keep the cronjob running until there are no more unanalyzed records?
Or should I retrieve a fixed amount of new records on each cronjob run and call the cronjob every certain amount of minutes?
A job queue server may work well for this scenario (See ActiveMQ or MemcacheQ for example. Rather than adding the un-analyzed records directly to the database, send them to a queue for processing. Then your cron job could retrieve some items from the queue for processing, and if one job takes so long to run the cron job is triggered again, the next one will run and grab the next items in the queue.
Personally, I would have the cron job retrieve a fixed number of records for processing, just to make sure you don't get the script stuck processing for a very long time in the event new records keep getting added and the processor can't keep up. Eventually it would probably finish everything but you could end up in a situation where it continues for a very long time.
You may consider creating a lock file as well that the job can look for to see if the task processor is already running. For example when the cron job starts, check for the existence of a file (e.g. processor.lock), if it exists, exit, if not, create the file, process some records, and delete the file.
Hope that helps.
Or should I retrieve a fixed amount of new records on each cronjob run and call the cronjob every certain amount of minutes?
That. And you'll have to do some trial and error metrics first to decide an optimal fixed amount.
Of course it heavily depends on what you are actually doing, how many db intensive cron jobs you are running simultaneously and what kind of setup you have. I recently spent a day looking for a Heisenbug in a very intensive script that migrated images from db to s3 (and created a few thumbs while migrating). The problem was that due to an undocumented behaviour in our ORM the connection to the database was lost at some point, as posting to s3 + thumbs generation for certain images took a little bit more than the connection time limit. It was an ugly situation, that would probably cost more than a day to identify in a recursive do it all scheme.
You'd be better off with the safe approach, even if it means a little time lost between cron executions.
Instead of using a cron job, I would use The Fat Controller to run and repeat tasks. It is basically a daemon which can run any script or application and restart it after it finishes, optionally with a delay between runs.
You can additionally specify a timeout so that long-running scripts will be stopped. This way you don't need to care about locking, long-running processes, error process and so on. It will help to keep your business logic clean.
There's more examples and use cases on the website:
http://fat-controller.sourceforge.net/
I have to run a pretty heavy task on PHP once a week (script that curls to various locations (websites, API's), gathers, sorts data and inserts it into a db). The whole script takes about 10 to 15 mintues to run on my mac (localhost) - guessing it'll run a bit faster on a server. Nevertheless - I'm currently looping through with AJAX, so when each task is finished, next one is launched. Now I need to run it weekly, automatically. So I think I can't do it with AJAX Anymore.
Do I have to just set the php.ini to let a script run for 30 mintues or there is a better way to do it ?
The maximum execution time of the PHP script is determined by the amount of time in which no output has been generated. So writing data into STDOUT (e.g. to a logfile) will keep the script running.
However, if you're running the script from command line, the max-execution-time will be defaulted to zero anyway and as already suggested, I'd start the script with a cronjob instead of an AJAX-Request or similar methods. I actually do that for most of my php-scripts performing administrative tasks like synchronizing data across several databases or similar purposes.
php.ini has nothing to do with scheduling jobs. It's simply definining PHP's startup settings. What you want is a cron job, as your title says.
For OSX cron setup, see http://hintsforums.macworld.com/showthread.php?s=&threadid=39005
I have a Cron Job with PHP which I want to set up on my webhost, but at the moment the script takes about 20 seconds to run with only 3 users data being refreshed. If I get a 1000 users - gonna take ages. Is there an alternative to Cron Job? Will my web host let me run a cron job which takes, for example, 10 minutes to run?
Your cron job can be as long as you want.
The main problem for you is that you must ensure the next cron job execution is not occuring while the first one is still running. You have a lot of solutions to avoid it, basically use a semaphore.
It can be a lock file, a record in database. Your cron job should check if the previous one is finished or not. A good thing is maybe sending you an email if he cannot run because of a long previous job (this way you'll have some notice alerting you that something is maybe getting wrong) By default cron jobs with bad error dstatus on exit are outputing all the standard output to the email of the account running the job, depending on how is configured the platform you could use this behavior or build an smtp connexion on the job (or store the alert in a database table).
If you want some alternatives to cron jobs you should have a look at work queues. You can mix work queues with a cron job, or use work queue in apache-php envirronment, lot of solutions, but the main idea is to make on single queue of things that should be done, and execute them one after the other (but be careful, if you handle theses tasks very slowly you'll get a big fat waiting queue).
A cron job shouldn't have any bearing on how long it's 'job' takes to complete. If you're jobs are taking 20 seconds to complete, it's PHP's fault, not cronjob.
Will my web host let me run a cron job which takes, for example, 10 minutes to run?
Ask your webhost.
If you want to learn about optimizing php scripts, take a look at Profiling PHP Code.