Un portale editoriale italiano ad alto traffico può girare interamente su software open source, senza un solo prodotto commerciale nello stack di pubblicazione. Lo sto vedendo da vicino sui siti del gruppo Radio 105 — 105.net, radiomontecarlo.net, unitedmusic.it — dove i picchi seguono la diretta e i contenuti cambiano nel giro di minuti. Sotto c’è Zope — Z Object Publishing Environment — con Python come linguaggio applicativo, distribuito sotto Zope Public License.
Contesto
Nel 2001 il modello dominante per i siti editoriali è ancora la pagina generata da uno script che interroga un database relazionale e incolla HTML. Funziona, ma si porta dietro un problema noto: ogni richiesta ricostruisce da capo una struttura che è, di fatto, un grafo di oggetti — sezioni, programmi, schede, blocchi di palinsesto — appiattito a forza in righe e colonne. Per un sito che pubblica decine di volte al giorno, la distanza fra come ragiona il redattore (contenitori dentro contenitori) e come è fatto il database (tabelle) diventa attrito quotidiano.
Zope ribalta il punto di partenza. Il contenuto vive in ZODB, l’object database transazionale di Zope: gli oggetti sono persistenti per default, si navigano per URL come un filesystem, e la gerarchia che leggo nell’URL è la stessa che esiste in memoria. Una cartella programmi che contiene oggetti scheda non viene serializzata e ricostruita a ogni colpo: è già lì, raggiungibile per path.
Architettura
Tre meccanismi reggono in pratica un portale di questo tipo.
Il primo è l’acquisition. In Zope un oggetto eredita per contesto: una scheda dentro /rmc/programmi/ può chiamare un metodo intestazione definito alla radice senza sapere dove si trova, perché Zope risale la gerarchia di contenimento finché non lo incontra. In redazione questo significa scrivere layout, navigazione e frammenti comuni una volta sola, in alto, e lasciare che ogni sottosezione li raccolga. Aggiungere una sezione non obbliga a ricablare i template: l’oggetto nuovo prende ciò che gli serve dal suo contenitore.
Il secondo è la separazione fra logica e presentazione tramite template. Il linguaggio storico di Zope è DTML, una sintassi a tag che intreccia controllo di flusso e markup; comodo, ma produce documenti che non sono HTML valido e che un editor grafico non sa aprire. Le Zope Page Templates, introdotte con Zope 2.3, spostano il controllo dentro attributi nel namespace TAL (Template Attribute Language): il file resta HTML ben formato, e un tal:repeat o un tal:content sta accanto al markup invece che dentro. Un redattore che lavora su un palinsesto apre il template in un editor visuale e lo vede renderizzato, senza inciampare nei tag di logica.
Il terzo è il management through-the-web. L’intera istanza si amministra dal browser: creare oggetti, modificare metodi, editare template, assegnare permessi avviene da un’interfaccia web autenticata, con un modello di sicurezza per ruoli applicato oggetto per oggetto. In una redazione distribuita, dove chi cura un programma non è chi amministra il server, poter assegnare permessi fini ramo per ramo pesa più di qualsiasi prestazione.
Il nodo critico
Il vero nodo di un portale radiofonico è il carico in lettura. Durante una diretta migliaia di richieste cadono su poche pagine calde — la home, la scheda del programma in onda, la pagina del concorso — mentre le scritture restano rare e concentrate (il redattore che aggiorna). Un singolo processo Zope su ZODB ha un tetto: il database è pensato per molte letture e poche scritture, ma un solo server resta un collo di bottiglia di CPU.
La risposta nello stack è ZEO — Zope Enterprise Objects. ZEO spezza l’accesso al database in client e server: un unico ZEO Storage Server custodisce lo storage, e più processi Zope vi si collegano come client condividendo lo stesso database in ogni istante. In pratica metto più processi Zope (sulla stessa macchina o su macchine diverse) dietro un bilanciatore, tutti a leggere lo stesso ZODB attraverso ZEO. Le letture scalano in orizzontale aggiungendo client; le scritture restano serializzate sul server, ed è esattamente come deve distribuirsi il carico di un sito editoriale. ZEO è codice Python che parla TCP/IP e aggiunge un tipo di storage, ClientStorage, che inoltra le chiamate al server: per l’applicazione la differenza è trasparente, perché un client ZEO si comporta come uno storage locale.
Implicazioni
Quello che mi interessa qui non è Zope di per sé, è che uno stack open source regge un caso mission-critical italiano fatto di traffico reale e scadenze editoriali. Tre conseguenze concrete.
La prima riguarda costi e lock-in: l’intera catena di pubblicazione — application server, object database, linguaggio, motore di template — è ispezionabile e modificabile, senza licenze per CPU né una roadmap dettata da un fornitore. La seconda riguarda le competenze: chi mantiene il sito programma in Python, un linguaggio generale, non in un dialetto proprietario chiuso dentro il prodotto. La terza riguarda il modello dei dati: trattare il sito come un grafo di oggetti persistenti, invece che come query verso tabelle, avvicina la struttura del codice a quella editoriale del contenuto, e riduce i passaggi mentali necessari per andare dall’una all’altra.
Lo sviluppo ad hoc dei portali del gruppo Radio 105 su questo stack è documentato nell’insight noze: https://www.noze.it/insights/radio-105-portali/.
Limiti
ZODB non è una panacea. Il modello a oggetti persistenti complica le interrogazioni che un database relazionale risolve con una JOIN: cercare “tutte le schede pubblicate il mese scorso con un dato tag” richiede di costruire e mantenere indici a mano (in Zope, un Catalog), perché non c’è uno SQL su cui appoggiarsi. Lo storage di default di ZODB, FileStorage, cresce in modo append-only e va compattato (pack) di tanto in tanto, altrimenti il file Data.fs si gonfia senza limite. ZEO scala le letture, ma il server di storage resta un punto singolo da presidiare. E la curva di apprendimento è ripida: acquisition e through-the-web danno potenza, però chi arriva da CGI e SQL deve disimparare qualche abitudine prima di muoversi con scioltezza. Sono compromessi accettabili per un portale ad alta lettura e bassa scrittura; lo sarebbero meno per un’applicazione transazionale dominata da query analitiche.
https://www.python.org/ https://www.zope.org/
Immagine di copertina: Studio radiofonico con consolle di trasmissione, mixer e microfono su braccio snodato — foto di Henryk Kotowski, CC BY 2.5 — https://commons.wikimedia.org/wiki/File:Radio_syd_2000_studio.jpg