Page 2 of 2

Posted: Thu Aug 16, 2007 12:37 pm
by s.dot
Assuming the above post was correct, this would successfully determine if the script is already running.

Code: Select all

public function __construct()
{
        if ($this->_isRunning()) {
                return;
        }
}

private function _isRunning()
{
	//check if pid file exists
	if (!file_exists('fakecron.pid')) {
		//attempt to create file
		if (fopen('fakecron.pid', "w")) {
			//file was created -- call this function again
			$this->_isRunning();
		} else {
			trigger_error('Fake Cron: PID file does not exist and could not be created.', E_USER_ERROR);
		}
	} else {
		//attempt to open it, will fail if file is locked
		if (!fopen('fakecron.pid', "w")) {
			//script is running
			return true;
		} else {
			//attempt to lock pid file
			if (!flock('fakecron.pid', LOCK_EX | LOCK_NB, $blockable) || $blockable) {
				//script is running
				return true;
			}
		}
	}
	
	//script was not running and is now running for the first time
	return false;
}
At least, I hope it will work. I really need to set up a testing environment.

Posted: Thu Aug 16, 2007 1:29 pm
by s.dot
Okay, going to break while I'm setting up a testing environment to ensure that what I have actually works (especcially the _isRunning() method).

Then, I'm going to:

Time each "cron" to make sure it doesn't take longer than $_timeout seconds to execute.
Change the script to calculate timestamps on each iteration through the loop, so timestamps are fresh every day.
Add support for crontab style times (will be a toughy).
Figure out a different way to store the cronjobs than [time] => $script, because this could account for duplicate keys/overwriting of keys.
Make a fakecron_statdump.php to tell the status and current jobs of fakecron.

Wow, it feels good to write something that might actually be helpful to someone besides myself.

Posted: Thu Aug 16, 2007 1:43 pm
by VladSun
I've seen many times this message:
#~ bla-bla start
Error: bla-bla.pid file exists. Is bla-bla runing?
This kind of error is reported by (I'm not quite sure) Apche and/or MySQL and/or PGSQL deamon control interface.
So, I think it is not an easily solved solution.

Posted: Thu Aug 16, 2007 4:47 pm
by feyd
It's actually fairly simple to handle. Each iteration the script does it should update the .pid file in some sequential format. If the file is some arbitrary number of updates off, the script can probably be assumed to have stopped running or has locked up.

Posted: Thu Aug 16, 2007 4:57 pm
by VladSun
I've just pointed that using the *existence* of a pid file (you'ev called it pid, I've called it lock-file - still the same) as indicitaion of runing service is not reliable. I.e. one could not rely only on its existance, there should be other techniques to check it - e.g. by using the content of this file or its properties as you suggested.

Posted: Fri Aug 17, 2007 1:21 pm
by s.dot
I'm redesigning this and I have a couple questions.

1. The PID file. Check its value against.. what? If a script is no longer running, you won't be able to use that script to check if the PID file is off. Unless you mean updating and checking against time() or something.. or maybe I'm missing the logic on how to do this.

(brain fart) Unless, the value is checked on instantiation of the object, and is found to be off... (ding ding, probably).

Then, what do you decide to use as an "arbitrary number"?

2. The usage of include(). I don't really like it. I would like to use something like file_get_contents().. but I'll have to test and see if this executes the php code inside of the file and returns that output..(so I could email the output). I've only used it on HTML and .txt files.

However, if someone were to put this script in a page with other code, would the variables made inside the file get passed along to the rest of the script?

Can someone propose a better way than include(). Ideally I would like to capture the output of the script.

Posted: Fri Aug 17, 2007 1:37 pm
by feyd

Posted: Fri Aug 17, 2007 11:31 pm
by s.dot
Doing some testing using file_get_contents(), when a "cron script" was called, the script is supposed to be ran.. instead I got this..

Code: Select all

Script "somescript.php" was executed and the result was "<?php echo str_repeat('im a cron script! ', 10000); ?>"
So, it's not evaluating the php code, rather it's reading it as text (what I expected, really). feyd, with your post, did you mean to use a combination of fsockopen and file_get_contents?

Or, maybe I should eval() and use output handlers to save the result in a string?

Posted: Sat Aug 18, 2007 7:54 am
by feyd
Combination, no. eval(), no. What I was referring to was using them to initiate a separate HTTP request that launched those scripts. Alternately, you could use shell_exec() et al to call "php -q -f filename.php"

Generally the cron execute command would involve calling php with the quiet option and the script path.

Posted: Sat Aug 18, 2007 8:16 am
by s.dot
shell_exec() seems like a good function to use.

Does it present environment problems? Like the path to PHP on the server, whether or not its a windows or linux server, and if windows -- if the program "php" is in the PATH?

Ironically this is the last problem I have to solve before I let you guys critique my new script :P And it's the most important one.

Posted: Sat Aug 18, 2007 8:21 am
by feyd
You do generally need to know where it is, but often it is in the path. On *nix systems typically calling "which php" will return the path to php, if it was found in the path. I don't recall "which" or a variant like it on Windows. You could have the code do some tests at initial run (or when there's an error) to determine the proper call and save them to a configuration file.

Posted: Sat Aug 18, 2007 8:57 am
by s.dot
I can set it to run php -q -f, and if it fails, error out with a message telling them to set a _phpPath class property. That saves a configuration file as well.