In Microsoft Fabric, l’orchestrazione dei workload data engineering avviene con le Data Factory pipeline, il servizio che coordina l’esecuzione di attività eterogenee (notebook, dataflow, copy, stored procedure) secondo un flusso di controllo. A livello associate la competenza chiave non è “come si scrive una pipeline”, ma dove collocare la logica e come renderla robusta.
Pipeline vs notebook: separazione delle responsabilità
La regola architetturale è netta: la pipeline orchestra, il notebook elabora.
- Pipeline → controllo di flusso: sequenza delle attività, dipendenze, parametri, loop, gestione errori, schedulazione. È il “direttore d’orchestra”, non trasforma dati riga per riga.
- Notebook (Spark) → trasformazione dei dati: lettura da Lakehouse/Warehouse, join, aggregazioni, scrittura in tabelle Delta. È qui che sta la business logic pesante.
Errore tipico da evitare: costruire logica di trasformazione dentro le espressioni della pipeline. Le pipeline hanno un motore di espressioni limitato; qualsiasi manipolazione dati va delegata a un notebook o a un dataflow.
Attività concatenate e dipendenze
Le attività si collegano tramite output arrows tipizzate su quattro condizioni:
- Success – l’attività a valle parte solo se quella a monte riesce (percorso “happy path”).
- Failure – ramo di gestione errore (es. logging, notifica, cleanup).
- Completion – parte comunque, sia in caso di successo che di fallimento.
- Skipped – parte se l’attività precedente è stata saltata.
Attenzione: se un’attività ha più dipendenze in ingresso, la logica è AND — tutte le condizioni devono essere soddisfatte. Per ottenere un comportamento OR (es. “prosegui se A oppure B”) occorre ristrutturare con rami paralleli o attività If Condition.
Parametri ed espressioni dinamiche
Le pipeline si parametrizzano con:
- Parameters – valori impostati all’avvio (immutabili durante il run), utili per riuso e per passaggio ai notebook.
- Variables – mutabili durante l’esecuzione via Set Variable, utili per accumulare stato in un loop.
Con dynamic content e la sintassi di espressione (@, funzioni come @utcNow(), @pipeline().parameters.NomeParam, @activity('Copy').output) si costruiscono valori runtime. I parametri arrivano al notebook tramite l’attività Notebook che li inietta come variabili nella cella marcata parameters (integrazione papermill).
Loop e iterazione
L’attività ForEach itera su una collezione (tipicamente un array JSON prodotto da una Lookup o da un’attività Get Metadata). Usi tipici: processare N file, N tabelle, N clienti. Punti d’esame:
- isSequential: se
false, le iterazioni girano in parallelo (batch count fino a 50) — occhio alla concorrenza su risorse condivise. - Per interrompere un ciclo o gestire logica condizionale interna si annidano If Condition o Until.
Schedulazione e trigger event-based
Due modelli di attivazione:
- Schedule – ricorrenza a tempo (oraria, giornaliera). Semplice ma “cieca”: scatta anche se non ci sono dati nuovi.
- Event-based / file arrival – la pipeline parte quando arriva un file in una posizione (storage event). È la scelta corretta quando l’ingestion deve reagire al dato, non all’orologio.
Data Activator (parte di Real-Time Intelligence) copre il caso event-driven avanzato: osserva stream/eventi e scatena azioni (incluso l’avvio di pipeline) al superamento di una condizione. Da preferire quando il trigger dipende da soglie sui dati (es. temperatura > X, backlog > N), non dalla semplice presenza di un file.
Robustezza: retry ed error handling per-attività
La resilienza si configura a livello di singola attività, non di pipeline:
- Retry e Retry interval – ritenta i fallimenti transienti (timeout di rete, throttling) prima di dichiarare failure.
- Timeout – evita attività appese all’infinito.
- Ramo Failure verso attività di notifica (Teams/Outlook via webhook) o di cleanup.
Per un try/catch pulito si combina il ramo Failure con attività di compensazione e, se serve terminare con esito controllato, l’attività Fail.
Trappole tipiche d’esame
- Trasformazione dentro la pipeline → sbagliato: aggregazioni/join vanno in un notebook o dataflow; la pipeline solo orchestra.
- Ingestion che deve reagire all’arrivo di un file → trigger event-based (file arrival), non uno Schedule a tempo.
- Attività che deve girare sia in caso di successo sia di errore (es. logging finale) → dipendenza Completion, non Success né Failure.
- Fallimenti transienti (throttling, timeout rete) → configurare Retry + Retry interval sull’attività, non ricostruire la pipeline.
- Trigger basato su una soglia sui dati (non sulla mera presenza di un file) → Data Activator, non un file-arrival trigger.
- ForEach con più iterazioni pesanti in conflitto tra loro → impostare isSequential = true per evitare race condition sulla scrittura.