Link to home
Create AccountLog in
Avatar of Drace
DraceFlag for Canada

asked on

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?
Avatar of nemagee
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?
Avatar of 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.

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.
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.
Avatar of 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


SHELL=/bin/bash
PATH=/sbin/:/bin/:/usr/sbin:/usr/bin:/usr/local/bin
MAILTO=root
HOME=/

cd /www/autoimport/
php auto_import_email.php



auto_import_email.php used Imap and downloads emails to import them with attachments.
Hi !

Sigh, sounds strange....

I will double check tomorrow morning.

Expect an answer in 20 hours.

Bye.
ASKER CERTIFIED SOLUTION
Avatar of schwomp
schwomp

Link to home
membership
Create an account to see this answer
Signing up is free. No credit card required.
Create Account
Avatar of Drace

ASKER

Exactly what I needed!! Thank you.