Pular para o conteúdo

Sinais de atividade

Jobs de longa duração e etapas de streaming podem enviar sinais de atividade para comprovar que ainda estão em execução. Sem esses sinais, o detector de jobs obsoletos pode recuperar um job que ainda está sendo processado porque seu registro de data e hora reserved_at não foi atualizado.

Como funciona

Quando um worker começa a processar um job, ele chama Heartbeat::init() para definir o contexto do job atual. Dentro do seu handler, chamar Heartbeat::beat() atualiza a coluna reserved_at do job para NOW(). O detector de obsolescência usa reserved_at para determinar se um job está travado; atualizá-lo mantém o job seguro.

Quando o job termina, o worker chama Heartbeat::clear() para redefinir o contexto.

Enviar sinais de atividade

Chame Heartbeat::beat() dentro de qualquer handler de job ou etapa de streaming:

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.
    }
}

Dados de progresso

O parâmetro $progress é um array associativo opcional. Quando fornecido, ele é codificado em JSON e armazenado na coluna heartbeat_data da linha do job. Isso permite acompanhar o progresso de fora do worker:

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

Quando chamado sem argumentos, somente reserved_at é atualizado:

PHP
Heartbeat::beat();

API de sinais de atividade

A classe Queuety\Heartbeat é totalmente estática. Você não precisa instanciá-la.

Método Descrição
Heartbeat::init( int $job_id, Connection $conn ) Define o contexto do job. Chamado automaticamente pelo worker antes do processamento.
Heartbeat::beat( array $progress = [] ) Envia um sinal de atividade. Atualiza reserved_at e, opcionalmente, armazena dados de progresso.
Heartbeat::clear() Limpa o contexto do job. Chamado automaticamente pelo worker após o processamento.
Heartbeat::current_job_id() Obtém o ID do job atual (útil para testes).

Uso em etapas de streaming

O worker já envia um sinal de atividade após cada trecho que persiste, com heartbeat_data definido como {"streaming_chunks": n}; assim, um fluxo que gera conteúdo regularmente se mantém atualizado por conta própria. Chame Heartbeat::beat() você mesmo quando houver longos intervalos entre os trechos, por exemplo, enquanto aguarda o primeiro token. Os dados que você passar serão sobrescritos pelo próximo sinal por trecho do worker:

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 [];
    }
}

Quando usar sinais de atividade

Use sinais de atividade quando um único job ou etapa durar mais de QUEUETY_STALE_TIMEOUT segundos (padrão: 600). Casos comuns:

  • Chamadas de API com respostas em streaming
  • Downloads ou uploads de arquivos grandes
  • Repetições de processamento em lote dentro de uma única etapa
  • Qualquer chamada externa de API que possa levar minutos para responder

Se sua etapa terminar em menos de um minuto, não será necessário enviar sinais de atividade. O detector de obsolescência só entra em ação após o tempo limite configurado.