Jump to content

[SOLVED] Prevent multiple instancs of a script


Recommended Posts

Under Windows IIS, I have a php script which is setup as a scheduled task to run every 5 minutes.  The problem is that it is possible for the script to take longer than 5 minutes to complete, so I need a way to check within the script if an instance of the script is already running and exit if so.  How would I do this?

 

I've tried using flock() so that the next instance can exit if the lock fails, but all this does is hang the instance until the lock is obtained.  Since the script hangs, it never makes it to the exit statement.

 

Thanks for any help.

Hmm well, in C++ and Java I recall we used something called a singleton pattern to stop more than one instance of an object from existing at the same time. There's an entry on the Wikipedia page (http://en.wikipedia.org/wiki/Singleton_pattern) which also illustrates it in PHP5. Here is the code copied and pasted:

 

<?php
class Singleton {
  // object instance
  private static $instance;
  // The private construct prevents instantiating the class externally.  The construct can be
  // empty, or it can contain additional instructions...
  private function __construct() {
    ...
  }

  // The clone and wakeup methods prevents external instantiation of copies of the Singleton class,
  // thus eliminating the possibility of duplicate objects.  The methods can be empty, or
  // can contain additional code (most probably generating error messages in response
  // to attempts to call).
  public function __clone() {
    trigger_error('Clone is not allowed.', E_USER_ERROR);
  }
  public function __wakeup() {
    trigger_error('Deserializing is not allowed.', E_USER_ERROR);
  }
  //This method must be static, and must return an instance of the object if the object
  //does not already exist.
  public static function getInstance() {
    if (!self::$instance instanceof self) { 
      self::$instance = new self;
    }
    return self::$instance;
  }
  //One or more public methods that grant access to the Singleton object, and its private
  //methods and properties via accessor methods.
  public function doAction() {
    ...
  }
}

//usage
Singleton::getInstance()->doAction();

?>

For the temp file solution, what if the script terminates prematurely?  Then the temp file wouldn't be deleted, so the script is now blocked from ever running again.

 

I'll try out the singleton approach.

 

thanks.

 

I just gave the basic example.  In mine, within the temp file I put a timestamp.  If the timestamp is older than 1 hour (for example) it assumes its 'stale' and creates a new one.

For the temp file solution, what if the script terminates prematurely?  Then the temp file wouldn't be deleted, so the script is now blocked from ever running again.

 

I'll try out the singleton approach.

 

thanks.

 

You have to set up checks for this. Name the temp file after the current timestamp. If the filename is 10 minutes old, delete it and continue to run.

 

No matter what the solution is, you're going to have to set up timeouts for premature terminations... though I don't see why the script would terminate if it was coded properly...

I think the timestamp approach is fine, but I've got to believe there should be some way to determine if a script is currently running without having to resort to creating temporary files and checking timestamps and such.  Under Unix and using Perl, it was a simple command to see if a particular script is running or not.  Is there something similar in PHP?

 

Even with a perfectly coded script, early termination is possible.  It's not always an issue with the code that can stop a script from running.

I tried the singleton approach, and I can't see how it can be used to prevent multiple instances of a script from running.

 

Any other ideas?

 

etabetapi, that prevents more than 1 instance of the class existing in the scope of the execution.  IE, if that script is ran twice simultaneously, two instances will exist.

 

 

 

 

---------------------------------------------

 

 

If you could use ps and find the args passed to the PHP binary you could see if the script were running.  Dunno if that's possible.  I'll turn on my FC box and check.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.