Skip to content

[Spanner] No way to set timeout on queries #9336

Description

@taka-oyama

In v1, I was able to set a timeout for queries simply by passing requestTimeout to the SpannerClient.
In v2, this option was removed, and MIGRATING.md says to add timeoutMillis to the call options.
I added timeoutMillis to Database::execute(...) hoping it would be applied further down the code.
Unfortunately this option was ignored.

I believe the options needs to be passed on from Database::execute(...) -> Operation::execute(...) -> SpannerClient::executeStreamingSql(...) but it never got passed on because the code below that plucks the array does not contain timeoutMillis (and requestOptions).

$executeOptions = $this->pluckArray(['parameters', 'types'], $options);

I believe most of this code is shared in Transaction::execute(...) so I think the same thing applies to that as well.

Environment details

  • OS: Alpine Linux
  • PHP version: 8.4.23
  • Package name and version: google/cloud-spanner v2.10.0

Steps to reproduce

  1. Run the Code example below
  2. Should throw a DeadlineExceededException but doesn't.

Code example

<?php

require __DIR__ . '/vendor/autoload.php';

use Google\Cloud\Spanner\SpannerClient;
use Google\Cloud\Spanner\Transaction;
use Symfony\Component\Cache\Adapter\ArrayAdapter;

$projectId  = getenv('DB_SPANNER_PROJECT_ID')  ?: 'test-project';
$instanceId = getenv('DB_SPANNER_INSTANCE_ID') ?: 'test-instance';
$databaseId = getenv('DB_SPANNER_DATABASE_ID') ?: 'test-db';

$client = new SpannerClient([
    'projectId' => $projectId,
    'cacheItemPool' => new ArrayAdapter(),
]);

$instance = $client->instance($instanceId);

if (!$instance->exists()) {
    $config = $client->instanceConfiguration('emulator-config');
    $instance->create($config)->pollUntilComplete();
}

$database = $instance->database($databaseId);
$table = 'TimeoutTest';

if (!$database->exists()) {
    $instance->createDatabase($databaseId, [
        'statements' => [
            "CREATE TABLE $table (id INT64 NOT NULL, name STRING(10)) PRIMARY KEY (id)",
        ],
    ])->pollUntilComplete();
}

$sql = "SELECT * FROM $table";
iterator_to_array($database->execute($sql, ['timeoutMillis' => 1]));

That code should produce the following error.

Fatal error: Uncaught Google\Cloud\Core\Exception\DeadlineExceededException: {
    "message": "Deadline Exceeded",
    "code": 4,
    "status": "DEADLINE_EXCEEDED",
    "details": []
} in /project/vendor/google/cloud-core/src/RequestProcessorTrait.php:149

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions