Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

For a few days I saw that notification sending does't work #66

Closed
yourchoice opened this issue Dec 14, 2016 · 13 comments
Closed

For a few days I saw that notification sending does't work #66

yourchoice opened this issue Dec 14, 2016 · 13 comments

Comments

@yourchoice
Copy link

I have around 2000 users subscribed. I used version v1.3.2.

Push notif. worked well when I had around 1000 users. For a few days I saw that nothing received.

I have log file of notification sending. These appear as sent, but nothing received.

Here is an example:

#2016-12-14 11:00:01

I have returned bool(true) for all users around (2000), but seems that they not received.

This is a section of code that a few days ago worked:

$client = new \Buzz\Client\MultiCurl();//$client = new \Buzz\Client\Curl();
$client->setOption(CURLOPT_CAINFO, $this->certKeysPath.'cacert.pem');
$webPush = new WebPush($this->webPushAuth, $this->webPushDefaultOptions, null, $client);
....
while (get users from db) {
   //send all notifications in a single push					
   $r = $webPush->sendNotification(
       $dao_wpn_user->wpn_user_endpoint,
	json_encode($notif_list),
	$dao_wpn_user->wpn_user_key_pub,
	$dao_wpn_user->wpn_user_key_auth
	//, true //do flush
    );
    //write log
    $this->wpnLog($dao_wpn_user->toArray(), $notif_list, $r);
}
$webPush->flush();
....

Please, any idea how I can debug that? Regarding google dev console or firebase, exists there a way to can see what notif. are sent ?

@Minishlink
Copy link
Member

The tests are still passing, so there might have been a change in your service worker on your end?

Try looking at the Chrome dev console targeting your service worker, to see if the push event is actually received.

@yourchoice
Copy link
Author

I think service wroker is ok, because I can send manually.

When send via cron job to 2000 users, for all i have bool(true), but user not receive notification. I have a log in DB for displayed notifications. Or example: me as user in cron appear with bool(true) but not receive. When sent manually not receive,

Strange is that this worked well a few days ago.

@Minishlink
Copy link
Member

Oh, right, I looked at your code and noticed you were not actually flushing inside the loop (the parameter is commented out). So basically, you're logging if the notification has been successfully queued, but not sent, so it's always true! ;)

You may have done some modifications to your code for testing MultiCurl, as I see some code commented out. It's best to delete these commented out codes, you may have spotted your error earlier.

You have to check the result of flush().

$client = new \Buzz\Client\MultiCurl();
$client->setOption(CURLOPT_CAINFO, $this->certKeysPath.'cacert.pem');
$webPush = new WebPush($this->webPushAuth, $this->webPushDefaultOptions, null, $client);
....
while (get users from db) {
   // queue notifications	
   $webPush->sendNotification(
       $dao_wpn_user->wpn_user_endpoint,
	json_encode($notif_list),
	$dao_wpn_user->wpn_user_key_pub,
	$dao_wpn_user->wpn_user_key_auth
    );
}

// send queued notifications in parallel thanks to MultiCurl
$r = $webPush->flush();

// if there has been an error
if (is_array($r)) {
  foreach ($r as $result) {
     // $result is true if successful
     // if not it's an array containing several info like endpoint, if it's expired (so that you can delete it)...
  }
}

@yourchoice
Copy link
Author

Yes, seems that there are a lot of errors on send notifitifcations.

Total: 3043 users.

For 65 users i have success bool(true).

For 133 users I have error status code 410.

HTTP/1.1 410 Gone ;
Access-Control-Allow-Headers: content-encoding,encryption,crypto-key,ttl,encryption-key,content-type,authorization ;
Access-Control-Allow-Methods: POST ;
Access-Control-Allow-Origin: * ;
Access-Control-Expose-Headers: location,www-authenticate ;
Content-Type: application/json ;
Date: Thu, 15 Dec 2016 11:02:03 GMT ;
Content-Length: 154 ;
Connection: keep-alive

{"errno": 106, "message": "No such subscription", "code": 410, "more_info": "http://autopush.readthedocs.io/en/latest/http.html#error-codes", "error": ""}

Error expired: 1

For other 2845 I have returned array, but with no data.

@Minishlink
Copy link
Member

With no data? That is most surprising. Could you var_dump one of those 2845 results please?

The 65 ones are fine. And the 133 ones are normal, endpoints expire at some point, when users don't come back to the website for example.

@yourchoice
Copy link
Author

Sorry for the late answer. Just now i had access to check again.

I tried to send with flush one by one and seems that notifications was sent. There was just a few with expired=1 (around 170 from 4815):

while (get users from db) {
   // queue notifications	
   $result1 = $webPush->sendNotification(
       $dao_wpn_user->wpn_user_endpoint,
	json_encode($notif_list),
	$dao_wpn_user->wpn_user_key_pub,
	$dao_wpn_user->wpn_user_key_auth,
        true
    );
}

Problem here was that to send notifications to around 4000 users take around 2 hours.

Because take too many time to send, I tried again with flush at the end:

while (get users from db) {
   // queue notifications	
   $result1 = $webPush->sendNotification(
       $dao_wpn_user->wpn_user_endpoint,
	json_encode($notif_list),
	$dao_wpn_user->wpn_user_key_pub,
	$dao_wpn_user->wpn_user_key_auth
    );
    // i debug $result1 and was bool(true) for all
}

$rf = $webPush->flush();
if (is_array($rf)) {
    foreach ($rf as $result2) {					
	if($result2!==true) {//if not bool(true), then means error	
	    $this->wpnErrLog($result2);//write log into DB and in a file
            //i debug $result2 and for many I have strange data (total: 4661 rows)
        }
    }
}

Most of the notification was not sent, ... me and others with that I checked not received. I have and a log for displayed notifications, and seems that just a few was received, around 154.

If you look into code I noted $result1 into while loop, and $result2 after flush.

$result1: was bool(true) for all.
$result2:
- status code 410 (154 rows),
- NULL data for header, status_code, content, expired (4507 rows)

To be sure that there is not a DB insert problem I write logs and in a file.

For the most of the user this is the data stored as log:

#2016-12-20 12:07:32

Can you help me to understand what's happen there?

If I try to flush on each 100 users, can be a solution ?

$counter = 0;
while (get users from db) {
    $counter++;
   // queue notifications	
   $webPush->sendNotification(
       $dao_wpn_user->wpn_user_endpoint,
	json_encode($notif_list),
	$dao_wpn_user->wpn_user_key_pub,
	$dao_wpn_user->wpn_user_key_auth
    );
    if($counter==100) {
       $r = $webPush->flush();
    }
}

Can you explain what exactly is happen in code when do a flush ?

Thanks

@Minishlink
Copy link
Member

It looks like curl or Buzz is having difficulties when there are too many queued requests. I'll investigate this. I may switch to Guzzle. In the meantime, you're right that flushing every 100 users should mitigate the issue. Let me know it it works well.

When you flush, WebPush does all the encryption process of every queued notifications and prepares all the associated requests. If you haven't MultiCurl, it will send the requests one by one during this iteration. If you have it, the requests will be sent in parallel after the iteration. Then WebPush iterates over the responses and returns an array with added keys like expired and endpoint.

@yourchoice
Copy link
Author

A question

$counter = 0;
while (($user=$dao->fetch())==true) {
    $r = $webPush->sendNotification($user['endpoint'], json_encode($notif_list), $user['key_pub'], $['key_auth']);
    if($r===true) {
       ... //store notification as sent to $user['id'];
    }
    else {
       ...//store err log for $user['id'];
    }

    if($counter>0 && $counter%100==0) {
         $arr_rf = $webPush->flush();
          foreach ($arr_rf as $rf) {
            //I thought that $rf from here must to be same with $r get above from $r = $webPush->sendNotification, but seems that $r is anytime bool(true)
          }
    }
}//end while

 $arr_rf = $webPush->flush();
    foreach ($arr_rf as $rf) {
         ...//
    }
}

Question is: if there exists a way to use just result $r = $webPush->sendNotification(....) instead $rf (result flush) after flush, because for $r I have many info regarding $user ?

I ask because in my last run , I saw that $r = $webPush->sendNotification(....) in loop returned just bool(true), and errors appear just in flush (at the end).

I'm interested to use $r and not $rf in flush , because in while I have $user['id'], and for $rf I must to use endpoint to get $user_id from DB. $user_id (int) is faster that $user_endpoint for db operations.

@Minishlink
Copy link
Member

Notifications are sent in parallel in batches of 100, and you can look at the errors with a 100 keys arrays:

$counter = 0;
while (($user=$dao->fetch())==true) {
    $webPush->sendNotification($user['endpoint'], json_encode($notif_list), $user['key_pub'], $['key_auth']);

    if($counter>0 && $counter%100==0) {
         $arr_rf = $webPush->flush();
          foreach ($arr_rf as $rf) {
             // handle error
          }
    }
}//end while

Note that in your code, the X notifications after your last batch of 100 will not be sent, you should fix your code.

Notifications are sent one by one, so you can look at each error one at a time:

while (($user=$dao->fetch())==true) {
    $r = $webPush->sendNotification($user['endpoint'], json_encode($notif_list), $user['key_pub'], $['key_auth'], true);
    if($r===true) {
       ... //store notification as sent to $user['id'];
    }
    else {
       ...//store err log for $user['id'];
    }
}//end while

You can't do both as you can't get the result of a request before it has been sent.

@Minishlink
Copy link
Member

Please let me know if you still have issues. Happy new year.

@yourchoice
Copy link
Author

Happy new year!

Seems that notifications sent in batch of 100 working. Regarding my code, "last batch", after loop (while) I do again $arr_rf = $webPush->flush();

Thank You

@yourchoice
Copy link
Author

A question regarding "composer require minishlink/web-push". Exists there a parameter that to not add in folder vendor/.../ examples and doc for all libs?

@Minishlink
Copy link
Member

I'm not sure about this, but I don't think so. Try asking at composer/composer. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants