Skip to content

Commit

Permalink
minor update
Browse files Browse the repository at this point in the history
  • Loading branch information
AnourValar committed Oct 10, 2024
1 parent b255fe6 commit 7b77db6
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

namespace AnourValar\LaravelAtom\Exceptions;

class OptimisticTransactionException extends \Exception
class OptimisticException extends \Exception
{
}
3 changes: 2 additions & 1 deletion src/Providers/LaravelAtomServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ public function boot()
$this->publishes([__DIR__.'/../resources/lang/' => lang_path('vendor/laravel-atom')]);

// migrations
$this->loadMigrationsFrom(__DIR__.'/../database/migrations');
//$this->loadMigrationsFrom(__DIR__.'/../database/migrations');
$this->publishes([__DIR__.'/../database/migrations/' => database_path('migrations')], 'migrations');

// events
\Event::listen([TransactionCommitted::class, TransactionRolledBack::class], function ($event) {
Expand Down
19 changes: 1 addition & 18 deletions src/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,13 @@ public function lock(): void
{
$sha1 = sha1(serialize($this->canonizeArgs(func_get_args())));
$connection = \DB::connection($this->config['locks']['connection']);
$table = $this->config['locks']['table'];

$class = $this->config['locks']['strategies'][$this->config['locks']['strategy']];
(new $class())->lock($sha1, $connection, $table);
(new $class())->lock($sha1, $connection);

if ($this->lockHook) {
($this->lockHook)($sha1, func_get_args());
}
$this->cleanUp($connection, $table);
}

/**
Expand Down Expand Up @@ -240,21 +238,6 @@ protected function canonizeArgs($value)
return $value;
}

/**
* @param \Illuminate\Database\Connection $connection
* @param string $table
* @return void
*/
protected function cleanUp(\Illuminate\Database\Connection $connection, string $table): void
{
if (! mt_rand(0, 50)) {
$connection
->table($table)
->where('updated_at', '<=', date('Y-m-d H:i:s', strtotime('-5 days')))
->delete();
}
}

/**
* @param mixed $connection
* @return bool
Expand Down
28 changes: 28 additions & 0 deletions src/Strategies/OptimisticAdvisoryStrategy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace AnourValar\LaravelAtom\Strategies;

use Illuminate\Database\Connection;

class OptimisticAdvisoryStrategy implements StrategyInterface
{
/**
* @throws \AnourValar\LaravelAtom\Exceptions\OptimisticException
*
* {@inheritDoc}
* @see \AnourValar\LaravelAtom\Strategies\StrategyInterface::lock()
*/
public function lock(string $sha1, Connection $connection): void
{
if (! $connection->transactionLevel()) {
throw new \LogicException('Lock can be applied only inside transaction');
}

$id1 = crc32($sha1) - 2147483648;
$id2 = crc32(strrev($sha1)) - 2147483648;

if (! $connection->select('SELECT pg_try_advisory_xact_lock(:id1, :id2)', ['id1' => $id1, 'id2' => $id2])[0]->pg_try_advisory_xact_lock) {
throw new \AnourValar\LaravelAtom\Exceptions\OptimisticException();
}
}
}
19 changes: 9 additions & 10 deletions src/Strategies/OptimisticTransactionStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@
class OptimisticTransactionStrategy extends PessimisticTransactionStrategy
{
/**
* @throws \AnourValar\LaravelAtom\Exceptions\OptimisticTransactionException
* @throws \AnourValar\LaravelAtom\Exceptions\OptimisticException
*
* {@inheritDoc}
* @see \AnourValar\LaravelAtom\Strategies\PessimisticTransactionStrategy::lock()
*/
public function lock(string $sha1, Connection $connection, string $table): void
public function lock(string $sha1, Connection $connection): void
{
try {
parent::lock($sha1, $connection, $table);
parent::lock($sha1, $connection);
} catch (\Illuminate\Database\QueryException $e) {
if ($this->isLockException($e->getMessage())) {
throw new \AnourValar\LaravelAtom\Exceptions\OptimisticTransactionException();
throw new \AnourValar\LaravelAtom\Exceptions\OptimisticException();
}

throw $e;
Expand All @@ -28,24 +28,23 @@ public function lock(string $sha1, Connection $connection, string $table): void
/**
* @param string $sha1
* @param \Illuminate\Database\Connection $connection
* @param string $table
* @param bool $reTry
* @throws \Exception
* @return void
*/
protected function apply(string $sha1, Connection $connection, string $table, bool $reTry = true): void
protected function apply(string $sha1, Connection $connection, bool $reTry = true): void
{
$connection->beginTransaction();

try {
$record = $connection->table($table)->lock($this->getLock())->where('sha1', '=', $sha1)->first();
$record = $connection->table('locks')->lock($this->getLock())->where('sha1', '=', $sha1)->first();
} catch (\Illuminate\Database\QueryException $e) {
$connection->rollBack();
throw $e;
}

if ($record) {
$connection->table($table)->where('sha1', '=', $sha1)->update(['updated_at' => date('Y-m-d H:i:s')]);
$connection->table('locks')->where('sha1', '=', $sha1)->update(['updated_at' => date('Y-m-d H:i:s')]);

$connection->commit();
return;
Expand All @@ -57,7 +56,7 @@ protected function apply(string $sha1, Connection $connection, string $table, bo
}

try {
$connection->table($table)->insert(['sha1' => $sha1, 'updated_at' => date('Y-m-d H:i:s')]);
$connection->table('locks')->insert(['sha1' => $sha1, 'updated_at' => date('Y-m-d H:i:s')]);
$connection->commit();
} catch (\Illuminate\Database\QueryException $e) {
$connection->rollBack();
Expand All @@ -67,7 +66,7 @@ protected function apply(string $sha1, Connection $connection, string $table, bo
throw $e;
}

$this->apply($sha1, $connection, $table, false);
$this->apply($sha1, $connection, false);
}

/**
Expand Down
24 changes: 24 additions & 0 deletions src/Strategies/PessimisticAdvisoryStrategy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace AnourValar\LaravelAtom\Strategies;

use Illuminate\Database\Connection;

class PessimisticAdvisoryStrategy implements StrategyInterface
{
/**
* {@inheritDoc}
* @see \AnourValar\LaravelAtom\Strategies\StrategyInterface::lock()
*/
public function lock(string $sha1, Connection $connection): void
{
if (! $connection->transactionLevel()) {
throw new \LogicException('Lock can be applied only inside transaction');
}

$id1 = crc32($sha1) - 2147483648;
$id2 = crc32(strrev($sha1)) - 2147483648;

$connection->select('SELECT pg_advisory_xact_lock(:id1, :id2)', ['id1' => $id1, 'id2' => $id2]);
}
}
22 changes: 14 additions & 8 deletions src/Strategies/PessimisticTransactionStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,35 @@ class PessimisticTransactionStrategy implements StrategyInterface
* {@inheritDoc}
* @see \AnourValar\LaravelAtom\Strategies\StrategyInterface::lock()
*/
public function lock(string $sha1, Connection $connection, string $table): void
public function lock(string $sha1, Connection $connection): void
{
if (! $connection->transactionLevel()) {
throw new \LogicException('Lock can be applied only inside transaction');
}

$this->apply($sha1, $connection, $table);
$this->apply($sha1, $connection);

if (! mt_rand(0, 50)) {
$connection
->table('locks')
->where('updated_at', '<=', date('Y-m-d H:i:s', strtotime('-5 days')))
->delete();
}
}

/**
* @param string $sha1
* @param \Illuminate\Database\Connection $connection
* @param string $table
* @param bool $reTry
* @throws \Exception
* @return void
*/
protected function apply(string $sha1, Connection $connection, string $table, bool $reTry = true): void
protected function apply(string $sha1, Connection $connection, bool $reTry = true): void
{
$record = $connection->table($table)->lock($this->getLock())->where('sha1', '=', $sha1)->first();
$record = $connection->table('locks')->lock($this->getLock())->where('sha1', '=', $sha1)->first();

if ($record) {
$connection->table($table)->where('sha1', '=', $sha1)->update(['updated_at' => date('Y-m-d H:i:s')]);
$connection->table('locks')->where('sha1', '=', $sha1)->update(['updated_at' => date('Y-m-d H:i:s')]);

return;
}
Expand All @@ -44,7 +50,7 @@ protected function apply(string $sha1, Connection $connection, string $table, bo
$connection->beginTransaction();

try {
$connection->table($table)->insert(['sha1' => $sha1, 'updated_at' => date('Y-m-d H:i:s')]);
$connection->table('locks')->insert(['sha1' => $sha1, 'updated_at' => date('Y-m-d H:i:s')]);
$connection->commit();
} catch (\Illuminate\Database\QueryException $e) {
$connection->rollBack();
Expand All @@ -54,7 +60,7 @@ protected function apply(string $sha1, Connection $connection, string $table, bo
throw $e;
}

$this->apply($sha1, $connection, $table, false);
$this->apply($sha1, $connection, false);
}

/**
Expand Down
3 changes: 1 addition & 2 deletions src/Strategies/StrategyInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ interface StrategyInterface
*
* @param string $sha1
* @param \Illuminate\Database\Connection $connection
* @param string $table
* @throws \Exception
* @return void
*/
public function lock(string $sha1, Connection $connection, string $table): void;
public function lock(string $sha1, Connection $connection): void;
}
4 changes: 2 additions & 2 deletions src/database/migrations/2020_03_29_000000_create_locks.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*/
public function up()
{
Schema::connection(config('atom.locks.connection'))->create(config('atom.locks.table'), function (Blueprint $table) {
Schema::connection(config('atom.locks.connection'))->create('locks', function (Blueprint $table) {
$table->string('sha1', 40)->unique();
$table->timestamp('updated_at')->nullable()->index();
});
Expand All @@ -26,6 +26,6 @@ public function up()
*/
public function down()
{
Schema::connection(config('atom.locks.connection'))->dropIfExists(config('atom.locks.table'));
Schema::connection(config('atom.locks.connection'))->dropIfExists('locks');
}
};
11 changes: 6 additions & 5 deletions src/resources/config/atom.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
return [
'locks' => [
'connection' => null,
'strategy' => 'pessimistic_transaction',

'table' => 'locks',
'strategy' => 'pessimistic_advisory',

'strategies' => [
'pessimistic_transaction' => AnourValar\LaravelAtom\Strategies\PessimisticTransactionStrategy::class,
'optimistic_transaction' => AnourValar\LaravelAtom\Strategies\OptimisticTransactionStrategy::class,
'pessimistic_advisory' => AnourValar\LaravelAtom\Strategies\PessimisticAdvisoryStrategy::class,
'optimistic_advisory' => AnourValar\LaravelAtom\Strategies\OptimisticAdvisoryStrategy::class,

'pessimistic_transaction' => AnourValar\LaravelAtom\Strategies\PessimisticTransactionStrategy::class, // @deprecated
'optimistic_transaction' => AnourValar\LaravelAtom\Strategies\OptimisticTransactionStrategy::class, // @deprecated
],
],

Expand Down

0 comments on commit 7b77db6

Please sign in to comment.