Skip to content

Commit b994bff

Browse files
authored
Merge pull request #227 from keboola/zajca/inc_25140/retry
INC 25140 retry on case of specific snowflake error
2 parents adcd5bf + 3f3fa21 commit b994bff

1 file changed

Lines changed: 42 additions & 4 deletions

File tree

src/Connection/Snowflake/SnowflakeStatement.php

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77
use Doctrine\DBAL\Driver\Statement;
88
use Doctrine\DBAL\ParameterType;
99
use Keboola\TableBackendUtils\Connection\Exception\DriverException;
10+
use Retry\BackOff\ExponentialBackOffPolicy;
11+
use Retry\BackOff\ExponentialRandomBackOffPolicy;
12+
use Retry\BackOff\UniformRandomBackOffPolicy;
13+
use Retry\Policy\CallableRetryPolicy;
14+
use Retry\Policy\SimpleRetryPolicy;
15+
use Retry\RetryProxy;
1016
use Throwable;
1117

1218
class SnowflakeStatement implements Statement
@@ -16,6 +22,8 @@ class SnowflakeStatement implements Statement
1622
*/
1723
private $dbh;
1824

25+
private RetryProxy $retry;
26+
1927
/**
2028
* @var resource
2129
*/
@@ -31,8 +39,30 @@ class SnowflakeStatement implements Statement
3139
/**
3240
* @param resource $dbh database handle
3341
*/
34-
public function __construct($dbh, string $query)
42+
public function __construct($dbh, string $query, RetryProxy|null $retry = null)
3543
{
44+
if ($retry === null) {
45+
$this->retry = new RetryProxy(
46+
new CallableRetryPolicy(
47+
function (Throwable $e): bool {
48+
if (str_contains($e->getMessage(), 'SYSTEM$ALLOWLIST')) {
49+
// Retry in case of SYSTEM$ALLOWLIST error #prod_24_7___inc_25140
50+
// this is usually accompanied with SNFLK incidents
51+
// or can happen in case hostname is wrong
52+
return true;
53+
}
54+
return false;
55+
},
56+
5, // 5 attempts
57+
),
58+
new UniformRandomBackOffPolicy(
59+
3_000, // 3 seconds
60+
10_000, // 10 seconds
61+
),
62+
);
63+
} else {
64+
$this->retry = $retry;
65+
}
3666
$this->dbh = $dbh;
3767
$this->query = $query;
3868
$this->stmt = $this->prepare();
@@ -43,7 +73,10 @@ public function __construct($dbh, string $query)
4373
*/
4474
private function prepare()
4575
{
46-
$stmt = @odbc_prepare($this->dbh, $this->query);
76+
/** @var resource|false $stmt */
77+
$stmt = $this->retry->call(function () {
78+
return @odbc_prepare($this->dbh, $this->query);
79+
});
4780
if (!$stmt) {
4881
throw DriverException::newFromHandle($this->dbh);
4982
}
@@ -82,8 +115,13 @@ public function execute($params = null): Result
82115
}
83116

84117
try {
85-
odbc_execute($this->stmt, $this->repairBinding($this->params));
86-
} catch (Throwable $e) {
118+
$this->retry->call(function () {
119+
odbc_execute(
120+
$this->stmt,
121+
$this->repairBinding($this->params),
122+
);
123+
});
124+
} catch (Throwable) {
87125
throw DriverException::newFromHandle($this->dbh);
88126
}
89127

0 commit comments

Comments
 (0)