Ctrl K
ComunidadGuías…

app/Jobs/SyncExternalUserSource.php

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
<?php

namespace App\Jobs;

use Artwork\Modules\ExternalUserManagement\Models\ExternalUserSource;
use Artwork\Modules\ExternalUserManagement\Service\ExternalUserSyncService;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Facades\Cache;
use Throwable;

class SyncExternalUserSource implements ShouldBeUnique, ShouldQueue
{
    use Queueable;

    public const int LOCK_SECONDS = 7200;

    public int $timeout = 3600;

    public int $tries = 3;

    public int $uniqueFor = self::LOCK_SECONDS;

    /** @var array<int, int> */
    public array $backoff = [60, 300, 900];

    public bool $failOnTimeout = true;

    public bool $deleteWhenMissingModels = true;

    public function __construct(public ExternalUserSource $source)
    {
    }

    public function uniqueId(): string
    {
        return (string) $this->source->getKey();
    }

    public static function statusKey(int $sourceId): string
    {
        return 'external-user-sync-status-' . $sourceId;
    }

    public function handle(ExternalUserSyncService $syncService): void
    {
        $source = $this->source->fresh();

        if (!$source || $source->type !== 'ldap' || !$source->active) {
            $this->storeStatus(
                'cancelled',
                __('LDAP synchronization was cancelled because the source is no longer active.')
            );

            return;
        }

        $lock = Cache::lock('external-user-sync-' . $this->source->id, self::LOCK_SECONDS);

        if (!$lock->get()) {
            $this->storeStatus('waiting', __('Another sync is still running. The queued sync will retry.'));
            $this->release(60);

            return;
        }

        $this->storeStatus('running', __('LDAP synchronization is running.'));

        try {
            $result = $syncService->syncSource($source);
            $this->storeStatus('completed', __('LDAP synchronization completed.'), $result);
        } catch (Throwable $exception) {
            $this->storeStatus(
                'retrying',
                __('LDAP synchronization failed and will be retried.'),
                null,
                $exception::class . ': ' . $exception->getMessage()
            );
            throw $exception;
        } finally {
            $lock->release();
        }
    }

    public function failed(?Throwable $exception): void
    {
        $this->storeStatus(
            'failed',
            __('LDAP synchronization failed. Please check the logs.'),
            null,
            $exception === null ? null : $exception::class . ': ' . $exception->getMessage()
        );
    }

    /** @param array{total:int, synced:int, skipped:int}|null $result */
    private function storeStatus(
        string $status,
        string $message,
        ?array $result = null,
        ?string $error = null
    ): void {
        Cache::put(self::statusKey($this->source->id), [
            'status' => $status,
            'message' => $message,
            'result' => $result,
            'error' => $error,
            'updated_at' => now()->toIso8601String(),
        ], now()->addDay());
    }
}