If you set the requestTimeout on the Subscription->pull() call, the connection does not seem to get terminated properly, and the server will still send a message to the terminated connection. If you have the timeout set to something like 10 seconds and continuously loop over the pull() call, the message might not actually get to the client for a long time because it will get sent to connections that were terminated by the client, but not the server.
Please the logs below. One log is for publishing messages and one is for receiving messages. As you can see, if the message is sent after the first pull() call begins and before it reaches the timeout, it is delivered as expected. However, the second message is sent after the next pull() call times out, and does not actually get delivered until some time later. Presumably, it got sent to the first connection which was already terminated by the client. The awk deadline on the subscription is 10s, and this becomes even more problematic if the requestTimeout is equal to or less than the awk deadline as the message never seems to reach the script until you stop it, wait at least 90s for server to finish all pull requests, and restart the script.
If the requestTimeout parameter is omitted, the pull() request goes the entire 90s duration, and it properly receives messages every time.
I'm not sure if this is a bug in the way the pull request is terminated, or if PubSub has an issue with clients terminating connections, but the documentation for the returnImmediately parameter under the pull request API explicitly says that the client may cancel the request.
https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.subscriptions/pull
$ php gps-send.php
6:24:15 - Published message with id:77937868586577 to projects/.../topics/test_topic
$ php gps-send.php
6:24:33 - Published message with id:77938042888680 to projects/.../topics/test_topic
$ php gps-pull.php
6:24:13 - Starting pull from projects/.../subscriptions/test_sub
6:24:15 - Got messages from projects/.../subscriptions/test_sub
6:24:16 - Ack'd message -> 77937868586577 -> data: Test message
6:24:16 - Starting pull from projects/.../subscriptions/test_sub
6:24:31 - Timeout reached
6:24:31 - Starting pull from projects/.../subscriptions/test_sub
6:24:44 - Got messages from projects/.../subscriptions/test_sub
6:24:44 - Ack'd message -> 77938042888680 -> data: Test message
First message gets delivered 1s after it is sent, the second message is delivered after 11s. Presumably it was sent to the first (already terminated) connection, never got awk'd by the client, and got resent to the second connection. The requestTimeout is set to 15s in this example, and awk deadline is 10s.
These are the two scripts I was using.
gps-send.php
use Google\Cloud\PubSub\PubSubClient;
require 'vendor/autoload.php';
$pubSub = new PubSubClient([
'projectId' => '...',
'keyFilePath' => '...'
]);
$topic = $pubSub->topic('test_topic');
$result = $topic->publish([
'data' => 'Test message'
]);
echo sprintf("%s - Published message with id:%s to %s\n", date('G:i:s'), $result['messageIds'][0], $topic->name());
gps-pull.php
use Google\Cloud\Core\Exception\ServiceException;
use Google\Cloud\PubSub\PubSubClient;
require 'vendor/autoload.php';
$pubSub = new PubSubClient([
'projectId' => '...',
'keyFilePath' => '...'
]);
$subscription = $pubSub->subscription('test_sub');
while(true) {
try {
echo sprintf("%s - Starting pull from %s\n", date('G:i:s'), $subscription->name());
$messages = $subscription->pull([
'maxMessages' => 1,
'requestTimeout' => 10,
]);
echo sprintf("%s - Got messages from %s\n", date('G:i:s'), $subscription->name());
foreach ($messages as $message) {
$subscription->acknowledge($message);
echo sprintf("%s - Ack'd message -> %s -> data: %s\n", date('G:i:s'), $message->id(), $message->data());
}
} catch (ServiceException $e) {
echo sprintf("%s - Timeout reached\n", date('G:i:s'));
}
}
If you set the
requestTimeouton the Subscription->pull() call, the connection does not seem to get terminated properly, and the server will still send a message to the terminated connection. If you have the timeout set to something like 10 seconds and continuously loop over the pull() call, the message might not actually get to the client for a long time because it will get sent to connections that were terminated by the client, but not the server.Please the logs below. One log is for publishing messages and one is for receiving messages. As you can see, if the message is sent after the first pull() call begins and before it reaches the timeout, it is delivered as expected. However, the second message is sent after the next pull() call times out, and does not actually get delivered until some time later. Presumably, it got sent to the first connection which was already terminated by the client. The awk deadline on the subscription is 10s, and this becomes even more problematic if the
requestTimeoutis equal to or less than the awk deadline as the message never seems to reach the script until you stop it, wait at least 90s for server to finish all pull requests, and restart the script.If the
requestTimeoutparameter is omitted, the pull() request goes the entire 90s duration, and it properly receives messages every time.I'm not sure if this is a bug in the way the pull request is terminated, or if PubSub has an issue with clients terminating connections, but the documentation for the
returnImmediatelyparameter under the pull request API explicitly says that the client may cancel the request.https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.subscriptions/pull
First message gets delivered 1s after it is sent, the second message is delivered after 11s. Presumably it was sent to the first (already terminated) connection, never got awk'd by the client, and got resent to the second connection. The
requestTimeoutis set to 15s in this example, and awk deadline is 10s.These are the two scripts I was using.
gps-send.php
gps-pull.php