Exponential Backoff With Google API PHP Client Library - php

I am running a web app to get a list of users with Google API PHP Client Library 2.0.3. and save them to a CSV file and at the same time, I am tracking the process on screen. The code I am using is the following:
$pageToken = null;
$optParams = array(
"customer" => "my_customer",
"maxResults" => 500,
"orderBy" => "email",
"sortOrder" => "ASCENDING"
);
try {
$usernum = 0;
do {
if ($pageToken){
$optParams['pageToken'] = $pageToken;
}
$results = $service->users->listUsers($optParams);
$pageToken = $results->getNextPageToken();
$users = $results->getUsers();
foreach ($users as $user) {
$usernum++;
$csvfileusers = array($user->getPrimaryEmail());
fputcsv($savecsv, $csvfileusers);
$usersemails = $user->getPrimaryEmail();
print "<li>".$usernum." - <font color='#9dd7fb'>".$usersemails."</font></li>";
}
} while($pageToken);
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
Everything works fine. The problem is that from time to time I am getting { error: { errors: [ { domain: global, reason: backendError, message: Service unavailable. Please try again } ], code: 503, message: Service unavailable. Please try again } }
I know this means that I am sending requests to Google Server too fast hence I need to implement an exponential backoff solution. My problem is that I don't know how to do that. Would someone be kind enough to provide me an example on how to do that using the PHP Client Library? I know that I might be able to figure this out at the long term but if I can get some help I will greatly appreciate it.

Unfortunately, the documentation is lacking for the actual backoff implementation. However, the Google_Task_Runner class outlines the backoff implementation process. You can see how it does it here.
However, based on what you're doign you don't actually want to implement a exponential backoff procedure in general networking terms. You're really wanting to just throttle the request so you don't slam the API. Depending on how many $pageToken you're iterating over, you could just do a sleep before doing the next while iteration.
Additionally, what does $pageToken = $results->getNextPageToken(); become after one request? Becuase you're setting that from the response rather than decrementing it programatically, which may be causing an infinute loop or something of that nature.

So after 20 days of trying and investigating and thanks to the information provided by #kyle, I came up with this exponential backoff solution.
$attemptNum = 1; // retry attempt
$expBackoff = false; // exponential backoff rety indicator
do {
if($attemptNum <= 4) {
try {
$usernum = 1;
do {
if ($pageToken){
$optParams['pageToken'] = $pageToken;
}
$results = $service->users->listUsers($optParams);
$pageToken = $results->getNextPageToken();
$users = $results->getUsers();
foreach ($users as $user) {
$csvfileusers = array($user->getPrimaryEmail());
fputcsv($savecsv, $csvfileusers);
$usersemails = $user->getPrimaryEmail();
print "<li>".$usernum." - <font color='#9dd7fb'>".$usersemails."</font></li>";
$usernum++;
}
} while($pageToken);
} catch (Exception $e) {
$err503ReasonA = "Service unavailable"; // Service unavailable.
$err503ReasonB = "Backend Error"; //Backend Error
$exception = $e->getMessage();
if(strpos($exception, $err503Reason) !== false || strpos($exception, $err503ReasonB) !== false){
$expBackoff = true;
$sleeptime = $retrynum * 1; //retrynum * seconds
sleep($sleeptime);
$retrynum++;
} else {
$expBackoff = false;
print "There was an error -> $exception";
}
}
} else {
$expBackoff = false;
}
} while ($expBackoff);
I have been trying this solution for two days now and it has worked like a charm. Hopefully this might be helpful for someone else. I´m happy now. :)

Related

php foreach - try catch, I don't know why I get 500 Error. I have call activeMQ

php foreach - try catch, I don't know why I get 500 Error.
in my code, I used this way to call activeMQ, but I will get 500 Error. I don't know what's happen.
This code only run to $url = "tcp://".$url; cannot run to uder try{}. Where is issues?
$stomp = null;
$mqUser='aaa';
$mqPasswd='aaa';
foreach ($urls as $url) {
$url = "tcp://".$url;
//echo $url." stomp status: null;<br />";
try {
$stomp = new Stomp($url);
} catch(Exception $e) {
}
if ($stomp) {
break;
}
}

how to stop PHP to catch errors in an array loop?

I am trying to loop through an array of four servers. I am trying to find a user on those servers. I am able to see the program works but PHP throws errors from the servers it cannot find from the array. Could someone help how to avoid those errors?
$ID = '1234';
$server_list = array("example1.com", "example2.com", "example3.com");
function serverQuery($server_array, $ID){
foreach ($server_array as $value) {
$host = $value;
try{
include('info.php');
$response = $client->getUser(array("name" => ID))->return;
//print_r($response);
}catch (Exception $e){
echo "Print the error";
}
}
}
Every time I search the user, it did fine in one of the servers but "Print the Error" is also printed along with it. Please help.
Thanks.

How to end a php functionality if their is no response in some time

I'm using neverbounce api in my project to check the email is valid or not. Usually neverbounce returning 5 result codes as a response result codes.In this, we'll get response for status code 0 to 3 in almost 3-4 seconds. but the last status code for unknown emails took almost 30 seconds to get the result. They are providing a timeout option in the API itself but it is not working. I contacted the support team but no use still the issue exists.
So I need to exit the functionality and return a default value if the response didn't receive from API. I tried by using set_time_limit(5); but it didn't work.Any help is appreciable.
This is the code that we're using
$res = 0;
try {
// Make verification request, specify optional $max_execution_time
$result = \NeverBounce\Single::check($email, // Email to verify
true, // Address info
true, // Credits info
5// Timeout in seconds
);
if (!empty($result->result_integer)) {
$res = $result->result_integer;
} else {
$res = 0;
}
// Call wrapper method here
} catch (\NeverBounce\Errors\AuthException $e) {
// The API credentials used are bad, have you reset them recently?
$res = 0;
} catch (\NeverBounce\Errors\BadReferrerException $e) {
// The script is being used from an unauthorized source, you may need to
// adjust your app's settings to allow it to be used from here
$res = 0;
} catch (\NeverBounce\Errors\ThrottleException $e) {
// Too many requests in a short amount of time, try again shortly or adjust
// your rate limit settings for this application in the dashboard
$res = 0;
} catch (\NeverBounce\Errors\HttpClientException $e) {
// An error occurred processing the request, something may be wrong with
// the Curl PHP extension or your network
$res = 0;
} catch (\NeverBounce\Errors\GeneralException $e) {
// A non recoverable API error occurred check the message for details
$res = 0;
} catch (Exception $e) {
// An error occurred unrelated to the API
$res = 0;
}
return $res;

PHP Gmail API - Send draft

How may I send a draft with GMAIL API and OAuth2.0 via PHP?
In the official docs there is no reference on how to achieve this with PHP.
Based on the Java example, I tried:
$drafts = array();
try {
$draftsResponse = $service->users_drafts->listUsersDrafts('me');
if ($draftsResponse->getDrafts()) {
$drafts = array_merge($drafts, $draftsResponse->getDrafts());
}
}
catch (Exception $e) {
echo 'An error occurred: ' . $e->getMessage();
}
var_dump($drafts);
foreach ($drafts as $draft) {
echo 'Draft with ID: ' . $draft->getId() . '<br/>';
$abc = $service->users_drafts->send('me',$draft->getId());
var_dump($abc);
}
But of course I am doing something wrong, because it is not working. The first var_dump() returns all drafts. But nothing else happens after that.
Can you please help me?
You have to create a new Google_Service_Gmail_Draft instance and use that, not just supply the id:
foreach ($drafts as $draft) {
$d = new Google_Service_Gmail_Draft();
$d->setId($draft->getId());
$service->users_drafts->send('me', $d);
}

Collect all downtime start times to reach total downtime at end of month - PHP

I have a cron job running every 10-15 minutes pinging minecraft servers in my database, and if one of them returns "offline", the database records the time this happened and sticks in it the lastDT (last downtime) table. My question is, how can I collect all of the times, and at the end of each month figure out the average downtime (if any). I assume this would be ((totalMinutesInMonth-totalMinutesOfDT)*100). Is there a way to do this? To get a better idea of what I'm dealing with, here is some code to reference:
<?php
require_once './inc/connectToDB.php';
date_default_timezone_set('UTC');
session_start();
try {
$collectServers = $database->prepare('SELECT * FROM servers');
$collectServers->execute();
$serversDat = $collectServers->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
error_log($e->getMessage());
exit();
}
foreach ($serversDat as $server) {
try {
$remoteCon = #fsockopen(#gethostbyname($server['address']),$server['port'],$errno,$errstr,1);
$connected = false;
if (#is_resource($remoteCon)) { $connected = true; #fclose($remoteCon); }
if ($connected) { $serverStat = 'Online'; } else { $serverStat = 'Offline'; }
if ($serverStat == 'Offline') {
$downTime=date('H:i:s',time());
} else {
$downTime=0;
}
$reinsert = $database->prepare('UPDATE servers SET status=:status,lastPing=:time,lastDT=:lastdt WHERE id=:id');
$reinsert->bindValue(':id',$server['id'],PDO::PARAM_INT);
$reinsert->bindValue(':status',$serverStat,PDO::PARAM_STR);
$reinsert->bindValue(':time',date('H:sa T',time()),PDO::PARAM_STR);
$reinsert->bindValue(':lastdt',$downTime,PDO::PARAM_STR);
$reinsert->execute();
} catch (PDOException $e) {
error_log($e->getMessage());
exit();
}
}
unset($database);
exit();
?>
The database table looks like:
(http://i.imgur.com/0ypc99g.png)
If I can provide more info, I'd be glad to do so. Not sure what to do from here, however. Thanks in advance.
EDIT: If anyone has any idea how to do this more efficiently, I'm all for rewriting. This is not working out for me.
It seems like finding the time the server went down is only half of the equation. You will also need to know when the server came back up.
Down at 10:00AM, Up at 10:15AM equals 15min downtime.
You will need to store that in the database somewhere. That isn't solution, but it does seem like the next step.

Categories