Gå til indhold

Hjerteslag

Langvarige jobs og streamingtrin kan sende hjerteslag for at vise, at de stadig er aktive. Uden hjerteslag kan registreringen af forældede jobs overtage et job, der stadig er i gang, fordi dets tidsstempel for reserved_at ikke er blevet opdateret.

Sådan fungerer det

Når en worker begynder at behandle et job, kalder den Heartbeat::init() for at angive den aktuelle jobkontekst. Inde i din handler opdaterer et kald til Heartbeat::beat() jobbets kolonne reserved_at til NOW(). Registreringen af forældede jobs bruger reserved_at til at afgøre, om et job er gået i stå, så en opdatering holder jobbet sikkert.

Når jobbet er færdigt, kalder workeren Heartbeat::clear() for at nulstille konteksten.

Send hjerteslag

Kald Heartbeat::beat() inde fra en vilkårlig jobhandler eller et streamingtrin:

PHP
use Queuety\Heartbeat;

class LongRunningStep implements \Queuety\Step {

    public function handle( array $state ): array {
        $items = $state['items'];

        foreach ( $items as $i => $item ) {
            $this->process( $item );
            Heartbeat::beat( [ 'processed' => $i + 1, 'total' => count( $items ) ] );
        }

        return [ 'done' => true ];
    }

    public function config(): array {
        return [];
    }

    private function process( $item ): void {
        // Expensive work here.
    }
}

Fremdriftsdata

Parameteren $progress er et valgfrit associativt array. Når den angives, kodes den som JSON og gemmes i kolonnen heartbeat_data på jobrækken. Det gør det muligt at følge fremdriften uden for workeren:

PHP
Heartbeat::beat( [
    'processed' => 450,
    'total'     => 1000,
    'percent'   => 45,
] );

Når funktionen kaldes uden argumenter, opdateres kun reserved_at:

PHP
Heartbeat::beat();

Hjerteslag API

Klassen Queuety\Heartbeat består udelukkende af statiske metoder. Du opretter ikke en instans af den.

Metode Beskrivelse
Heartbeat::init( int $job_id, Connection $conn ) Angiv jobkonteksten. Kaldes automatisk af workeren før behandlingen.
Heartbeat::beat( array $progress = [] ) Send et hjerteslag. Opdaterer reserved_at og gemmer eventuelt fremdriftsdata.
Heartbeat::clear() Ryd jobkonteksten. Kaldes automatisk af workeren efter behandlingen.
Heartbeat::current_job_id() Hent det aktuelle job-ID (nyttigt til test).

Brug i streamingtrin

Workeren sender allerede et hjerteslag efter hver chunk, den gemmer, med heartbeat_data angivet til {"streaming_chunks": n}, så en stream, der jævnligt afgiver data, holder sig opdateret af sig selv. Kald selv Heartbeat::beat(), når der kan gå lang tid mellem dataafgivelser, f.eks. mens der ventes på det første token. Data, du sender, overskrives af workerens næste hjerteslag efter en chunk:

PHP
use Queuety\Contracts\StreamingStep;
use Queuety\Heartbeat;

class StreamAPIResponse implements StreamingStep {

    public function stream( array $state, array $existing_chunks = [] ): \Generator {
        $response = $this->client->stream( $state['prompt'] );

        foreach ( $response as $i => $chunk ) {
            Heartbeat::beat( [ 'chunks' => $i + 1 ] );
            yield $chunk;
        }
    }

    public function on_complete( array $chunks, array $state ): array {
        return [ 'response' => implode( '', $chunks ) ];
    }

    public function config(): array {
        return [];
    }
}

Hvornår skal hjerteslag bruges?

Brug hjerteslag, når et enkelt job eller trin varer længere end QUEUETY_STALE_TIMEOUT sekunder (standard: 600). Almindelige tilfælde:

  • LLM-kald API med streamingresponser
  • Store fildownloads eller -uploads
  • Gentagen batchbehandling i et enkelt trin
  • Ethvert eksternt API-kald, der kan tage flere minutter at besvare

Hvis dit trin afsluttes på under et minut, er hjerteslag unødvendige. Registreringen af forældede jobs træder først i kraft, når den konfigurerede timeout er udløbet.