Siirry sisältöön

Työt

Työt ovat Queuety-järjestelmän perusyksikkö. Lähetä työ suoritettavaksi käsittelijän nimellä ja hyötykuormalla, niin työntekijä poimii ja suorittaa sen taustalla.

Töiden lähettäminen

PHP
use Queuety\Queuety;

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

dispatch() palauttaa PendingJob-rakentajan. Voit ketjuttaa siihen asetuksia ennen kuin se lähettää työn automaattisesti:

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 );

Saat työn tunnuksen heti kutsumalla toimintoa ->id():

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

Käsittelijöiden kirjoittaminen

Käsittelijä on mikä tahansa luokka, joka toteuttaa Queuety\Handler-rajapinnan:

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',
        ];
    }
}

Metodi handle() vastaanottaa työn hyötykuorman ja suorittaa työn. Metodi config() palauttaa valinnaiset oletusarvot:

Avain Tyyppi Kuvaus
queue string Oletusjonon nimi
max_attempts int Enimmäissuorituskerrat, ensimmäinen mukaan lukien, ennen kuin työ haudataan
backoff string Uudelleenyritysten viivestrategia: exponential, linear tai fixed
rate_limit array Nopeusrajoitus muodossa [max_executions, window_seconds]
concurrency_group string Kalliiden käsittelijöiden yhteinen työntekijöiden hyväksyntäryhmä
concurrency_limit int Ryhmän yhtäaikaisesti käsiteltävien töiden enimmäismäärä
cost_units int Suorituksen suhteellinen kustannus, jota käytetään painotettujen jono- tai palveluntarjoajabudjettien, työnkulkubudjettien ja hyväksyntäheuristiikkojen yhteydessä

Nämä resurssiavaimet ovat osa Queuety-järjestelmän laajempaa Resurssienhallinta-mallia, jossa työn metatiedot, työnkulkubudjetit ja työntekijöiden hyväksyntä toimivat yhdessä.

Rekisteröi käsittelijä:

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

Tai käytä PHP-attribuutteja automaattiseen rekisteröintiin.

Prioriteetti

Töillä on neljä prioriteettitasoa. Työntekijät varaavat ensin korkeamman prioriteetin työt.

PHP
use Queuety\Enums\Priority;

Queuety::dispatch( 'handler', $payload )->with_priority( Priority::Urgent );
Taso Arvo Kuvaus
Priority::Low 0 Oletus. Taustatyö, joka voi odottaa.
Priority::Normal 1 Tavallinen prioriteetti.
Priority::High 2 Käsitellään ennen arvoja Low ja Normal.
Priority::Urgent 3 Käsitellään ensimmäisenä. Käytä säästeliäästi.

Viive

Aseta työlle viive, jotta se on käytettävissä vasta määritetyn sekuntimäärän kuluttua:

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

Työ lisätään heti, mutta työntekijät eivät varaa sitä ennen kuin viive on kulunut.

Yksilölliset työt

Estä saman käsittelijän ja hyötykuorman töiden lähettäminen kahteen kertaan. Jos odottava tai käsittelyssä oleva työ samalla käsittelijällä ja hyötykuormalla on jo olemassa, palautetaan sen nykyinen tunnus uuden työn luomisen sijaan.

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

Työriippuvuudet

Työ voi riippua toisesta työstä. Työntekijä ei varaa sitä ennen kuin riippuvuus on valmis.

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

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

Erälähetys

Lähetä useita töitä yhdellä usean rivin INSERT-lauseella, jotta läpimeno on mahdollisimman suuri:

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' ] ],
] );

Jokainen kohde voi sisältää valinnaisia avaimia: queue, priority, delay, max_attempts.

Uudelleenyritys ja viive

Kun työ aiheuttaa poikkeuksen, Queuety palauttaa sen arvoon pending viivästetyllä available_at-toiminnolla, kunnes työ on suoritettu yhteensä max_attempts kertaa (ensimmäinen suorituskerta lasketaan mukaan, joten max_attempts( 3 ) tarkoittaa enintään kahta uudelleenyritystä). Kunkin uudelleenyrityksen viive määräytyy viivestrategian mukaan. attempt ilmaisee juuri epäonnistuneen suorituskerran numeron:

Strategia Viivekaava Esimerkki (suorituskertojen 1, 2, 3 jälkeen)
exponential 2^attempt * 30 sekuntia, enintään 3600 60s, 120s, 240s
linear attempt * 60 sekuntia 60s, 120s, 180s
fixed 60 sekuntia 60s, 60s, 60s

Aseta yleinen oletusarvo kohteessa wp-config.php:

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

Tai käsittelijäkohtaisesti kohdassa config():

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

Tai lähetyskertakohtaisesti:

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

Sivuun siirretyt työt

Kun kaikki uudelleenyritysyritykset on käytetty, työ merkitään haudatuksi. Haudatut työt säilyvät tietokannassa tarkastelua varten, mutta niitä ei käsitellä. Voit yrittää niitä uudelleen manuaalisesti. Manuaalinen uudelleenyritys asettaa työn jälleen tilaan pending nollaamatta sen yritysten määrää, joten uudelleen yritetty haudattu työ suoritetaan vielä kerran ja haudataan uudelleen, jos suoritus epäonnistuu:

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

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

Tai käyttämällä CLI:

Shell
wp queuety retry 42
wp queuety retry-buried

Aikakatkaisu

Queuety käynnistää pcntl_alarm()-ajastimen enimmäissuoritusajalle, ja sen on tarkoitus epäonnistua yrityksessä TimeoutException-virheellä, jos aika ylittyy. Aikakatkaisua ei tällä hetkellä valvota (#10): työntekijä ei ota asynkronisia signaaleja käyttöön, joten pitkään suoritettava käsittelijä jatkaa loppuun asti, ja sleep()-kutsuun jumiutunut käsittelijä keskeytetään hälytyksen lauetessa ja merkitään sitten suoritetuksi. Määritä aikakatkaisu yleisesti:

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

Työt, joiden tila on processing yli QUEUETY_STALE_TIMEOUT sekuntia, palautetaan automaattisesti:

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

Palauta vanhentuneet työt manuaalisesti:

Shell
wp queuety recover

Jonot

Työt lähetetään nimettyihin jonoihin. Kukin työntekijä käsittelee yhtä jonoa tai järjestettyä jonolistaa (katso Työntekijät):

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

Oletusjono on default. Voit eristää työkuormia suorittamalla kullekin jonolle omaa työntekijäprosessia.

Nopeuden rajoittaminen

Rajoita, kuinka usein käsittelijä voidaan suorittaa tietyn aikavälin aikana:

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

Lisätietoja on kohdassa Nopeuden rajoittaminen.

Lähetettävät työluokat

Queuety v0.6.0 esittelee luokkapohjaisen työn API. Erillisten käsittelijän nimen, hyötykuorman ja käsittelijäluokan sijaan määrittelet yhden luokan, joka kokoaa kaiken yhteen: hyötykuorman (tyypitettyinä julkisina ominaisuuksina), suorituslogiikan ja valinnaiset väliohjelmistot.

Contracts\Job-rajapinta

PHP
use Queuety\Contracts\Job;

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

Job-luokka sisältää hyötykuormansa julkisina ominaisuuksina ja suorittaa oman logiikkansa kohdassa handle(). Erillistä config()-metodia tai käsittelijän rekisteröintiä ei tarvita.

Dispatchable-trait

Lisää Dispatchable-trait saadaksesi staattisen dispatch()-metodin työluokkaasi:

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 );
    }
}

Lähetä työ välittämällä konstruktorin argumentit:

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

Dispatchable-trait kutsuu sisäisesti Queuety::dispatch()-metodia, joten kaikki PendingJob-asetukset (jono, prioriteetti, viive, max_attempts, unique, after) toimivat täsmälleen samalla tavalla.

Sarjallistamisen toiminta

Kun lähetät Job-esiintymän, Queuety-luokan JobSerializer poimii täysin määritetyn luokan nimen käsittelijäksi ja kaikki julkiset ominaisuudet hyötykuormaksi. Työntekijän puolella sarjallistaja muodostaa esiintymän uudelleen yhdistämällä hyötykuorman avaimet konstruktorin parametrien nimiin. Enum-arvot, joilla on tausta-arvo, sarjallistetaan niiden perustana olevaksi arvoksi ja palautetaan automaattisesti.

Työn ominaisuudet

Työluokat voivat määrittää julkisia ominaisuuksia uudelleenyritys- ja aikakatkaisutoiminnan ohjaamiseksi. Työntekijä lukee ne reflektiolla ja soveltaa niitä automaattisesti.

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...
    }
}
Ominaisuus Tyyppi Kuvaus
$tries int Työn enimmäisyritysmäärä ennen sen hautaamista. Ohittaa lähetyshetkellä määritetyn arvon max_attempts.
$timeout int Suorituksen enimmäiskesto sekunteina. Ohittaa yleisen vakion QUEUETY_MAX_EXECUTION_TIME. Edellyttää asetusta pcntl, eikä sitä vielä valvota (katso Aikakatkaisu).
$backoff array Viivearvojen taulukko kullekin uudelleenyritykselle sekunteina. Viimeistä arvoa käytetään myös myöhemmissä yrityksissä.
$concurrency_group string Kalliiden töiden yhteinen työntekijän pääsyryhmä.
$concurrency_limit int Ryhmän samanaikaisesti suoritettavien processing-töiden enimmäismäärä. Ohitetaan, jos $concurrency_group puuttuu.
$cost_units int Suhteellinen suoritusmaksu, jota käytetään työnkulun budjeteissa ja työntekijän pääsynhallinnassa.

$backoff-taulukko määrittää kasvavat uudelleenyritysviiveet. Esimerkiksi [10, 30, 60, 120] tarkoittaa, että ensimmäistä uudelleenyritystä odotetaan 10 sekuntia, toista 30 sekuntia ja kolmatta 60 sekuntia. Kaikissa myöhemmissä yrityksissä odotetaan 120 sekuntia.

Resurssiominaisuuksista on hyötyä, kun työluokat edustavat erilaisia kustannusprofiileja. Nopea välimuistin päivitys ja suuri palveluntarjoajakutsu voivat kumpikin olla ”yksi työ”, mutta niitä ei välttämättä pidä laskea samalla tavalla, kun työnkulun budjetti tai työntekijän pääsyä koskeva päätös pyrkii pitämään prosessin turvallisissa rajoissa.

Katso koko mallin kuvaus, mukaan lukien työnkulun budjetit ja työntekijäpuolen pääsynhallinta, kohdasta Resurssien hallinta.

Epäonnistuneen työn koukku

Kun työ haudataan kaikkien uudelleenyritysyritysten epäonnistuttua, Queuety kutsuu työesiintymän failed()-metodia, jos sellainen on määritelty. Käytä sitä siivoukseen, hälytyksiin tai lokitukseen.

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()}" );
    }
}

failed()-metodi saa parametrikseen lopullisen epäonnistumisen aiheuttaneen poikkeuksen. Työesiintymä sarjallistetaan alkuperäisestä hyötykuormastaan, joten kaikki julkiset ominaisuudet ovat käytettävissä.

Ehdollinen lähetys

Dispatchable-trait tarjoaa ehdolliseen lähettämiseen metodit dispatch_if() ja dispatch_unless(). Molemmat saavat ensimmäisenä argumenttinaan totuusarvoisen ehdon ja sen jälkeen työn konstruktorin argumentit.

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() lähettää työn, kun ehto on true, ja palauttaa PendingJob. Se palauttaa arvon null, kun ehto on false.

dispatch_unless() lähettää työn, kun ehto on false, ja palauttaa PendingJob. Se palauttaa arvon null, kun ehto on true.

Molemmat metodit tukevat ketjutettavia PendingJob-asetuksia työn lähetyksen yhteydessä:

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

Synkroninen lähetys

Käytä Queuety::dispatch_sync()-metodia suorittaaksesi työn heti nykyisessä prosessissa lisäämättä sitä jonoon. Tämä sopii testaamiseen ja töihin, jotka on suoritettava suoraan.

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' ] );

Työn handle()-metodia kutsutaan suoraan. Tietokantariviä ei luoda, työntekijää ei käytetä eikä väliohjelmistoa sovelleta.

Töiden ketjutus

Töiden ketjutuksessa tehtävät suoritetaan järjestyksessä yksi toisensa jälkeen. Kukin ketjun työ riippuu siitä, että edellinen työ valmistuu onnistuneesti. Jos jokin työ epäonnistuu, ketjun seuraavat työt jäävät odottamaan.

Queuety::chain()-metodin käyttö

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() palauttaa arvon ChainBuilder, jossa on sujuvan rajapinnan metodit jonon ja epäonnistumisen käsittelijän määrittämiseen. dispatch()-metodi luo kaikki työt peräkkäisinä depends_on-suhteina ja palauttaa ensimmäisen työn tunnuksen.

with_chain()-metodin käyttö

Dispatchable-trait tarjoaa with_chain()-metodin. Se vastaa tällä hetkellä Queuety::chain( $jobs )-metodia: luokkaa, jolle metodia kutsutaan, ei lisätä ketjuun (#13), joten lisää myös taulukon ensimmäinen työ:

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

Ketjun epäonnistumisen käsittely

Rekisteröi epäonnistumisen käsittelijäluokka käyttämällä catch()-metodia. Käsittelijäluokassa on oltava handle()-metodi. Sitä kutsutaan, kun jokin ketjun työ haudataan pysyvästi. Työntekijä tukee arvoja handle(), handle( Job $job ) ja handle( Job $job, \Throwable $exception ).

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

Väliohjelmiston lisääminen

Työluokat voivat määrittää middleware()-metodin, joka palauttaa suorituksen ympärille kietoutuvan väliohjelmiston:

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 ),
        ];
    }
}

Lisätietoja sisäänrakennetuista väliohjelmistoista ja omien väliohjelmistojen kirjoittamisesta on kohdassa Väliohjelmistot.

Vertailu käsittelijäpohjaisiin töihin

Käsittelijäpohjainen (v0.1+) Luokkapohjainen (v0.6+)
Lähetys Queuety::dispatch( 'send_email', $payload ) SendEmailJob::dispatch( $to, $subject )
Käsittelijä Erillinen luokka, joka toteuttaa Handler Sama luokka toteuttaa Contracts\Job
Hyötykuorma Tyypittämätön array $payload Tyypitetyt julkiset ominaisuudet
Rekisteröinti Queuety::register() tai #[QueuetyHandler] Ei tarvita (käytössä on FQCN)
Väliohjelmisto Ei käytettävissä Valinnainen middleware()-metodi
Määritys config()-metodi Työominaisuudet + PendingJob-ketju

Molempia tapoja tuetaan täysin. Nykyiset käsittelijäpohjaiset työt toimivat edelleen ilman muutoksia. Voit käyttää molempia tyylejä samassa projektissa.

Työn elinkaari

Koodi
dispatch() -> pending -> processing -> completed
                  |           |
                  |           +-> exception -> pending (retry after backoff)
                  |                       |
                  |                       +-> buried (max attempts reached)
                  |
                  +-> delayed (available_at in the future)
Tila Kuvaus
pending Odottaa työntekijän noudettavaksi ottamista
processing Suoritetaan parhaillaan
completed Suoritettu onnistuneesti
failed Varattu; työntekijä ei aseta tätä tilaa tällä hetkellä. Uudelleen yritettävä epäonnistunut suoritus palaa tilaan pending
buried Kaikki uudelleenyritysyritykset on käytetty