Tâches en arrière-plan
Pour de très gros lots de contenu (des centaines de pages, de billets ou d'insertions de blocs) l'API de création synchrone n'est pas le bon outil. Chinaski livre une file de tâches (job queue) : vous soumettez une seule requête décrivant tout le lot, un worker le traite élément par élément en arrière-plan, et vous interrogez un unique point de terminaison (ou jetez un œil à l'écran Jobs de l'administration) jusqu'à ce que les compteurs se stabilisent.
Soumettre une tâche
POST /api/jobs avec une clé API de portée write et un corps JSON de {type, items} :
type: exactement l'un des trois types pris en charge :bulk_upsert_pages: créer ou mettre à jour des pagesbulk_upsert_posts: la même chose pour les billetsbulk_create_blocks: créer de nouveaux blocs
items: un tableau non vide d'objets de ligne correspondant au type choisi.
Le point de terminaison répond immédiatement avec {"job_id": "…", "status": "queued"}. Chaque élément est traité l'un après l'autre dans un worker en arrière-plan, si bien qu'un lot de 5 000 éléments ne vous coûte qu'une petite requête au lieu d'une géante.
Forme d'un élément (les trois types)
Pour les upserts de pages/billets, chaque élément nécessite au minimum :
slug+language: la paire qui identifie l'élément.- Si aucune ligne existante ne correspond à cette paire : aussi
title(requis à la création), plus tous les autres champs que vous voulez définir ; seules les vraies colonnes de page/billet sont honorées. - Si une ligne existe déjà : tout champ fourni la met à jour en place, sauf slug et language ; ce sont l'identité et ils ne peuvent jamais être modifiés par la tâche.
- Les éléments avec
published=truesont créés publiés ; tout le reste reste un brouillon jusqu'à ce que quelque chose le publie.
Pour les blocs, les éléments sont de simples enregistrements de création (champs tels que create_block les reçoit).
Suivre une tâche
- Interrogez
GET /api/jobs/:id(clé API de portée lecture). La forme de la réponse est fixe :
{
"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": [ … ] }
} - Les compteurs avancent en direct pendant que la tâche tourne :
donemonte (ouerrorspour les éléments en échec) en temps réel ; l'objetresultapparaît exactement quand le statut bascule à done. - Les échecs au niveau des éléments ne font pas échouer la tâche : la ligne continue d'avancer, et le résultat final liste chaque erreur accompagnée de l'élément d'origine pour que vous puissiez corriger et relancer rien que ces lignes.
- Les statuts sont littéraux : un worker planté est marqué
failed(jamais laissé bloqué en queued), si bien que l'interrogation converge toujours.
Réessayer les éléments en échec
Les tâches ne se réessayent pas elles-mêmes. Prenez le tableau result.errors de la tâche terminée, corrigez les lignes en échec (slugs en doublon, titre manquant, langue bloquée), et soumettez une nouvelle tâche ne contenant que ces éléments : la sémantique d'upsert signifie que les éléments déjà réussis sont simplement mis à jour à nouveau, de façon idempotente.
L'écran Jobs de l'administration
L'écran Jobs dans l'administration (administrateurs uniquement) affiche les 200 tâches les plus récentes, les plus récentes d'abord, avec le type, les compteurs de progression en direct, et tout instantané de résultat/erreur, horodatages en UTC. Il est en lecture seule : rechargez pour rafraîchir, et aucune soumission ni aucun contrôle n'y existe ; les tâches sont une surface API par conception, si bien que l'intérêt de l'écran se résume à : « qu'est-ce que l'API a fait à mon contenu ? »
Des limites à connaître
- Une tâche n'est pas un build. Les contenus soumis via l'API de tâches écrivent des enregistrements ; le site statique se reconstruit toujours selon ses déclencheurs habituels. Après une grande tâche de blocs/contenu, déclenchez un build (depuis le tableau de bord ou la même API) dans la même étape d'automatisation.
- Pas de programmation différée. Les tâches s'exécutent immédiatement après la soumission ; il n'y a pas de sémantique « retarder jusqu'à plus tard » ; la publication programmée vit dans la couche de contenu (voir Scheduling), pas dans cette file.
- Les types sont fixes. Les trois listés ci-dessus sont les seuls types de tâches ; les mises à jour de masse de sous-ensembles arbitraires et les autres types d'entités ont leurs propres points de terminaison bulk ponctuels plutôt que des créneaux de type de tâche.
- La taille n'est pas plafonnée côté serveur. Une tâche peut porter un nombre quelconque d'éléments (les outils par lot comme bulk_import se découpent eux-mêmes par centaines pour rester polis) ; la file déroule simplement la liste.
- Un échec particulier : si le worker ne peut pas se connecter à la base de données, la tâche est explicitement marquée
failedplutôt que de rester suspendue en « queued », le seul type d'échec qui atteint ce statut en cours de route.
La version courte
Un gros lot = une tâche : une requête (la clé API avec write), deux points de terminaison pour suivre la progression, trois types de contenu qu'elle peut créer/mettre à jour en masse, un rapport d'erreur par élément, un écran d'administration avec les 200 dernières lignes, et rappelez-vous qu'elle écrit des lignes, pas des sites : rebuild quand votre lot se stabilise.