Skip to content

Commit 167a87b

Browse files
fixed races during process row creation using Laravel's upsert. (#23)
Co-authored-by: Paul Rogers <[email protected]>
1 parent f4a5ccc commit 167a87b

File tree

1 file changed

+12
-12
lines changed

1 file changed

+12
-12
lines changed

src/ProcessStamp.php

+12-12
Original file line numberDiff line numberDiff line change
@@ -59,21 +59,21 @@ public static function firstOrCreateByProcess(array $process, ?string $hash = nu
5959
$parent = static::firstOrCreateByProcess(static::getProcessName($process['type'], $process['parent_name']));
6060
}
6161

62-
$stamp = static::where('hash', $hash)->first();
63-
64-
/*
65-
* If stamp does not exist in the database yet, go ahead and obtain a lock to create it.
66-
* 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.
67-
*/
68-
if (! $stamp) {
69-
Cache::lock('process-stamps-hash-create-' . $hash, 10)->get(function () use (&$stamp, $hash, $process, $parent) {
70-
$stamp = static::firstOrCreate(['hash' => $hash], [
62+
// Workaround races with `firstOrCreate` by leveraging a no-change upsert.
63+
// NOTE: Not using `insertOrIgnore` because of possible side-effects.
64+
static::upsert(
65+
[
66+
[
67+
'hash' => $hash,
7168
'name' => trim($process['name']),
7269
'type' => $process['type'],
7370
'parent_id' => optional($parent)->getKey(),
74-
]);
75-
});
76-
}
71+
],
72+
],
73+
['hash'], // Should be unique to hash.
74+
[] // Update nothing.
75+
);
76+
$stamp = static::where('hash', $hash)->first();
7777

7878
return $stamp;
7979
}

0 commit comments

Comments
 (0)