I want to put a php daemon to sleep (with System_Daemon::iterate())
so it runs max 20 times randomly spread over an hour. maybe a min distance would be smart so it doesn't run 20 times in the first half hour and 0 times in the second half.
i'm kinda stuck here and don't know how to start with this one, any help is very apreciated!
You may use cron jobs, to set the script to run ever so often.
http://net.tutsplus.com/tutorials/php/managing-cron-jobs-with-php-2/
... Crontab:
0 9 * * * /path/to/bashscript
and in /path/to/bashscript:
#!/bin/bash
maxdelay=$((1*60)) # every hour, converted to minutes
for ((i=1; i<=20; i++)); do
delay=$(($RANDOM%maxdelay)) # pick an independent random delay, 20 times
(sleep $((delay*60)); /path/to/phpscript.php) & # background a subshell, then run the php script
done
i came up with one possible solution, i didnt try it out yet, so it main contain syntax or logic errors. because it is running as a daemon there is a never ending loop around it.
// 3600 seconds or one hour
$timeframe=3600;
// run max 20 times in $timeframe
$runtimes=20;
// minimum delay between two executions
$mindelay=60;
// maxium delay between two executions
$maxdelay=240;
if ($cnt % $runtimes != 0) {
$delay = rand($mindelay,$maxdelay);
System_Daemon::iterate($delay);
$sum += $delay;
$cnt++;
} else {
//final delay till the $timeframe
if ($sum < $timeframe) {
System_Daemon::iterate($timeframe - $sum);
}
$sum=0;
}
its not perfect and u waste some time but i guess its going to fullfill the job.
any comments?
Related
I am developing a php script, which should run a shell script for every 20 mins for one 10 days.
I did explored the option of crontab but, crontab gives duration or specific time of every day.
It does not have option for running script every 20 mins for 10 days continuously.
If anybody has better option kindly, suggest.
Thanks !
Put this in your crontab:
*/20 * * * * bash /path/to/your/script.sh
Then remove it after 10 days.
Better yet, have your script check the current date and send you an email when it's 10 days from now to remind you to remove it.
You could also just have the script remove the line from the crontab (or just remove the crontab file if it's only got this one line) after 10 days.
I agree with everyone else use crontab, then on your php file you could do this:
if(time() > strtotime('2013-08-01 00:00:00 +10 days')) {
die();
}
Look at the at command, which will run the command specified at the specified time. Note you will have to do your own calculation to determine each run time, and you'll wind up with a seed script like this:
$ for i in {0..720}; do echo 'php the-command.php' | at now + $(($i * 20)) minutes; done
I'm writing a a php script where i do a loop and inside the loop there is a particular function processing information, as illustrated here.
while (some condition){
// some code
processInformation();
// Some more code
}
Well it turns out that midway, inside processInformation(), I encountered the error Fatal error: Maximum execution time of 30 seconds exceeded. Using set_time_limit(0), would not help in my situation because processInformation() might take forever. I don't want an error to completely break my program, so is there anyway i can catch an exception or tell php to "continue" the loop if processInformation() takes too long?
You can increase the value of maximum execution time from 30 seconds to any value. For example: if you want to set the limit of maximum execution time of 3 minutes (instead of 30 seconds), then you can set as:
ini_set('max_execution_time', 180); //maximum execution time of 3 minutes
This way, you can set the time based on your need.
I dunno how to catch the exception but you could use a simple time calculation to escape after say 60 secs. ()
$x=time();
while (some condition){
processInformation();
if ($x + 60) < time()
break;
}
Say my set_time_limit is set to 30 seconds and can't be changed. I have an email script in php that will run longer than 30 seconds on 1 cron job (I haven't reached that time mark yet.) What happens on timeout after 30 seconds? Will the script stop then continue?
If not, I would like to record the elapsed time from the beginning of my script's loop until it reaches 30 seconds and pause the process then continue.
What is a good way to do this?
Update: what I think might work
function email()
{
sleep(2); //delays script 2 seconds (time to break script on reset)
foreach ($emails as $email):
// send individual emails with different content
// takes longer than 30 seconds
enforeach;
// on 28 seconds
return email(); //restarts process
}
Suggested approach:
function microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
$time_start = microtime_float();
foreach ($emails as $email):
// send individual emails with different content
// takes longer than 30 seconds
$time_curr = microtime_float();
$time = $time_curr - $time_start;
if($time > 28){ //if time is bigger than 28 seconds (2 seconds less - just in case)
break;// we will continue processing the rest of the emails - next time cron will call the script
}
enforeach;
What you ask is not possible. When the script timeout is reached, it stops. You cannot pause it and continue it. You can only restart it. Let me tell you what I did to solve a similar problem.
Part One:
Queue all your emails into a simple database. (Just a few fields like to,
from, subject, message, and a flag to track if it is sent.)
Part Two.
1. Start script
2. Set a variable with the start time
3. Check the db for any mails that have not been sent yet
4. If you find any start a FOR loop
5. Check if more than 20 seconds have elapsed (adjust the window here, I like
to allow some spare time in case a mail call takes a few seconds longer.)
6. If too much time passed, exit the loop, go to step 10
7. Send an email
8. Mark this email as sent in the db
9. The FOR loop takes us back to step 4
10. Exit the script
Run this every 60 seconds. It sends what it can, then the rest gets sent next time.
I need to get average sleep interval from following data:
22:00-06:00
00:00-08:00
02:00-10:00
=> expected: 00:00-08:00
22:00-06:00
00:00-08:00
02:00-10:00
04:00-08:00
=> expected: 01:00-08:00
The problem is oscillation around midnight, where part is under 00:00 and part over 00:00.
Simple mean 22+00+02+04 doesn't work. I could count number of times over midnight (3 in this case) and if it's more than those before midnight, I should add 25 co compensate. But this doesn't count with those people, who work at night and go sleep around 8-14!
My theory is: First, somehow I need found peak, something like the most frequented area (e.g., in 9-10 there is 5 record, in 10-11, there is 3 etc.) and then I can decide co compensate border values by adding 24 hours.
What do you think?
What about taking into account relative difference with midnight ?
The result would be (-2+0+2+4)/4 = 00:45
Making the assumption that the person is not sleeping more than 24 hours, then make a method to calculate like so (pseudo code):
calculateSleepTime(sleepTime, wakeupTime) {
if (sleepTime > wakeupTime) {
return (24 - sleepTime) + wakeupTime;
} else {
return wakeupTime - sleepTime;
}
}
averageSleepTime(sleepTimesArray) {
totalSleptTime = 0;
totalTimesSlept = 0;
foreach (oneSleepTime in sleepTimesArray) {
totalTimesSlept++;
totalSleptTime += calculateSleepTime(oneSleepTime);
}
return totalSleptTime / totalTimesSlept;
}
After you get the average sleep time, calculate either the average sleep time, or average wake up time, and do addition/substraction to find your interval. The alternative to this is finding the average sleep time and the average wakeup time (taking relative to midnight times into account).
Determine a lower limit where you can say
Okay, people won't go to sleep this time of the day, if I get this time, it must mean they worked all night and only sleep now
and if the time is below that limit, add 24 hours to both start and finish.
I am currently writing a online game. Now I have to check if an event happen (checking timestamp in database) and depending on that execute some actions. I have to check for an event every second.
I wanted to use a cronjob but with cron you can run a script only every minute.
My idea was to use cron and loop 60 times in my php script. But I think this isn't the best solution.
So whats the best way to run a script every second?
I searched for a better solution but it seems that my first idea, with clean code, is the best solution.
This is my current code:
<?php
set_time_limit(60);
$start = time();
for ($i = 0; $i < 59; ++$i) {
// Do whatever you want here
time_sleep_until($start + $i + 1);
}
?>
Why not modify the script so that it just repeats the code every second? This will reduce the parsing overhead and be less complicated.
You should probably run the script once, and use a loop with delay to accomplish your desired timing.
The side benefit is that this is more efficient, and you would only have to open resources (ie, databases) once.
You shouldn't want this :P. No host will accept your cronjob is running every second every minute?
You can save the time it runned in a database, and the next time you run it calculate the time between both runs and do the calculations you want. every second is a very bad idea.
$total_time = 0;
$start_time = microtime(true);
while($total_time < 60)
{
//DoSomethingHere;
echo $total_time."\n";
//sleep(5);
$total_time = microtime(true) - $start_time ;
}
add this in crontab to run every minute.