Skip to content

Commit

Permalink
Improve unique constraint handling
Browse files Browse the repository at this point in the history
  • Loading branch information
timacdonald committed May 21, 2024
1 parent 9293fff commit 7ec00bd
Showing 1 changed file with 36 additions and 6 deletions.
42 changes: 36 additions & 6 deletions src/Drivers/DatabaseDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Database\Connection;
use Illuminate\Database\DatabaseManager;
use Illuminate\Database\UniqueConstraintViolationException;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Laravel\Pennant\Contracts\CanListStoredFeatures;
use Laravel\Pennant\Contracts\Driver;
use Laravel\Pennant\Events\UnknownFeatureResolved;
use Laravel\Pennant\Feature;
use RuntimeException;
use stdClass;

class DatabaseDriver implements CanListStoredFeatures, Driver
Expand Down Expand Up @@ -58,6 +60,13 @@ class DatabaseDriver implements CanListStoredFeatures, Driver
*/
protected $unknownFeatureValue;

/**
* The current retry depth for retrieving values from the database.
*
* @var int
*/
protected $retryDepth = 0;

/**
* The name of the "created at" column.
*
Expand Down Expand Up @@ -170,11 +179,21 @@ public function getAll($features): array
if ($inserts->isNotEmpty()) {
$now = Carbon::now();

$this->newQuery()->insert($inserts->map(fn ($insert) => [
...$insert,
static::CREATED_AT => $now,
static::UPDATED_AT => $now,
])->all());
try {
$this->newQuery()->insert($inserts->map(fn ($insert) => [
...$insert,
static::CREATED_AT => $now,
static::UPDATED_AT => $now,
])->all());
} catch (UniqueConstraintViolationException $e) {
if (++$this->retryDepth === 3) {
throw new RuntimeException('Unable to insert feature values into the database.', previous: $e);
}

return $this->getAll($features);
} finally {
$this->retryDepth = 0;
}
}

return $results;
Expand All @@ -197,7 +216,18 @@ public function get($feature, $scope): mixed
return false;
}

$this->insert($feature, $scope, $value);
try {
$this->insert($feature, $scope, $value);

} catch (UniqueConstraintViolationException $e) {
if (++$this->retryDepth === 2) {
throw new RuntimeException('Unable to insert feature value from the database.', previous: $e);
}

return $this->get($feature, $scope);
} finally {
$this->retryDepth = 0;
}

return $value;
});
Expand Down

0 comments on commit 7ec00bd

Please sign in to comment.