What happens when you have a cron job that you want to run fairly regularly - let's say every minute or every two minutes. Now what happens if the server is under load and it doesn't complete the job before the next call - you get a cron collision. Sometimes that's not a big deal, but often that can cause problems. For example if you have an email queue, or sms queue and it is called twice - you could end up sending out each message twice. If there is an API call you could end up with duplicate data or worse case information could be deleted. There are several ways around this - the 3rd is the best and easist: 1. Firstly you could use the flock() function in php. This is a function which will lock a file - and if it locks you then do what you want, unlock it when finished and then exit. If another copy comes along wanting to lock the file - it is already locked and the file exits quickly. There are more options than this which you can read about at http://php.net/manual/en/function.flock.php Here is an example of how you would use flock() to protect from a cron collision 2. Another alternative is to create your own lock file using file() and other file functions in php. For this you will need several files. You will need the file that is called from cron - let's call it flock.php. Then you need the actual lock file - let's call it flock-timestamp.txt and then you need the php script you will actually use. What you do is you call the flock.php file from cron and have it run every minute. Flock.php opens flock-timestamp.txt and gets whatever data is inside it which will be something like 0 or 1. If its locked it will be 1, if its not locked it will be 0. If the file is 1 (or locked) simply exit and cron will call again in a minute. If its not locked - first thing is to write to the file with fwrite() and lock it by overwriting the 0 with a 1. Then call the script you want with $page = file_get_contents('filename');. After this unlock the file by writing over again and exit. However one more thing to keep in mind - each time you check if the file is locked - check the file time as well because if its has been locked for a long time like 10 or 15 minutes - its possible that some error has happened and it has frozen and you will want to allow for it to manually be unlocked. You can setup an email notification or sms notification so that you will find out if it gets stuck being locked. 3. This third method is in my opinion the easiest - you need to be using a Linux based server with flock installed. All you need is the script you are wanting to run and another text file which doesn't even have to have any contents. Just call them from cron with a few extra parameters. For example. If you had an account called octopus (let's pick a name) on a linux server and your script is names script.php and your text file is text.txt and both files are located in the main directory you would call cron like this. flock -n /home/octopus/public_html/text.txt curl --silent --compressed curl http://www.yourdomainname.com/script.php That's all there is to it. Every time cron runs it will try to lock text.txt and if successful will run script.php with curl. You can modify whatever command you want after the text.txt to do whatever you want there. If the file was not able to be locked (because it aleady was) it just exits and waits. You can setup email alerts to check it for the first 5 or 6 times to make sure it's working. If using drupal or another content management system which redirects URLS with the apache redirect module - you will need to make sure that the flock command in the cron command is calling a real file and not a URL rewritten file. The second command can be a "fake" file if needed. For more information about what commands you can use along with the flock command visit this page - http://linux.die.net/man/1/flock If you need to add flock to your server you can locate the package here - ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/ and to check if it is installed go to usr/bin/flock because that is where it normally is. In the course of the last few months I've played with all 3 methods of locking files and if you find that this has saved you time - don't hesitate to give me a backlink

Thursday, August 16, 2012

« Back