Liigu sisu juurde

Tööd

Tööd on Queuety-i põhiline tööühik. Saada töö järjekorda käsitleja nime ja koormaga ning tööline võtab selle ja käivitab taustal.

Tööde järjekorda saatmine

PHP
use Queuety\Queuety;

Queuety::dispatch( 'send_email', [ 'to' => 'user@example.com' ] );

dispatch() tagastab PendingJob koosturi. Enne automaatset järjekorda saatmist saad sellele valikuid aheldada:

PHP
use Queuety\Enums\Priority;

Queuety::dispatch( 'send_email', [ 'to' => 'user@example.com' ] )
    ->on_queue( 'emails' )
    ->with_priority( Priority::High )
    ->delay( 300 )
    ->max_attempts( 5 );

Töö ID kohe kättesaamiseks kutsu välja ->id():

PHP
$job_id = Queuety::dispatch( 'send_email', $payload )->id();

Käsitlejate kirjutamine

Käsitlejaks sobib iga klass, mis rakendab liidest Queuety\Handler:

PHP
use Queuety\Handler;

class SendEmailHandler implements Handler {
    public function handle( array $payload ): void {
        wp_mail( $payload['to'], $payload['subject'], $payload['body'] );
    }

    public function config(): array {
        return [
            'queue'           => 'emails',
            'max_attempts'    => 5,
            'backoff'         => 'exponential',
        ];
    }
}

Meetod handle() saab töö koorma ja teeb töö ära. Meetod config() tagastab valikulised vaikeväärtused:

Võti Tüüp Kirjeldus
queue string Järjekorra vaikenimi
max_attempts int Käivituste maksimaalne arv (sh esimene käivitus), enne kui töö viiakse ootele
backoff string Korduskatsete ooteaja strateegia: exponential, linear või fixed
rate_limit array Kiirusepiirang kujul [max_executions, window_seconds]
concurrency_group string Kallis käsitleja tööliste ühine vastuvõturühm
concurrency_limit int Selle rühma samaaegselt töödeldavate tööde maksimaalne arv
cost_units int Suhteline käivituskulu, mida kasutatakse kaalutud järjekorra või teenusepakkuja eelarvetes, töövoo eelarvetes ja vastuvõtuheuristikates

Need ressursivõtmed kuuluvad Queuety laiema Resource Management mudeli juurde, kus töö metaandmed, töövoo eelarved ja tööliste vastuvõtt toimivad koos.

Registreeri käsitleja:

PHP
Queuety::register( 'send_email', SendEmailHandler::class );

Või kasutage automaatseks registreerimiseks PHP atribuute.

Prioriteet

Töödel on neli prioriteeditaset. Töötajad võtavad esmalt ette kõrgema prioriteediga tööd.

PHP
use Queuety\Enums\Priority;

Queuety::dispatch( 'handler', $payload )->with_priority( Priority::Urgent );
Tase Väärtus Kirjeldus
Priority::Low 0 Vaikimisi. Taustatöö, mis võib oodata.
Priority::Normal 1 Tavaline prioriteet.
Priority::High 2 Töödeldakse enne tasemeid Low ja Normal.
Priority::Urgent 3 Töödeldakse esimesena. Kasuta säästlikult.

Viivitus

Lükka töö edasi, et see muutuks kättesaadavaks alles määratud arvu sekundite möödudes:

PHP
Queuety::dispatch( 'send_reminder', $payload )->delay( 3600 ); // 1 hour

Töö lisatakse kohe, kuid töötajad ei võta seda ette enne viivitusaja möödumist.

Unikaalsed tööd

Väldi sama käsitleja ja andmete korduvat tööle saatmist. Kui sama käsitleja ja andmetega ootel või töötlemisel töö on juba olemas, tagastatakse uue loomise asemel olemasoleva töö ID.

PHP
Queuety::dispatch( 'sync_inventory', [ 'sku' => 'ABC-123' ] )->unique();

Töö sõltuvused

Töö võib sõltuda teisest tööst. Töötaja ei võta seda ette enne, kui sõltuv töö on lõpetatud.

PHP
$first_id = Queuety::dispatch( 'import_data', $payload )->id();

Queuety::dispatch( 'send_notification', [ 'import_id' => $first_id ] )
    ->after( $first_id );

Tööde paketina saatmine

Saada mitu tööd ühe mitmerealise INSERT-päringuga, et saavutada maksimaalne läbilaskevõime:

PHP
$job_ids = Queuety::batch( [
    [ 'handler' => 'send_email', 'payload' => [ 'to' => 'a@example.com' ] ],
    [ 'handler' => 'send_email', 'payload' => [ 'to' => 'b@example.com' ] ],
    [ 'handler' => 'send_email', 'payload' => [ 'to' => 'c@example.com' ] ],
] );

Iga üksus võib sisaldada valikulisi võtmeid: queue, priority, delay, max_attempts.

Uuesti proovimine ja viivitused

Kui töö käivitab erandi, paneb Queuety selle tagasi olekusse pending ja lisab sellele viivitusega available_at, kuni töö on käivitatud kokku max_attempts korda (esimene käivitus läheb arvesse, seega max_attempts( 3 ) tähendab kuni kahte korduskatset). Iga korduskatse eelneva viivituse määrab viivituse strateegia, kus attempt tähistab äsja ebaõnnestunud käivituse numbrit:

Strateegia Viivituse valem Näide (pärast käivitusi 1, 2, 3)
exponential 2^attempt * 30 sekundit, ülempiiriga 3600 60s, 120s, 240s
linear attempt * 60 sekundit 60s, 120s, 180s
fixed 60 sekundit 60s, 60s, 60s

Määra globaalne vaikeväärtus asukohas wp-config.php:

PHP
define( 'QUEUETY_RETRY_BACKOFF', 'linear' );

Või määra see iga käsitleja jaoks asukohas config():

PHP
public function config(): array {
    return [ 'backoff' => 'exponential', 'max_attempts' => 5 ];
}

Või iga tööle saatmise korral:

PHP
Queuety::dispatch( 'handler', $payload )->max_attempts( 10 );

Ootele paigutatud tööd

Kui kõik korduskatsed on ammendatud, märgitakse töö maetud olekusse. Maetud tööd jäävad andmebaasi kontrollimiseks alles, kuid neid ei töödelda. Saad neid käsitsi uuesti proovida. Käsitsi korduskatse viib töö uuesti olekusse pending, katsete arvu lähtestamata, nii et uuesti proovitud maetud töö käivitatakse veel ühe korra ja maetakse ebaõnnestumise korral taas:

PHP
// Retry a specific buried job
Queuety::retry( $job_id );

// Retry all buried jobs
$count = Queuety::retry_buried();

Või CLI kaudu:

Shell
wp queuety retry 42
wp queuety retry-buried

Ajalimiit

Queuety käivitab pcntl_alarm() maksimaalse käitusaja jaoks ning peaks tähtaja ületamisel katse nurjama, andes TimeoutException. Seda ajalõppu praegu ei jõustata (#10): töötaja ei luba asünkroonseid signaale, mistõttu pika käitusajaga käsitleja töötab lõpuni; alarmi käivitumisel katkestatakse aga sleep()-is blokeeritud käsitleja ja märgitakse lõpetatuks. Määra ajalõpp globaalselt:

PHP
define( 'QUEUETY_MAX_EXECUTION_TIME', 300 ); // 5 minutes

Tööd, mis on olekus processing kauem kui QUEUETY_STALE_TIMEOUT sekundit, taastatakse automaatselt:

PHP
define( 'QUEUETY_STALE_TIMEOUT', 600 ); // 10 minutes

Taastage aegunud tööd käsitsi:

Shell
wp queuety recover

Järjekorrad

Tööd saadetakse nimelisse järjekorda. Iga töötaja töötleb üht järjekorda või järjestatud järjekordade loendit (vt Töötajad):

PHP
Queuety::dispatch( 'handler', $payload )->on_queue( 'emails' );
Shell
wp queuety work --queue=emails

Vaikimisi järjekord on default. Töökoormuste eraldamiseks saad käitada iga järjekorra jaoks eraldi töötajaprotsessi.

Kiiruse piiramine

Piira, kui sageli saab käsitlejat kindla ajavahemiku jooksul käivitada:

PHP
Queuety::dispatch( 'call_api', $payload )
    ->rate_limit( 10, 60 ); // max 10 executions per 60 seconds

Lisateavet leiad jaotisest Kiiruse piiramine.

Töölähetatavad tööklassid

Queuety v0.6.0 lisab klassipõhise töö API. Selle asemel et hoida käsitleja nimi, andmed ja käsitlejaklass eraldi, määrad ühe klassi, mis koondab kõik: andmed (tüübitud avalike atribuutidena), käivitamisloogika ja valikulise vahetarkvara.

Liides Contracts\Job

PHP
use Queuety\Contracts\Job;

interface Job {
    public function handle(): void;
}

Klass Job hoiab oma andmeid avalike atribuutidena ja käivitab oma loogika meetodis handle(). Eraldi meetodit config() ega käsitleja registreerimist pole vaja.

Tunnusjoon Dispatchable

Lisa tunnusjoon Dispatchable, et lisada oma tööklassile staatiline meetod dispatch():

PHP
use Queuety\Contracts\Job;
use Queuety\Dispatchable;

class SendEmailJob implements Job {
    use Dispatchable;

    public function __construct(
        public readonly string $to,
        public readonly string $subject,
        public readonly string $body,
    ) {}

    public function handle(): void {
        wp_mail( $this->to, $this->subject, $this->body );
    }
}

Saada see tööle, edastades konstruktori argumendid:

PHP
SendEmailJob::dispatch( 'user@example.com', 'Welcome!', 'Hello there.' )
    ->on_queue( 'emails' )
    ->with_priority( Priority::High );

Tunnusjoon Dispatchable kutsub sisemiselt välja Queuety::dispatch(), nii et kõik valikud PendingJob (järjekord, prioriteet, viivitus, max_attempts, unique, after) toimivad täpselt samamoodi.

Kuidas serialiseerimine toimib

Kui saadad tööklassi Job eksemplari tööle, eraldab Queuety JobSerializer-i abil täielikult kvalifitseeritud klassinime käsitlejana ja kõik avalikud atribuudid andmetena. Töötaja taastab eksemplari, sobitades andmete võtmed konstruktori parameetrite nimedega. Backed enumid serialiseeritakse nende aluseks olevaks väärtuseks ja taastatakse automaatselt.

Töö omadused

Tööklassid võivad korduskatsete ja ajalõpu käitumise juhtimiseks deklareerida avalikke atribuute. Töötaja loeb need peegelduse abil ja rakendab automaatselt.

PHP
use Queuety\Contracts\Job;
use Queuety\Dispatchable;

class ImportProductsJob implements Job {
    use Dispatchable;

    public int $tries = 5;
    public int $timeout = 120;
    public array $backoff = [ 10, 30, 60, 120 ];
    public string $concurrency_group = 'imports';
    public int $concurrency_limit = 2;
    public int $cost_units = 4;

    public function __construct(
        public readonly int $supplier_id,
    ) {}

    public function handle(): void {
        // Import products...
    }
}
Atribuut Tüüp Kirjeldus
$tries int Katsete maksimaalne arv enne töö maetamist. Tühistab tööle saatmise ajal määratud väärtuse max_attempts.
$timeout int Maksimaalne käitusaeg sekundites. Tühistab globaalse konstandi QUEUETY_MAX_EXECUTION_TIME. Vajab pcntl-i ja seda veel ei jõustata (vt Ajalõpp).
$backoff array Iga korduskatse viivituse väärtuste massiiv sekundites. Viimast väärtust kasutatakse ka järgmistel katsetel.
$concurrency_group string Kallite tööde jagatud töötajale lubamise rühm.
$concurrency_limit int Sellesse rühma kuuluvate samaaegsete processing tööde maksimumarv. Ilma $concurrency_group-ita eiratakse.
$cost_units int Suhteline käitamiskulu, mida kasutavad töövoo eelarved ja töötajale lubamise loogika.

Massiiv $backoff määrab kasvavad korduskatsete viivitused. Näiteks [10, 30, 60, 120] tähendab, et enne esimest korduskatset oodatakse 10 sekundit, enne teist 30 sekundit, enne kolmandat 60 sekundit ja enne edasisi korduskatseid 120 sekundit.

Ressursiga seotud atribuudid on kasulikud, kui tööklassid esindavad eri kuluprofiile. Kiire vahemälu värskendamine ja suur teenusepakkuja päring võivad mõlemad olla „üks töö”, kuid töövoo eelarve või töötajale lubamise otsuse puhul ei peaks neid tingimata võrdselt arvestama, kui eesmärk on hoida protsess turvalistes piirides.

Täielikku mudelit, sealhulgas töövoo eelarveid ja töötajapoolset lubamist, kirjeldab Ressursihaldus.

Ebaõnnestumise hook

Kui töö maetakse pärast kõigi korduskatsete ammendamist, kutsub Queuety töö eksemplaril meetodi failed() välja, kui see on määratud. Kasuta seda puhastuseks, teavitusteks või logimiseks.

PHP
use Queuety\Contracts\Job;
use Queuety\Dispatchable;

class ProcessPaymentJob implements Job {
    use Dispatchable;

    public int $tries = 3;

    public function __construct(
        public readonly int $order_id,
    ) {}

    public function handle(): void {
        // Process the payment...
    }

    public function failed( \Throwable $exception ): void {
        // Notify the team that payment processing failed permanently.
        error_log( "Payment failed for order {$this->order_id}: {$exception->getMessage()}" );
    }
}

Meetod failed() saab erandi, mis põhjustas lõpliku ebaõnnestumise. Töö eksemplar deserialiseeritakse algsete andmetega, seega on kõik avalikud atribuudid saadaval.

Tingimuslik tööle saatmine

Tunnusjoon Dispatchable pakub tingimuslikuks tööle saatmiseks meetodeid dispatch_if() ja dispatch_unless(). Mõlemad võtavad esimeseks argumendiks tõeväärtustingimuse, millele järgnevad töö konstruktori argumendid.

PHP
// Only dispatch if the user has opted in to notifications.
SendEmailJob::dispatch_if( $user->wants_notifications, $user->email, 'Update', $body );

// Dispatch unless the feature flag is disabled.
SyncInventoryJob::dispatch_unless( $maintenance_mode, $sku );

dispatch_if() saadab tööle, kui tingimus on true, ja tagastab PendingJob. Kui tingimus on false, tagastab see null.

dispatch_unless() saadab tööle, kui tingimus on false, ja tagastab PendingJob. Kui tingimus on true, tagastab see null.

Mõlemad meetodid toetavad tööle saatmisel aheldatavaid valikuid PendingJob:

PHP
SendEmailJob::dispatch_if( $should_send, $to, $subject, $body )
    ?->on_queue( 'emails' )
    ?->with_priority( Priority::High );

Sünkroonne tööle saatmine

Kasuta Queuety::dispatch_sync()-i, et käivitada töö kohe praeguses protsessis seda järjekorda lisamata. See on kasulik testimiseks ja tööde puhul, mis peavad käivituma samas protsessis.

PHP
use Queuety\Queuety;

// With a Job instance
Queuety::dispatch_sync( new SendEmailJob( to: 'user@example.com', subject: 'Hello', body: 'Hi!' ) );

// With a handler name and payload
Queuety::dispatch_sync( 'send_email', [ 'to' => 'user@example.com' ] );

Töö meetodit handle() kutsutakse otse. Andmebaasi rida ei looda, töötajat ei kaasata ja vahevara ei rakendata.

Tööde aheldamine

Tööde aheldamine käivitab tööd üksteise järel. Iga ahelas olev töö sõltub sellele eelneva töö edukast lõpetamisest. Kui mõni töö ebaõnnestub, jäävad järgnevad tööd ootele.

Kasutades Queuety::chain()

PHP
use Queuety\Queuety;

$first_job_id = Queuety::chain( [
    new FetchDataJob( $url ),
    new ProcessDataJob(),
    new NotifyCompleteJob(),
] )
    ->on_queue( 'pipeline' )
    ->catch( ChainFailedHandler::class )
    ->dispatch();

Queuety::chain() tagastab ChainBuilder, mille aheldatavate meetoditega saab määrata järjekorra ja ebaõnnestumise käsitleja. Meetod dispatch() loob kõik tööd järjestikuste depends_on seostega ja tagastab esimese töö ID.

Kasutades with_chain()

Tunnusjoon Dispatchable pakub meetodit with_chain(). Praegu on see samaväärne meetodiga Queuety::chain( $jobs ): klassi, millel seda kutsutakse, ahelasse ei lisata (#13), seega loetle massiivis ka esimene töö:

PHP
FetchDataJob::with_chain( [
    new FetchDataJob(),
    new ProcessDataJob(),
    new NotifyCompleteJob(),
] )
    ->on_queue( 'pipeline' )
    ->dispatch();

Ahela ebaõnnestumise käsitlemine

Registreeri ebaõnnestumise käsitleja klass meetodiga catch(). Käsitlejaklassil peab olema meetod handle(). See kutsutakse välja, kui mõni töö ahelas püsivalt maetakse. Töötaja toetab valikuid handle(), handle( Job $job ) ja handle( Job $job, \Throwable $exception ).

PHP
class ChainFailedHandler {
    public function handle(): void {
        // Alert, clean up, etc.
    }
}

Vahetarkvara lisamine

Tööklassid võivad määrata meetodi middleware(), mis tagastab käivitamist ümbritseva vahetarkvara:

PHP
use Queuety\Contracts\Job;
use Queuety\Dispatchable;
use Queuety\Middleware\RateLimited;
use Queuety\Middleware\Timeout;

class CallOpenAIJob implements Job {
    use Dispatchable;

    public function __construct(
        public readonly string $prompt,
    ) {}

    public function handle(): void {
        // Call the API...
    }

    public function middleware(): array {
        return [
            new RateLimited( max: 60, window: 60 ),
            new Timeout( seconds: 120 ),
        ];
    }
}

Sisseehitatud vahetarkvara ja kohandatud vahetarkvara kirjutamise üksikasjad leiad jaotisest Vahetarkvara.

Käsitlejapõhiste ja klassipõhiste tööde võrdlus

Käsitlejapõhine (v0.1+) Klassipõhine (v0.6+)
Tööle saatmine Queuety::dispatch( 'send_email', $payload ) SendEmailJob::dispatch( $to, $subject )
Käsitleja Eraldi klass, mis rakendab Handler Sama klass rakendab Contracts\Job
Andmed Tüübita array $payload Tüübitud avalikud atribuudid
Registreerimine Queuety::register() või #[QueuetyHandler] Pole vajalik (kasutab FQCN-i)
Vahetarkvara Pole saadaval Valikuline meetod middleware()
Seadistus Meetod config() Töö atribuudid + ahel PendingJob

Mõlemad lähenemisviisid on täielikult toetatud. Olemasolevad käsitlejapõhised tööd toimivad muudatusteta edasi. Samas projektis saad kasutada mõlemat stiili.

Töö elutsükkel

Kood
dispatch() -> pending -> processing -> completed
                  |           |
                  |           +-> exception -> pending (retry after backoff)
                  |                       |
                  |                       +-> buried (max attempts reached)
                  |
                  +-> delayed (available_at in the future)
Olek Kirjeldus
pending Ootab, et töötaja selle ette võtaks
processing Praegu käivitatakse
completed Edukalt lõpetatud
failed Broneeritud; töötaja ei määra seda praegu. Ebaõnnestunud katse, mida uuesti proovitakse, läheb tagasi olekusse pending
buried Kõik korduskatsed ammendatud