Sleep never continues execution - php

I have made a script that checks a server's availability.
The site was down and I was awaiting a fix(I was on call for a client and was awaiting a ticket from the provider), to limit calls I have used sleep():
$client = new \GuzzleHttp\Client();
$available = false;
date_default_timezone_set('doesntMatter');
//The server was more likely to respond after 5 AM, hence the decrese between intervals
$hours = array( //Minutes between calls based on current hour
0=>30,
1=>30,
2=>30,
3=>30,
4=>20,
5=>20,
6=>10,
7=>10,
8=>10
);
$lastResponse = null;
while(!$available) {
$time = time();
$hour = date('G', $time);
echo "\n Current hour ".$hour;
try {
$crawler = $client->request('GET', 'www.someSiteToCheck.com');
$available = true; //When the server returns a stus code of 200 available is set to TRUE
} catch (\GuzzleHttp\Exception\ServerException $e) {}
if(!$available) {
$secondsToSleep = $hours[$hour]*60;
echo "\n Sleeping for ".$secondsToSleep;
sleep($hours[$hour]*$secondsToSleep); //Sleep until the next request
} else {
exec('start ringtone.mp3'); //Blast my stereo to wake me up
}
}
Problem:
When I started the script it went in a 1800 second sleep and froze, it didn't re-execute anything
Given:
I tested my script with a sleep of 160 (for ex) and it made multiple calls
Checked my power settings so that the machine wouldn't go in stand-by
Checked error logs
(Even if obvious) I ran in CLI
Checked sleep() documentation for issues but nothing
Couldn't find anithing related

I think you have an error in your logic.
For example:
When it's 5AM
Then $secondsToSleep is 20*60 = 1200sec;
When you call the sleep function you multiply it again with 20
sleep($hours[$hour]*$secondsToSleep); => sleep(20*1200); => 24000sec => 6,66... hours

If you simply update your sleep parameter the result should be as expected.
if(!$available) {
$secondsToSleep = $hours[$hour]*60;
echo "\n Sleeping for ".$secondsToSleep;
sleep($secondsToSleep); //Sleep until the next request
}

Related

I am not successful with PayPal-PHP-SKD code "payment->execute"

I have successfully utilized PayPal-PHP-SKD to request a payment sending the user to the PayPal payment gateway sandbox with credentials and sandbox buyer account etc. Everything works and I get a request to the returnURL with $_GET variables success=true, paymentID, token and PayerID. My problem is in the next step which captures the paymentID and PayerID, creates objects for Payment PaymentExecution which seems to work OK but crashes when I execute the line "result = $payment->execute($exClaimPayment, $mPPcredentials);". If I comment out that line, the code works without error but when I include it the code crashes.
"result = $payment->execute($exClaimPayment, $mPPcredentials);"
if (isset($_GET['success'], $_GET['paymentId'], $_GET['PayerID'])) {
if ($_GET['success'] == 'true') {
$mSuccess = TRUE;
$mPaymentID = $_GET['paymentId'];
$mPayerID = $_GET['PayerID'];
$payment = Payment::get($mPaymentID, $mPPcredentials);
$exClaimPayment = New PaymentExecution();
$exClaimPayment->setPayerId($mPayerID);
$mProgress = 'in success after $exClaimPayment->setPayerId($mPayerID)';
try {
$mProgress = 'in try';
//result = $payment->execute($exClaimPayment, $mPPcredentials);
} catch(Exception $ex){
$errorMsg = json_decode($ex->getData());
}
}
} else {
$mSuccess = FALSE;
$mProgress = 'in NOT success';
}
In my envoronment, Win 10, Notepad++, FileZilla, Hostmonnster hosting and Chrome, I cannot see the error. It just crashes (with HTTP 500 ??)
I found my error! It was MY error.
The line:
result = $payment->execute($exClaimPayment, $mPPcredentials);
Should have been:
$result = $payment->execute($exClaimPayment, $mPPcredentials);
I have worked on this code for half a day and did not see my error until 5 minutes after I posted the question on StackOverflow.
My conspicuous errors in PHP often cost me a lot of time. I would benefit from an environment that would point out my syntax errors.
StackOverflow is a very good resource. Thanks!

PHP Wait before sending next api request

I have a website that pulls prices from an API. The problem is that if you send more than ~10 requests to this API in a short amount of time, your ip gets blocked temporarily (I'm not sure if this is just a problem on localhost or if it would also be a problem from the webserver, I assume the latter).
The request to the API returns a JSON object, which I then parse and store certain parts of it into my database. There are about 300 or so entries in the database, so ~300 requests I need to make to this API.
I will end up having a cron job that every x hours, all of the prices are updated from the API. The job calls a php script I have that does all of the request and db handling.
Is there a way to have the script send the requests over a longer period of time, rather than immediately? The problem I'm running into is that after ~20 or so requests the ip gets blocked, and the next 50 or so requests after that get no data returned.
I looked into sleep(), but read that it will just store the results in a buffer and wait, rather than wait after each request.
Here is the script that the cron job will be calling:
define('HTTP_NOT_FOUND', false);
define('HTTP_TIMEOUT', null);
function http_query($url, $timeout=5000) {
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT_MS, $timeout);
$text = curl_exec($curl);
if($text) {
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
switch($code){
case 200:
return $text;
case 404:
return -1;
default:
return -1;
}
}
return HTTP_TIMEOUT;
}
function getPrices($ID) {
$t = time();
$url = url_to_API;
$result = http_query($url, 5000);
if ($result == -1) { return -1; }
else {
return json_decode($result)->price;
}
}
connectToDB();
$result = mysql_query("SELECT * FROM prices") or die(mysql_error());
while ($row = mysql_fetch_array($result)) {
$id = $row['id'];
$updatedPrice = getItemPrices($id);
.
.
echo $updatedPrice;
. // here I am just trying to make sure I can get all ~300 prices without getting any php errors or the request failing (since the ip might be blocked)
.
}
sleep() should not affect/buffer queries to the database. You can use ob_flush() if you need to print something immediately. Also make sure to set max execution time with set_time_limit() so your script don't timeout.
set_time_limit(600);
while ($row = mysql_fetch_array($result)) {
$id = $row['id'];
$updatedPrice = getItemPrices($id);
.
.
echo $updatedPrice;
//Sleep 1 seconds, use ob_flush if necessary
sleep(1);
//You can also use usleep(..) to delay the script in milliseconds
}

How to loop every 3 minutes but script not sleep

I have a script for chat auto respond that uses while() to run, so it runs forever until it dies.
I want to be able to make it send a 'PING' message once every 3 minutes but still can do 'AUTO RESPOND' each message received.
The trouble is if i am using sleep(180) function for looping 'PING' message every 3 minute will make the 'AUTO RESPOND' every message be stop responding message because the script get sleep with sleep(180) function.
So what solution to make the script can do looping 'PING' message every 3 minutes but still can do 'AUTO RESPOND' every message at the same time.
What is possible ?
Did someone can help me with based on my script below ?
$this->connect();
while(!$this->isDisconnected()) {
$starts = $this->processUntil(array('message', 'session_start'));
foreach($starts as $go) {
switch($go[0]) {
case 'session_start':
$this->presence($status="Just Online !!!", $show="online");
break;
case 'message':
$filter = $show="online";
if($new['from'] == $filter) {
$sender = explode('#', $new['from']);
$this->message($new['from'], $body="AUTO RESPOND MESSAGE: Sorry $sender[0] Iam Not Here Right Now.", $type="chat");
}
$the_time = time();
$interval = 3*60;
while(true) {
if ($the_time + $interval >= time()) {
$this->message($myself, $body="PING !!!", $type="chat");
$the_time = time();
}
}
break;
}
}
}

PHP waiting for correct response with cURL

I don't know how to make this.
There is an XML Api server and I'm getting contents with cURL; it works fine. Now I have to call the creditCardPreprocessors state. It has 'in progress state' too and PHP should wait until the progess is finished. I tried already with sleep and other ways, but I can't make it. This is a simplified example variation of what I tried:
function process_state($xml){
if($result = request($xml)){
// It'll return NULL on bad state for example
return $result;
}
sleep(3);
process_state($xml);
}
I know, this can be an infite loop but I've tried to add counting to exit if it reaches five; it won't exit, the server will hang up and I'll have 500 errors for minutes and Apache goes unreachable for that vhost.
EDIT:
Another example
$i = 0;
$card_state = false;
// We're gona assume now the request() turns back NULL if card state is processing TRUE if it's done
while(!$card_state && $i < 10){
$i++;
if($result = request('XML STUFF')){
$card_state = $result;
break;
}
sleep(2);
}
The recursive method you've defined could cause problems depending on the response timing you get back from the server. I think you'd want to use a while loop here. It keeps the requests serialized.
$returnable_responses = array('code1','code2','code3'); // the array of responses that you want the function to stop after receiving
$max_number_of_calls = 5; // or some number
$iterator = 0;
$result = NULL;
while(!in_array($result,$returnable_responses) && ($iterator < $max_number_of_calls)) {
$result = request($xml);
$iterator++;
}

Libevent timeout loop exit

I'm having some difficulties getting the PHP libevent extension to break out of a loop on a timeout. Here's what I've got so far based on the demos on the PHP.net docs pages:
// From here: http://www.php.net/manual/en/libevent.examples.php
function print_line($fd, $events, $arg) {
static $max_requests = 0;
$max_requests++;
printf("Received event: %s after %s\n%s", implode(getEventFlags($events)), getTimer(), fgets($fd));
if ($max_requests == 10) {
// exit loop after 3 writes
echo " [EXIT]\n";
event_base_loopexit($arg[1]);
}
}
// create base and event
$base = event_base_new();
$event = event_new();
getTimer(); // Initialise time
$fd = STDIN;
event_set($event, $fd, EV_READ | EV_PERSIST, "print_line", array($event, $base));
event_base_set($event, $base);
event_add($event, 2000000);
event_base_loop($base);
// extract flags from bitmask
function getEventFlags ($ebm) {
$expFlags = array('EV_TIMEOUT', 'EV_SIGNAL', 'EV_READ', 'EV_WRITE', 'EV_PERSIST');
$ret = array();
foreach ($expFlags as $exf) {
if ($ebm & constant($exf)) {
$ret[] = $exf;
}
}
return $ret;
}
// Used to track time!
function getTimer () {
static $ts;
if (is_null($ts)) {
$ts = microtime(true);
return "Timer initialised";
}
$newts = microtime(true);
$r = sprintf("Delta: %.3f", $newts - $ts);
$ts = $newts;
return $r;
}
I can see that the timeout value passed to event_add effects the events passed to print_line(), if these events are any more than 2 seconds apart I get an EV_TIMEOUT instead of an EV_READ. What I want however is for libevent to call print_line as soon as the timeout is reached rather than waiting for the next event in order to give me the timeout.
I've tried using event_base_loopexit($base, 2000000), this causes the event loop to exit immediately without blocking for events. I've also tried passing EV_TIMEOUT to event_set, this seems to have no effect at all.
Has anyone managed to get this working before? I know that the event_buffer_* stuff works with timeouts, however I want to use the standard event_base functions. One of the PECL bugs talks about event_timer_* functions and these functions do exist on my system, however they're not documented at all.
Problem is in fgets() in:
printf("Received event: %s after %s\n%s", implode(getEventFlags($events)), getTimer(), fgets($fd));
This blocks processing and waits for data from STDIN (but there are none on timeout)
Change to something like that:
$text = '';
if ($events & EV_READ) {
$text = fgets($fd);
}
printf("Received event: %s after %s\n%s", implode(getEventFlags($events)), getTimer(), $text);

Categories