Good day to all.
I need to do this:
From a computer somewhere in this world I need to access a specific URL and start a process. The only problem is that since the process may last over 5 hours and may return some errors (the process will move over them) PHP commands like exec, shell_exec, etc don't work (don't exactly know why but... all return error and stop execution)... so I tried this:
I made a cron that runs a script
use php to write the script file
Everything works fine but I need to return a counter telling me when the process will start so, when I run the php script that edit the shell script I return the hour of the system and start counting till the next full minute (when the script will be executed).
Now the only problem is this:
The counter SEEMS to work ok... but also the process needs some time to start and that time may vary from 3-4 sec to 1 minute. My question is... can I get sometime of hint at least if not the exact time of when the process will start up and the exact time when it did start?
I dunno... like writing in a file and a php script read it for a minute to see when something changed?
Ok... I promised I'll add some details:
The process is streaming. Live. So this is what I need to do:
create a stream
give a counter to the user when the stream will start
I use ffmpeg for streaming. The start.php have something like:
// Create a file called script.sh
$string = "ffserver & ffmpeg -i pipe.avi http://localhost:8090/feed1.ffm& echo exit 0 > script.sh& exit 0";
//write string to script.sh
//create a file that contains the exact time when the script was run.
The cron looks like this:
* * * * * /var/www/html/script.sh > /dev/null
and some other crons that doesn't matter
So I can create a counter that gets the time when the script was run and count till the next minute when the cron will run. The thing is that ffmpeg has some time until it starts (testing codecs, checking file etc.) I need to get that time and include it in timer so when the stream starts the guy that speaks says "Hello". Is not nice for him to do something like "Ok... is this working? Yes? Hello ppl." and is not good for the users to loose the first 3-4 sentences. That's why I need the moment when ffmpeg starts and somehow pass it to a php script. I can manage from there.
I have worked at places where crontab was only cycled every 5 mins, but more recently crontab seem to be cycled every 1 minute. It is probably a configurable value, so if you don't think your crontab is starting until some multiple of minutes that may be the reason.
Your process should start after the time seconds value moves from 59 to 00. There may also be minor delays starting the crontab entry if some other process is already using most/all of systems resources.
But looking at this from another point of view, if you are creating crontab entries with a specific time value, then you know what time to start looking at, + 2-3 seconds, right?
Please modify your posting to include a sample of what your crontab entry that your system creates looks like (are there any '*' in it, being my main interest).
Rereading your post, I see you're not programamtically creating the crontab entry. Nevermind on that.
If your process is running for many hours, why you need to immediately attach to it. If it crashes in the first 30 seconds, isn't waiting 1 minute max to find that out good enough?
Finally, in the shell environment, there is 99.99999% of the time, a way to capture a process's output from the very beginning. The idea of having to wait, to start getting the output requires more explanation. Is this something todo with that the program is running on a remote machine? The remote program should capture it's output, and then you 'get' that output as a seperate sub/co-process.
I hope this helps.
Related
put in simple words:
i am writing php scripts which send and receive sms,
scripts will calculate to send users campaign SMS every week based on each user registration date, for example every monday 10 AM send sms to mr. A and every friday at 7 pm sends sms to miss B..
and php scripts will take care of everything needed ..
problem : obviously a very funny way is to have someone refresh the main page of my application every some seconds or so to be able to continue to calculate and understand what and when to do jobs, or have the main page always open on my computer so javascripts and jquery will handle the rest!
My Question : how can i have my php program or scripts to be something like awake without need to someone refreshes or have open the main page? by awake i mean like it senses the next schadule and executes it and so on ..
some raw ideas to answer : perhaps i could call the main page using ajax or curl every 10 seconds .. but i don't know how to awake ajax or curl in first place ..
i see some internet posts suggest something like command line either in linux unix or windows .. but i usually access the host not the command line is it right ? or command line is something in host and i don't know it, if so please help me ..
important example : there are php wp plugins like total cache and supper cache which seem to be always on and awake of schedules without need of somebody refreshing a page ..
please give answers all in php and php families if possible, i don't know unix or those kind of programmings at all ..
------- accourding to answers made some progress to question ..
now i have this bellow script :
ignore_user_abort(true);
set_time_limit(0);
$data = file_get_contents('filename.txt');
$data = $data+1;
file_put_contents('filename.txt', $data);
$page = $_SERVER['PHP_SELF'];
$sec = "4";
header("Refresh: $sec; url=$page");
it works! even when i restart the local host . main problem is now when i closed the main page it stopped incrementing in filename.txt and when reoppend the page two instance where running the increment continued so :
should'nt it continue to increment even when i close the page ?
and how i stop it ?
and is it normal to have more than one instance of the page run in background?
finally : according to instructions on this page it's best i create a starter or reload page then use commands to initiate this reload page for example every 1 minute and then write PHPs like normal ..
last not least : how to stop this background script ? for update or maintenance ..
For this particular issue cron jobs have been invented. Cron jobs are timed jobs that can for example execute a PHP script.
You could set up a cron job to check which user should receive his/her sms every hour. Depending on your operating system you can set up these cron jobs. For linux distrubutions there are tons of guides on how to set this up.
From Wikipedia:
The software utility Cron is a time-based job scheduler in Unix-like computer operating systems. People who set up and maintain software environments use cron to schedule jobs (commands or shell scripts) to run periodically at fixed times, dates, or intervals. It typically automates system maintenance or administration—though its general-purpose nature makes it useful for things like downloading files from the Internet and downloading email at regular intervals. The origin of the name cron is from the Greek word for time, χρόνος (chronos). (Ken Thompson, author of cron, has confirmed this in a private communication with Brian Kernighan.)
I have added a resource explaining how to use cron jobs.
An alternative method is to keep a PHP script running in the background:
// Keep executing even if you close your browser
ignore_user_abort(true);
// Execute for an unlimited timespan
set_time_limit(0);
// Loop infinitely
// If you create a file called stop.txt,
// The script will stop executing
while (!file_exists('stop.txt')) {
// Retrieve user data and sens sms messages
// Wait for an hour
sleep(3600);
}
Update
ignore_user_abort(true);
set_time_limit(0);
$data = file_get_contents('filename.txt');
while (!file_exists('stop.txt')) {
// Add 1 to $data
$data = $data+1;
// Update file
file_put_contents('filename.txt', $data);
// Wait 4 seconds
sleep(4);
}
To stop executing create a file called stop.txt
Resources
About Cron jobs
You can create cron jobs in almost all servers without accessing command prompt.
Cron job can be used to initialize php scripts in cli at specified intervals lik every minute, every hour etc
I have been researching on how to approach this. What I am trying to prevent is an overlapping execution of a cronjob. I would like to run my script in every minute basis because the application is support needs a constant look out. The problem is if it takes quite a long time to finish and the next cron execute will catch up.
I have searched and some posted about PID but did not get on how to do it. I cannot use lock files because it can be unreliable, tried it already.
Is there any other approach on this?
Thank you.
Get each job to write to a database in completion. Then put an if statement at the start of each script to ensure that the other script has run and completed (by checking your database).
Alternatively...
You could have your first script run your second script at the end?
i have script which must execute after every n minutes. n minutes is dynamic so that i could not set a cron job to call the script (at a specific time).
so what i did was i stored the time after every n minutes in an array so that when the script is executed, it will first check whether the current time is in the array. if it is found in the array, it continues to executes otherwise it exits.
to execute the script, i must use a cron job to run every minute to check the time in the array. unfortunately, my web host only allows 5 minutes as the least interval. so every time the script is called, i check whether the values between $current_time and $current_time + (4*60) // 4 minutes is found in the array. if it is, and if needed, i use time_sleep_until to delay the script until the time reaches the value found in the array.
so if my script executes at 10:05 and the value found in the array is 10:06, i let the script sleep until 10:06 before it continues to execute. however, if the sleep time is more than a minute or so, i get a Mysql server gone away.
how can i prevent this? or is there a better way to do this?
thanks!
A couple choices, which is better I do not know.
One, is make sure your script works with CLI and after that minute is up call it with the http://www.php.net/exec function (if your host allows it).
Two, is setup a script, with a possible hash as a key and use a header redirect after the minute is up, this would call the script brand new so a new MySQL connection is made.
A third option is to set the script up like in two, except setup a schedule task / cron job on your computer that opens that page (it would have to be in the webroot) and calls it every minute or however you want. This is not a set method, but depends on how much your computer is on.
Fourth, similar to the third but use a free cron job hosting service like: http://www.onlinecronjobs.com/en
Hope that helps. If I think of other options I will update.
I'm pretty sure I've seen this done in a php script once, although I cant find the script. It was some script that would automatically check for updates to that script, and then replace itself if there was an update.
I don't actually need all that, I just want to be able to make my PHP script automatically run every 30 minutes to an hour, but I'd like to do it without cronjobs, if its possible.
Any suggestions? Or is it even possible?
EDIT: After reading through a possible duplicate that RC linked to, I'd like to clarify.
I'd like to do this completely without using resources outside of the PHP script. AKA no outside cronjobs that send a GET request. I'd also like to do it without keeping the script running constantly and sleeping for 30 minutes
If you get enough hits this will work...
Store a last update time somewhere(file, db, etc...). In a file that gets enough hits add a code that checks if the last update time was more xx minutes ago. If it was then run the script.
You may want to use the PHP's sleep function with specified time to run your code with that interval or you may want to try some online cron job services if you wish.
Without keeping the script running constantly, you'll either have to use something hackish that's not guaranteed to actually run (using regular user pages accesses to run a side routine to see if X amount of time has passed since last run of the script and if so, run it again), or use an external service like cron. There's no way for a regular PHP script to just magically invoke itself.
You can either use AJAX calls from your real visitors to run scheduled jobs in the background (google for "poor man's cron", there are a number of implementations out there) or use some external cron-like service (for example a cronjob on some other machine). In theory you could just run a PHP script with no timeout and make it loop forever and fire off requests at the appropriate time, but the only thing that would achieve is reinventing cron in a very ineffective and fragile way (if the script dies for some reason, it will never start again on its own, while cron would just call it again).
Either way, you will need to set proper execution time so the script does not exceed it.
I found this:
<?php
// name of your file
$myFile="time.db";
$time=file($myFile);
if(time()-3600 > $time[0]){
// an hour has elapsed
// do your thing.
// write the new timestamp to file
$fh = fopen($myFile, 'w') or die("can't open file");
fwrite($fh, time());
fclose($fh);
}
else{
// it hasn't been an hour yet, so do nothing
}
?>
in here
If the host includes a mysql 5.1+ db then perhaps timed triggers are availible to call the script? I like these mission impossible type questions, but need more information on what kind of playground and rules for the best answer.
I want to set up a small php script which simply returns a string, either from an array or from a line in a text file. As well as returning the string any time this script is called, I also want it to automatically cycle through the set of items (either an array or each line in a text file) on a timed basis. For example, every 15 minutes I want the script to step through each item in the list. I've not actually done anything like this before, so i'd be interested to hear any advice. Thanks
You have to use CRON JOBS. If you have admin rights then you can easily set up cron jobs to run your scripts by second,minute hour or day. Just add your script to a cron tab along with the intervals. Look below for instructions
http://adminschoice.com/crontab-quick-reference
As for the PHP script i guess you must have found it out by now.