Aggiornare le applicazioni senza ricostruire il Framework

Un’immagine comune, bundle applicativi su S3 e gruppi di worker aggiornabili a server vivo

Proposta architetturale Genro ASGI · nuovo core 20 agosto 2026

Il problema: una modifica piccola può coinvolgere molti repository

Un cliente chiede una modifica alle fatture. Lo sviluppatore interviene sull’applicativo, su un modulo GenroPy legacy e su due package condivisi. Il risultato da collaudare non è un singolo file: è una combinazione precisa di quattro repository.

SE TUTTO È NELL’IMMAGINE Ogni correzione applicativa richiede una nuova immagine container deploy + riavvio + rollback immagine CON FRAMEWORK + BUNDLE Immagine Framework invariata Nuovo bundle applicativo aggiunto a server vivo La piattaforma cambia raramente. Le applicazioni possono evolvere spesso e per piccoli gruppi di utenti.
🧱

Framework stabile

La stessa immagine Genro viene distribuita a tutti i clienti e contiene ciò che deve essere comune.

📦

Applicazione separata

Ogni combinazione esatta di codice e dipendenze diventa un bundle autonomo.

👥

Collaudo selettivo

Mario e Luigi provano la modifica; tutti gli altri continuano a usare la versione precedente.

Ritorno semplice

Se la nuova build non va bene, il gruppo torna a un bundle già noto senza ricostruire nulla.

L’idea chiave: l’immagine contiene la macchina che sa eseguire le applicazioni; il bundle contiene l’applicazione concreta da eseguire.

La mappa globale in una schermata

Ci sono due catene indipendenti che si incontrano sul server: la piattaforma produce l’immagine Framework; ogni applicazione produce i propri bundle.

CATENA DEL FRAMEWORK Repo Genro ASGI piattaforma comune CI Framework build e test Registry OCI immagine per digest CATENA DELL’APPLICAZIONE Repo applicativo lock dei repository CI applicativa crea il bundle Amazon S3 bundle immutabili CONTAINER GENRO FRAMEWORK · IDENTICO PER TUTTI I CLIENTI CONTROL RUNTIME Python A · ASGI · Commander risolve bundle e gruppi non importa codice cliente WORKER RUNTIME COMUNE · PYTHON B produzione bundle 017 collaudo bundle 005 Il container fornisce il motore. S3 fornisce il contenuto applicativo scelto per ciascun gruppo.
piattaforma applicazione artefatti pronti coorte di collaudo

Le due catene hanno ritmi diversi: un aggiornamento Framework sostituisce l’immagine per tutti; un aggiornamento applicativo aggiunge un bundle e può riguardare soltanto un gruppo.

L’immagine Framework: la macchina comune

È un’immagine container riproducibile, pubblicata in un registry OCI e utilizzabile sia su un server tradizionale sia dentro Kubernetes. Non contiene l’applicazione del cliente.

IMMAGINE GENRO FRAMEWORK · RELEASE P17 CONTROL RUNTIME Python 3.14 • server ASGI • commander e gruppi • catalogo e cache bundle • controllo operativo WORKER RUNTIME Python 3.12 · comune a tutti i bundle • bootstrap del worker • protocollo con il commander • dipendenze comuni dichiarate • caricamento del bundle socket + messaggi Stessa immagine per ACME, BETA, GAMMA…

Perché due Python?

Il Framework può evolvere

Il control plane può adottare una versione Python adatta al server senza imporla alle applicazioni.

I bundle hanno un contratto stabile

Tutti vengono costruiti per lo stesso Python worker e la stessa piattaforma.

Processi realmente separati

Commander e worker comunicano via socket: non condividono interprete, memoria o moduli importati.

CambiamentoConseguenza
Nuova build applicativaSi produce un nuovo bundle; l’immagine Framework non cambia.
Nuovo Python del control planeSi produce una nuova immagine; i bundle possono restare validi.
Nuovo Python dei workerÈ un cambio di piattaforma: tutti i bundle vanno ricostruiti o ricollaudati.
Nuova versione Genro ASGIAggiornamento globale e coordinato dell’immagine, non per singolo gruppo.

Il bundle: una fotografia completa dell’applicazione

L’applicativo possiede il proprio repository e la propria CI. Il suo lock descrive i commit esatti di tutti i repository che formano quella build.

REPO APPLICATIVO applicativocommit A GenroPy legacycommit B package contabilitàcommit C package esternocommit D uv.lock tag: …/005 CI DELL’APPLICAZIONE 1. ricostruisce dai commit bloccati 2. usa il builder del worker Python 3. esegue test e controlli 4. crea manifest e checksum 5. pubblica senza sovrascrivere BUNDLE IMMUTABILE application/codice runtime python/dipendenze app assets/risorse manifest.jsonprovenienza checksums.sha256integrità Il bundle non contiene un altro Framework e non viene assemblato sul server di produzione.

Un esempio di manifest leggibile

application: fatture
bundle_name: collaudo-fatture
build: "005"
source:
  tag: bundle/collaudo-fatture/005
  commit: 8ab31e...
worker_contract:
  python_abi: cp312
  runtime: genro-worker-P17
repositories:
  genropy: 71ac9f...
  package_contabilita: c19d02...
bundle_sha256: c7f1...

Il tag non basta: il manifest conserva sempre i commit e il checksum effettivi. Così “build 005” resta verificabile anche mesi dopo.

S3: un deposito semplice, leggibile e protetto

Le versioni applicative sono cartelle logiche con nomi espliciti. Il versioning nativo di S3 resta attivo come rete di sicurezza, non come nome principale della release.

s3://genro-bundles/customers/acme/applications/fatture/ BUNDLES / collaudo-fatture / 004 / bundle.tar.zst · manifest · checksum collaudo-fatture / 005 / bundle.tar.zst · manifest · checksum release-2026.08 / 001 / … CHANNELS / produzione.json → release-2026.08 / 001 collaudo.json → collaudo-fatture / 005 versioning S3 = protezione operativa

Build mai sovrascritta

La CI fallisce se la destinazione esiste già. Ogni prefisso identifica contenuti immutabili.

Canale leggibile

collaudo.json è un piccolo puntatore che può avanzare o tornare indietro.

Cache locale per digest

Il server scarica, verifica ed estrae una sola volta ogni contenuto.

Dal canale alla cache

Risolvicollaudo → build 005
Scaricain area temporanea
Verificamanifest + SHA-256
Estraisenza esporre file parziali
Attivacache/sha256-c7f1

Il worker non scarica direttamente da S3. Riceve un percorso locale già verificato dal control plane.

I gruppi sono vivi: si aggiungono e si tolgono senza fermare il server

Un gruppo non è un’immagine container. È una scelta runtime: nome, bundle risolto, policy e insieme di worker equivalenti.

COMMANDER utente → gruppo Anna → produzione Carlo → produzione Mario → collaudo Luigi → collaudo decide il gruppo, non il singolo worker GRUPPO PRODUZIONE bundle release-2026.08/001 · checksum 91ab… worker produzione_0001 worker produzione_0002 Anna · Carlo · … GRUPPO COLLAUDO-FATTURE bundle collaudo-fatture/005 · checksum c7f1… worker collaudo_0001 Mario · Luigi

Aggiunta di un gruppo

RESOLVING FETCHING VERIFYING WARMING ACTIVE

Aggiornamento dello stesso nome logico

# Vista concettuale — non è ancora un’API implementata
collaudo-fatture · generazione 3 · build 004 · ACTIVE
collaudo-fatture · generazione 4 · build 005 · WARMING

# Solo dopo la verifica:
generazione 4 → ACTIVE
generazione 3 → DRAINING → REMOVED

Regola di sicurezza: worker di build diverse non devono convivere nella stessa generazione. Il nome resta uguale, ma il contenuto fisico cambia attraverso una sostituzione controllata.

Un esempio completo: la modifica provata da Mario e Luigi

Questa storia copre sia il collaudo iterativo sia la possibile trasformazione della modifica in una vera release.

1 · Richiestanuovo calcolo fattura
2 · Sviluppo4 repository modificati
3 · Tagcollaudo-fatture/004
4 · CItest + bundle
5 · S3build immutabile
PUBBLICA AGGIUNGE ASSEGNA CORREGGE PROMUOVE build 004 su S3 commit A+B+C+D checksum verificato gruppo collaudo worker caldo nessun utente ancora Mario + Luigi restano sticky gli altri su produzione build 005 stesso nome logico nuova generazione produzione → 005 stesso checksum nessuna ricostruzione Se la build 005 non parte, la 004 resta attiva. Il cambio diventa visibile soltanto dopo download, verifica e warm-up.

La correzione continua

# Tag sorgente progressivi; nome logico invariato
bundle/collaudo-fatture/004  → S3 …/collaudo-fatture/004/
bundle/collaudo-fatture/005  → S3 …/collaudo-fatture/005/
bundle/collaudo-fatture/006  → S3 …/collaudo-fatture/006/

gruppo visibile: collaudo-fatture
build effettiva: checksum sempre esplicito

Una modifica sperimentale e una release vera usano lo stesso meccanismo. Cambiano soltanto durata, ampiezza della coorte e decisione finale di promozione.

Compatibile con Kubernetes, senza delegargli le decisioni applicative

Kubernetes esegue e sorveglia l’immagine Framework. Genro continua a sapere quali utenti appartengono a quali gruppi e quali worker devono eseguire un bundle.

KUBERNETES CLUSTER REGISTRY OCI genro-framework@sha256… POD DEL CLIENTE · IMMAGINE FRAMEWORK Control runtime commander bundle cache gruppi e utenti health applicativa Worker runtime prod 017 test 005 S3 BUNDLE STORE applicazioni versionate Kubernetes governa il Pod · Genro governa utenti, gruppi e worker
Kubernetes decideGenro decide
Quale immagine Framework eseguireQuale bundle usa ciascun gruppo
Avvio, riavvio e salute del PodQuanti worker applicativi servono
Risorse, rete e storage del containerDove vive l’utente e quando cambia gruppo
Distribuzione infrastrutturaleWarm-up, drain, promozione e rollback applicativi

Limite dichiarato: il primo progetto può funzionare in un singolo Pod. Più Pod coordinati richiedono directory condivisa, lease e fencing: appartengono alla successiva architettura distribuita, non vanno finti in questa fase.

Cosa esiste già e cosa deve costruire il progetto

Il nuovo core di Genro ASGI ha già le fondamenta del processo worker e dell’affinità utente. La distribuzione dei bundle e il lifecycle dinamico non sono ancora implementati.

● Esiste oggi nel nuovo core

  • configurazione per gruppo;
  • interprete, entry module e worker class per gruppo;
  • processi worker collegati via socket;
  • avvio e arresto dei worker;
  • memoria dell’assegnazione utente → gruppo;
  • gruppo predefinito per i nuovi utenti;
  • affinità dell’utente al proprio gruppo.

● Deve essere progettato e implementato

  • formato definitivo del bundle;
  • risoluzione S3 e cache transazionale;
  • caricamento isolato del bundle nel worker;
  • ambiente pulito fra i due Python;
  • API pubblica add/refresh/remove group;
  • generazioni interne del gruppo;
  • gestione della coorte e promozione;
  • identità del bundle nella presentazione del worker.

Il collaudo cresce per prove piccole

FaseDomanda a cui rispondeProva concreta
B0 · FormatoIl bundle è davvero autonomo?Due bundle con stessi moduli e risultati diversi.
B1 · Due PythonControl e worker sono davvero isolati?Commander su Python A, worker su Python B.
B2 · S3Un contenuto parziale può diventare visibile?Checksum errato, download interrotto, cache concorrente.
B3 · Gruppi viviLa produzione resta attiva?Aggiunta e rimozione del gruppo di collaudo.
B4 · RevisioniPossiamo correggere più volte?004 → 005 → 006, guasto e rollback.
B5 · PromozionePromuoviamo proprio ciò che è stato testato?Stesso SHA-256 dal collaudo alla produzione.

Il nuovo core non contiene ancora tutto il data plane GenroPy. Le prime prove useranno un worker diagnostico; il pilot cliente richiederà anche il completamento delle Macro 5 e 6.

Scheda rapida

Il vocabolario e le operazioni principali, senza gergo superfluo.

Concetti

Quando dico…Intendo…
Immagine FrameworkIl container comune con control runtime, worker runtime e dipendenze possedute dalla piattaforma.
BundleUna build immutabile dell’applicazione e delle sue dipendenze applicative.
CanaleUn nome mobile, come produzione o collaudo, che indica un bundle.
GruppoUn insieme vivo di worker equivalenti che usano lo stesso bundle risolto.
GenerazioneUna incarnazione interna del gruppo, necessaria per sostituire il bundle senza modificarlo in uso.
CoorteGli utenti scelti per usare un gruppo, per esempio Mario e Luigi.
Worker PythonLa versione Python comune con cui vengono eseguiti tutti i bundle.

Azioni

Voglio…Il sistema deve…
Pubblicare una modificaTaggare il repo applicativo, costruire in CI e creare un nuovo prefisso immutabile su S3.
Far provare una buildAggiungere un gruppo, scaldare un worker e poi assegnare una coorte esplicita.
Correggere il collaudoCreare una nuova build e sostituire la generazione del gruppo solo dopo il warm-up.
Ritirare il testImpedire nuovi ingressi, gestire gli utenti residenti, fermare i worker e rimuovere il gruppo.
PromuovereAssociare la produzione allo stesso checksum già collaudato, senza ricostruirlo.
Tornare indietroRiattivare un bundle precedente già verificato e conservato in cache/S3.
Aggiornare Genro ASGIProdurre e distribuire globalmente una nuova immagine Framework.

Responsabilità

Sviluppatore applicativo

Blocca i commit, crea il tag, interpreta i test e pubblica il bundle tramite CI.

Genro ASGI

Verifica il bundle, governa cache, gruppi, worker, coorti e lifecycle.

S3

Conserva artefatti immutabili, manifest, checksum e puntatori di canale.

Sysop / Kubernetes

Distribuisce l’immagine, concede risorse e osserva il container; non sceglie gli utenti del gruppo.

Riassunto in una frase: Kubernetes porta il motore, S3 porta le applicazioni, Genro decide quale applicazione alimenta ogni gruppo di worker e quali utenti vi entrano.