ediverse Explorer la plateforme

À la une PEPPOL BIS Billing 3.0 L’obligation européenne d’e-invoicing arrive : France sept 2026, Belgique janv 2026, Allemagne 2025.

Tumbling Window

Comment découper un flux infini en tranches temporelles disjointes pour calculer des agrégats périodiques exacts.

Problème

Un flux EDI est par nature infini : les messages arrivent en permanence depuis le réseau PEPPOL, depuis AS2/AS4, depuis les portails partenaires. On veut périodiquement répondre à des questions du type « combien de factures ont été reçues entre 09:00 et 10:00 ? », « quel est le volume B2B intra-UE pour le rapport DRR du 30 juin 2026 ? », « quel est le top-10 des partenaires par volume horaire ? ». Ces agrégats nécessitent de découper le flux en segments temporels disjoints sur lesquels appliquer la fonction d'agrégation.

Forces

  • Cardinalité prévisible : chaque évènement appartient à exactement une fenêtre.
  • Event-time vs processing-time : le bon choix dépend de la fonction métier (rapport fiscal = event-time strict).
  • Watermarks : nécessaires pour savoir quand une fenêtre est « définitivement complète ».
  • Late data : que faire des évènements qui arrivent après la fermeture (drop, side-output, reprocess) ?
  • Granularité : trop grosse = latence excessive ; trop fine = overhead state énorme.

Solution

Définir une taille de fenêtre fixe W (ex. 1 heure) et un référentiel temporel (event-time recommandé : timestamp du message à la source). Chaque évènement est routé vers la fenêtre [floor(ts/W)*W, floor(ts/W)*W + W). Quand la watermark dépasse la fin d'une fenêtre, on émet le résultat agrégé et on libère le state. Pour les évènements en retard (late data), choisir un policy : drop, side output vers une dead-letter, ou allowed lateness (Flink) qui maintient la fenêtre ouverte un délai supplémentaire et émet une mise à jour. Apache Flink, Spark Structured Streaming, Kafka Streams, Google Dataflow implémentent toutes ce pattern nativement.

Structure

Time:    09:00────────10:00────────11:00────────12:00────────►
         ┌────────────┐┌────────────┐┌────────────┐
Window:  │  W0 (09h)  ││  W1 (10h)  ││  W2 (11h)  │
         └────────────┘└────────────┘└────────────┘

Events:  ●●  ●  ●  ●●     ●●●  ●         ●●  ●  ●●●
         │                │                │
         09:01            10:05            11:10
         │                │
         09:42 ↓
                 09:55 ◄── arrives at 10:03 (LATE for W0!)
                          → drop, side-output, or allowed lateness?

When watermark passes 10:00:
  W0 closes → emit (W0, count=5)
When watermark passes 11:00:
  W1 closes → emit (W1, count=4)

Implémentation EDI

Trois cas EDI canoniques. (1) Reporting fiscal périodique : agréger les factures e-invoicing par fenêtre de 24h (UTC pour ZATCA, Europe/Paris pour PPF France) pour produire le batch quotidien à transmettre à l'administration. (2) KPI opérationnels par heure : count par partenaire, latence moyenne d'acquittement, top erreurs syntaxiques sur la dernière heure pour dashboard SRE. (3) Rate limiting comptable : si plus de N factures par minute pour un même émetteur, déclencher une revue manuelle (détection de robot de facturation suspect). Implémentation type Flink : stream.keyBy(senderGLN).window(TumblingEventTimeWindows.of(Time.hours(1))).aggregate(new CountAggregator()). Pour DRR ViDA (Digital Reporting Requirements, juillet 2030), la fenêtre quotidienne event-time avec allowed lateness de 24h est un pattern canonique pour produire le rapport à J+1 même avec quelques messages en retard.

Anti-patterns

  • Utiliser processing-time pour un rapport fiscal — les replays produisent des résultats incohérents avec le batch initial.
  • Watermark trop agressive — beaucoup de late data perdues, sous-déclaration fiscale possible.
  • Fenêtre trop fine sur des flux à fort cardinality — explose le state RocksDB en plusieurs To.
  • Pas de gestion du late data — un message PEPPOL qui arrive 6h en retard à cause d'un access point en panne n'est jamais comptabilisé.
  • Mélanger fuseaux horaires sans aligner au UTC — la fenêtre 00h-01h Europe/Paris en heure d'été n'est pas alignée sur UTC.

Patterns liés

Sources

  • Akidau T. et al. — The Dataflow Model: A Practical Approach to Balancing Correctness, Latency, and Cost in Massive-Scale, Unbounded, Out-of-Order Data Processing, VLDB 2015. research.google
  • Apache Flink documentation — Windows. nightlies.apache.org/flink
  • Spark Structured Streaming — Window operations on event time. spark.apache.org
  • Akidau T., Chernyak S., Lax R. — Streaming Systems, O'Reilly 2018, chap. 1-3.
  • Kafka Streams documentation — Windowing. kafka.apache.org