ldc-gen-game-web/app/Jobs/ProcessUniqueCode.php

122 lines
3.3 KiB
PHP
Raw Normal View History

<?php
2026-10-02 12:09:46 +02:00
declare(strict_types=1);
namespace App\Jobs;
2023-12-05 12:33:25 +01:00
use App\Mail\Jobs\CodeGenerationSucceed;
use App\Mail\Jobs\JobFailed;
use App\Models\Code;
use App\Models\Settings;
2023-11-23 17:31:28 +01:00
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
2026-10-02 12:09:46 +02:00
use Illuminate\Foundation\Queue\Queueable;
2023-11-23 17:31:28 +01:00
use Illuminate\Queue\Middleware\WithoutOverlapping;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
2026-10-02 12:09:46 +02:00
use Throwable;
2026-10-02 12:09:46 +02:00
class ProcessUniqueCode implements ShouldBeUnique, ShouldQueue
{
2021-08-18 17:08:02 +02:00
use Queueable;
/**
* The number of seconds the job can run before timing out.
*
* 7200 seconds (2 hours)
*
2026-10-02 12:09:46 +02:00
* @var int
*/
public $timeout = 7200;
/**
* Create a new job instance.
*
2026-10-02 12:09:46 +02:00
* @param int $amount Amount of code to generate.
* @param int $length Length of each code to generate.
*/
2023-11-23 17:31:28 +01:00
public function __construct(protected int $amount, protected int $length)
2021-08-18 17:08:02 +02:00
{
}
/**
* Execute the job.
*/
2026-10-02 12:09:46 +02:00
public function handle(): void
{
2026-10-02 12:09:46 +02:00
DB::transaction(function (): void {
2023-11-23 17:31:28 +01:00
// ! Le premier code commence à 1
$last_id = (Code::query()->max('id') ?? 0) + 1;
2026-10-02 12:09:46 +02:00
/** @var Settings $settings */
$settings = resolve(Settings::class);
2023-11-23 17:31:28 +01:00
$maxSQLPlaceholders = 65535;
$insertColumns = collect(DB::getSchemaBuilder()
2026-10-02 12:09:46 +02:00
->getColumnListing(new Code()->getTable()))
->reject(fn ($name): bool => in_array($name, ['id', 'code_exported']))->count() + 1;
2023-11-23 17:31:28 +01:00
/**
* Nombre d'insertions max sur un seule requète
*/
$perPage = \floor($maxSQLPlaceholders / $insertColumns);
/**
* Nombre de page totale à insérer.
*/
$totalPages = \ceil($this->amount / $perPage);
$totalGeneratedInserts = 0;
for ($currentPage = 1; $currentPage <= $totalPages; $currentPage++) {
$inserts = [];
$insertToGenerate = min($perPage, $this->amount - $totalGeneratedInserts);
do {
$inserts[] = [
2026-10-02 12:09:46 +02:00
'id' => $last_id++,
2023-11-23 17:31:28 +01:00
'date_creation' => now()->format('Y-m-d'),
];
} while (($totalGeneratedInserts < $this->amount) && --$insertToGenerate);
// * Mass insert
Code::query()->insert($inserts);
$totalGeneratedInserts += count($inserts);
}
// * Fin de la génération.
2023-12-05 12:33:25 +01:00
Mail::to(config('mail.admin'))->send(new CodeGenerationSucceed(
$this->amount,
$settings->name
));
2023-11-23 17:31:28 +01:00
});
}
/**
* In case of job failure
*/
2026-10-02 12:09:46 +02:00
public function failed(Throwable $exception): void
2023-11-23 17:31:28 +01:00
{
Mail::to(config('mail.admin'))->send(
2026-10-02 12:09:46 +02:00
new JobFailed(self::class, [
2023-11-23 17:31:28 +01:00
'message' => $exception->getMessage(),
2026-10-02 12:09:46 +02:00
'trace' => $exception->getTraceAsString(),
2023-11-23 17:31:28 +01:00
])
);
}
/**
* Get the middleware the job should pass through.
*
* @return array<int, object>
*/
public function middleware(): array
2021-08-18 17:08:02 +02:00
{
2023-11-23 17:31:28 +01:00
return [
2026-10-02 12:09:46 +02:00
new WithoutOverlapping('code_generation')
->releaseAfter(60),
2023-11-23 17:31:28 +01:00
];
}
}