From 106994d99f077290e70aa549f6f5402149e6ff83 Mon Sep 17 00:00:00 2001 From: "quentin.schmick" Date: Thu, 24 Feb 2022 12:12:12 -0500 Subject: [PATCH] Updated composer.json with contributors; Updated ProcessStamp firstOrCreateByProcess to wrap entire process in cache --- .github/workflows/tests.yml | 4 +-- composer.json | 25 ++++++++++------ src/ProcessStamp.php | 60 ++++++++++++++++++++++--------------- 3 files changed, 54 insertions(+), 35 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7933b62..ba54542 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -23,8 +23,8 @@ jobs: strategy: fail-fast: true matrix: - php: [7.3, 7.4] - stability: [prefer-lowest, prefer-stable] + php: [7.3, 7.4, 8.0, 8.1] + stability: [prefer-stable] name: PHP ${{ matrix.php }} - ${{ matrix.stability }} diff --git a/composer.json b/composer.json index b8e7989..05827fd 100644 --- a/composer.json +++ b/composer.json @@ -3,6 +3,8 @@ "description": "Logs which process created or modified a record", "keywords": [ "orisintel", + "always open", + "always-open", "laravel-process-stamps", "laravel", "logging" @@ -12,24 +14,29 @@ "authors": [ { "name": "Tom Schlick", - "email": "tschlick@orisintel.com", "role": "Developer" }, { - "name": "ORIS Intelligence", - "email": "developers@orisintel.com", - "homepage": "https://orisintel.com", + "name": "Quentin Schmick", + "email": "qschmick@gmail.com", + "role": "Developer" + }, + { + "name": "Lucas Graciano", + "role": "Developer" + }, + { + "name": "Always Open", + "homepage": "https://github.com/always-open", "role": "Organization" } ], "require": { - "php": "^7.3", - "laravel/framework": "^8.0" + "php": "^7.3|^8.0", + "laravel/framework": "^8.0|^9.0" }, "require-dev": { - "doctrine/dbal": "^2.9", - "larapack/dd": "^1.0", - "mockery/mockery": "~1.0", + "doctrine/dbal": "^2.9|^3.0", "orchestra/testbench": "^6.0", "phpunit/phpunit": "^9.0" }, diff --git a/src/ProcessStamp.php b/src/ProcessStamp.php index a19c70f..35c02d1 100644 --- a/src/ProcessStamp.php +++ b/src/ProcessStamp.php @@ -2,6 +2,7 @@ namespace OrisIntel\ProcessStamps; +use Exception; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -38,10 +39,12 @@ public function getTable() : string } /** - * @param array $process + * @param array $process * @param null|string $hash * * @return ProcessStamp + * + * @throws Exception */ public static function firstOrCreateByProcess(array $process, ?string $hash = null) : self { @@ -53,29 +56,38 @@ public static function firstOrCreateByProcess(array $process, ?string $hash = nu $hash = static::makeProcessHash($process); } - $parent = null; - - if (config('process-stamps.resolve_recursive') && ! empty($process['parent_name'])) { - $parent = static::firstOrCreateByProcess(static::getProcessName($process['type'], $process['parent_name'])); - } - - $stamp = static::where('hash', $hash)->first(); - - /* - * If stamp does not exist in the database yet, go ahead and obtain a lock to create it. - * This specifically doesn't lock as the first step to avoid all calls obtaining a lock from the cache if the item already exists in the DB. - */ - if (! $stamp) { - Cache::lock('process-stamps-hash-create-' . $hash, 10)->get(function () use (&$stamp, $hash, $process, $parent) { - $stamp = static::firstOrCreate(['hash' => $hash], [ - 'name' => trim($process['name']), - 'type' => $process['type'], - 'parent_id' => optional($parent)->getKey(), - ]); - }); - } - - return $stamp; + return retry( + 2, + function () use ($hash, $process) { + $lock = Cache::lock('process-stamps-hash-create-' . $hash, 10); + $lock->block(5); + + $parent = null; + + if (config('process-stamps.resolve_recursive') && ! empty($process['parent_name'])) { + $parent = static::firstOrCreateByProcess(static::getProcessName($process['type'], $process['parent_name'])); + } + + $stamp = static::where('hash', $hash)->first(); + + if (! $stamp) { + /* + * If stamp does not exist in the database yet, go ahead and obtain a lock to create it. + * This specifically doesn't lock as the first step to avoid all calls obtaining a lock from the + * cache if the item already exists in the DB. + */ + $stamp = static::firstOrCreate(['hash' => $hash], [ + 'name' => trim($process['name']), + 'type' => $process['type'], + 'parent_id' => optional($parent)->getKey(), + ]); + } + + $lock->release(); + + return $stamp; + }, + ); } /**