How can I allow only one instance of a PHP script when using crons?
Dear Experts,
I have a cron that runs a php page.
The php page is designed to log into an email account, download and import emails into the database.
This all works but sometimes, the attachments are so big, that it takes longer than the interval I allocated on the cron (15mins)
When this happens, the server starts to slow down. lengthening the time doesn't help, I would need to write something to see if this php page is already running.
If it isn't running -> run the php page
If it is running -> exit
Is there any code I can add to my php page which would enforce only one instance of this page being run?
PHPApache Web ServerLinux
Last Comment
Drace
8/22/2022 - Mon
nemagee
I'm not sure if/how that could be done in PHP, but you could write a bash shell script that basically looks at open processes and runs accordingly. The hard part might be identifying your cron job apart from any other PHP jobs. Normal PHP pages are going to show up as Apache processes, but your Cron task should show up as a PHP process, I believe.
I'll look at what that shell script might look like, but you would obviously have to test and see what to find. Maybe you could run two terminal windows, and run top in one and run your process manually in the other, and see what unique identifiers show up in top for the job?
But as to the timing, you're saying that you can't just run this once an hour and let it finish out?
Drace
ASKER
No, Even if I leave it for 1 hour it will slow the machine eventually.
The importing stops on the weekend for Database backups and repairs, so a backlog exists every Monday, not to mention during the week we get swamped with emails.
I remember using the php page to shell and run some type of linux command.. within that command I would parse the results and check if my process was running.
Of course I need to determine which PID is the right one too but I don't remember how to do that.
nemagee
Yeah, it will be tricky to know just which one is yours in the list of PIDs. Some of the utility scripts we use for various CMS's are simply PHP pages and we use a lynx or wget command in the Crontab to fire them, so they're still executed under Apache.
How does Cron call your script right now?
I believe that for your Crontab, you will want to trigger this directly via PHP, with something like:
/path/to/php -f /path/to/script.php
Or if PHP is in your path, then you can just call it via:
php -f /path/to/script.php
If you're not sure where PHP is, type "whereis php" and it should give you a path (hopefully /usr/bin/php). You'll need the -f flag to indicate you want to execute a file. You will also need to chmod your file as 755.
Your help has saved me hundreds of hours of internet surfing.
fblack61
schwomp
Hello !
$file = fopen ( 'lock.txt', 'w' );
if ( $file === false ) {
// Unable to open file, check that you have permissions to open/write
exit;
}
if ( flock ( $file, LOCK_EX | LOCK_NB ) === false ) {
// Lock is already in use by another process
exit;
}
// ---
// Do your stuf here
// ---
fclose ( $file );
Hope it helps.
Drace
ASKER
Hi Schwomp,
Your method didn't prevent the code from being run - I opened 2 SSH sessions and ran the code but it allowed both to run.
The way I call the improting is this:
0,30,45 4-21 * * 1-5 sh /mmsc/autoimport.sh > /tmp/autoimport.log
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
I'll look at what that shell script might look like, but you would obviously have to test and see what to find. Maybe you could run two terminal windows, and run top in one and run your process manually in the other, and see what unique identifiers show up in top for the job?
But as to the timing, you're saying that you can't just run this once an hour and let it finish out?