Jobs em Segundo Plano
Para lotes de conteúdo muito grandes (centenas de páginas, posts ou inserções de blocos), a API síncrona de criação não é a ferramenta certa. O Chinaski traz uma fila de jobs: você submete uma requisição descrevendo o lote inteiro, um worker o processa item por item em segundo plano, e você faz polling de um único endpoint (ou dá uma olhada na tela de Jobs do admin) até os contadores se assentarem.
Submetendo um job
POST /api/jobs com uma chave de API com escopo de write e um corpo JSON de {type, items}:
type: exatamente um de três tipos suportados:bulk_upsert_pages: cria ou atualiza páginasbulk_upsert_posts: o mesmo para postsbulk_create_blocks: cria novos blocos
items: um array não vazio de objetos de linha correspondentes ao tipo escolhido.
O endpoint responde imediatamente com {"job_id": "…", "status": "queued"}. Cada item é processado um após o outro em um worker em segundo plano, de modo que um lote de 5.000 itens custa a você uma pequena requisição em vez de uma gigante.
Forma do item (os três tipos)
Para upserts de página/post, cada item precisa no mínimo de:
slug+language: o par que identifica o item.- Se nenhuma linha existente corresponder a esse par: também
title(obrigatório para criação), mais quaisquer outros campos que você queira definir; apenas colunas reais de página/post são honradas. - Se uma linha realmente existe: quaisquer campos fornecidos a atualizam no lugar, exceto slug e language; esses são a identidade e nunca podem ser modificados pelo job.
- Itens com
published=truesão criados publicados; todo o resto permanece rascunho até que algo o publique.
Para blocos, os itens são registros simples de criação (campos como create_block os recebe).
Acompanhando um job
- Faça polling de
GET /api/jobs/:id(chave de API com escopo de leitura). A forma da resposta é fixa:
{
"job_id": "…", "type": "bulk_upsert_pages",
"status": "queued | running | done | failed",
"progress": { "total": 500, "done": 312, "errors": 7 },
"created_at": "…", "updated_at": "…",
"result": { "completed": 493, "errors": [ … ] }
} - Os contadores marcam ao vivo enquanto o job roda:
donesobe (ouerrorspara itens que falharam) em tempo real; o objetoresultaparece exatamente quando o status muda para done. - Falhas no nível do item não fazem o job falhar: a linha continua andando, e o resultado final lista cada erro junto com o item original, para que você possa corrigir e reexecutar apenas essas linhas.
- Os status são literais: um worker travado é marcado como
failed(nunca deixado preso em queued), de modo que o polling sempre converge.
Retentando itens que falharam
Os jobs não se retentam por si mesmos. Pegue o array result.errors do job concluído, corrija as linhas com problema (slugs duplicados, título faltando, idioma bloqueado) e submeta um novo job contendo apenas esses itens: a semântica de upsert significa que os itens que já tiveram sucesso são simplesmente atualizados de novo, idempotentemente.
A tela de Jobs do admin
A tela Jobs no admin (somente Administradores) mostra os 200 jobs mais recentes, os mais novos primeiro, com o tipo, contadores de progresso ao vivo e qualquer snapshot de resultado/erro, com timestamps em UTC. Ela é somente leitura: recarregue para atualizar, e não existem controles de submissão ali; jobs são uma superfície de API por design, então o sentido da tela é simplesmente "o que a API tem feito com meu conteúdo?"
Limites que vale conhecer
- Um job não é um build. Conteúdos submetidos pela API de jobs escrevem registros; o site estático ainda é reconstruído por seus gatilhos habituais. Depois de um job grande de blocos/conteúdo, dispare um build (pelo dashboard ou pela mesma API) como parte do mesmo passo de automação.
- Sem agendamento. Os jobs rodam imediatamente após a submissão; não há semântica de "atrasar para depois"; a publicação agendada vive na camada de conteúdo (veja Scheduling), não nesta fila.
- Os tipos são fixos. Os três listados acima são os únicos tipos de job; atualizações em massa (updates) de subconjuntos arbitrários e outros tipos de entidade têm seus próprios endpoints de bulk one-shot em vez de vagas de tipo de job.
- O tamanho não é limitado no servidor. Um job pode carregar qualquer número de itens (ferramentas de lote como o bulk_import se fatiam em centenas para manter a polidez); a fila simplesmente percorre a lista.
- Uma falha especial: se o worker não consegue conectar ao banco de dados, o job é explicitamente marcado como
failedem vez de ficar pendurado em "queued", o único tipo de falha que alcança esse status no meio do caminho.
A versão curta
Lote grande = um job: uma requisição (a chave de API com write), um par de endpoints para verificar o progresso, três tipos de conteúdo que ele pode criar/atualizar em massa, relatório de erros por item, uma tela de admin com as últimas 200 linhas; e lembre-se de que ele escreve registros, não sites: faça o rebuild quando seu lote se assentar.