>_ DevTrendsfr

Langue

Accueil

Langages

Sections

Frontend Backend Mobile DevOps AI / ML GameDev Blockchain Embarqué Sécurité
Rust

Comment faire pour que PostgreSQL termine les tâches d'arrière-plan même après un redémarrage

Imaginez ce scénario : vous écrivez un workflow complexe de traitement de données. Vous devez récupérer des enregistrements, les envoyer à une API externe, mettre à jour le statut dans la base de données, puis lancer la génération de rapports. Si la base de données « plante » ou que le serveur redémarre en plein milieu du processus, une procédure PL/pgSQL standard va simplement s'interrompre. Le résultat est des données « suspendues » et un mal de tête : comment déterminer à quelle étape tout s'est arrêté, et comment redémarrer en toute sécurité ?

D'habitude, nous résolvons cela avec des solutions de contournement. Nous configurons pg_cron, créons des tables avec des files d'attente de tâches, écrivons des workers en Python ou Go qui interrogent constamment la base de données. Dans le pire des cas, nous traînons des mastodontes comme Temporal ou Airflow dans le projet. Mais les ingénieurs de Microsoft ont décidé que toute cette complexité était inutile et ont publié l'extension pg_durable.

Pourquoi les développeurs en ont besoin

L'idée principale du projet est de donner à PostgreSQL la capacité d'exécuter des fonctions longue durée qui résistent aux échecs. Dans la terminologie des auteurs, cela s'appelle « l'Exécution Durable ».

pg_ durable logo

Si votre workflow est défini via pg_durable, la base de données sauvegardera son état après chaque étape. Si le serveur redémarre en plein milieu de l'exécution d'une requête lourde ou d'un appel API, l'extension reprendra la tâche à partir du dernier point de contrôle réussi. Vous n'avez plus besoin d'assembler des tâches cron, des workers et des tables de statut.

Comment ça fonctionne en interne

Le projet est écrit en Rust en utilisant pgrx. Architecturalement, ce n'est pas qu'un wrapper mais un environnement d'exécution à part entière à l'intérieur de la base de données. Il se compose de plusieurs couches :

  1. SQL DSL : un ensemble d'opérateurs pour décrire le graphe de tâches.
  2. Background Worker : un processus d'arrière-plan à l'intérieur de Postgres qui gère l'exécution.
  3. Duroxide : un moteur d'orchestration (également un développement Microsoft) qui gère la relecture déterministe et les points de contrôle.

Il est intéressant de noter que les auteurs ont choisi une approche « native SQL ». Vous décrivez la logique directement dans la console ou la migration, en utilisant des opérateurs spéciaux comme ~> ou |=>.

Exemple de graphe de workflow

Fonctionnalités principales

Voici trois choses qui simplifient vraiment votre vie.

Tolérance aux pannes sans services externes

Vous n'avez pas besoin de Redis pour les files d'attente ni d'instances Temporal séparées. Tout réside directement dans les tables df.* et duroxide.*. Les données et la logique de contrôle sont dans le même environnement transactionnel. Cela élimine le problème classique des systèmes distribués où une tâche existe dans la file d'attente mais les modifications dans la base de données n'ont pas encore été validées.

Exécution parallèle et fusion

En utilisant des opérateurs, vous pouvez facilement « bifurquer » l'exécution des tâches en plusieurs flux parallèles puis attendre qu'ils se terminent. Le README contient un exemple clair : compter les utilisateurs, les commandes et les revenus simultanément, puis consolider le tout dans une seule étape de rapport.

Intégration avec les systèmes externes

L'extension dispose d'une fonction df.http(). Cela signifie que vous pouvez appeler des microservices externes ou des API de réseaux neuronaux directement depuis un processus longue durée. Si l'API renvoie une erreur 500, pg_durable peut attendre et réessayer sans bloquer l'ensemble du fonctionnement de la base de données.

Exemple de code

Voici à quoi ressemble la création d'une tâche simple directement en SQL :

-- Запускаем процесс: берем 100 необработанных документов и обновляем их статус
SELECT df.start(
    'SELECT id FROM documents WHERE processed = false LIMIT 100' |=> 'batch'
    ~> 'UPDATE documents SET processed = true WHERE id = ANY($batch)'
);

Ce code créera une instance de Workflow qui est garantie de s'exécuter. Si la mise à jour échoue, le système saura exactement quel batch de données il essayait de traiter.

Où cela s'avère utile

Je vois plusieurs scénarios où pg_durable vous fera gagner beaucoup de temps.

Premièrement, les pipelines IA. Si vous devez traiter des milliers de lignes via des embeddings et les sauvegarder dans pgvector, c'est l'outil idéal. Le chunking de texte, les appels à l'API OpenAI et les upserts dans la base de données sont regroupés dans un pipeline fiable.

Deuxièmement, le traitement de données à grande échelle (ETL). Au lieu d'écrire des procédures PL/pgSQL monumentales qui s'effondrent quand le WAL est épuisé, vous pouvez diviser le travail en petites étapes avec des points de contrôle.

Troisièmement, l'automatisation de l'administration. Par exemple, vérifier le gonflement des tables, envoyer une notification et attendre une approbation — tout cela peut être décrit comme une Durable Function.

Nuances et limitations

Le projet est en statut Preview. Cela signifie qu'il est trop tôt pour le mettre en production, mais c'est parfait pour les outils internes.

Limitations importantes : vous avez besoin de PostgreSQL 17 ou 18. Si vous êtes sur des versions plus anciennes, vous devrez mettre à niveau. Un autre point concerne la sécurité. Par défaut, toutes les fonctions dans shared_preload_libraries nécessitent des droits de superutilisateur pour la configuration, bien que les développeurs aient prévu un système de permissions via df.grant_usage() pour les rôles ordinaires.

Le système est optimisé pour SQL. Si vous avez besoin d'une logique métier complexe avec des boucles délicates en Python ou Node.js, il vaut mieux utiliser le moteur Duroxide directement depuis le code de votre application. pg_durable concerne spécifiquement le fait de garder les calculs aussi proches des données que possible.

Microsoft investit activement dans Postgres (souvenez-vous de l'acquisition de Citus), et pg_durable est une étape de plus vers la transformation de la base de données en une plateforme d'application à part entière. Si vous en avez assez que vos tâches d'arrière-plan « disparaissent » aux moments les plus inopportuns, ou si vous en avez marre de configurer des orchestrateurs externes pour des pipelines simples, consultez absolument ce dépôt. Pour commencer, un simple conteneur Docker ou Codespaces suffira, qui sont déjà configurés dans l'onglet Development du dépôt.

Projets similaires