Progetti di classe Enterprise con Foundation

Vorrei riprendere questo argomento, già trattato in precedenza, ma in maniera organica e il più possibile completa.
Lo scopo è capire “cosa manca”, per poter iniziare un dialogo propositivo con Progamma avendo bene in mente la problematica nella sua interezza.

Ricapitolando quanto ho capito:

  • L’ide, e conseguentemente TW, fatica a gestire una grossa-grossa mole di codice.
  • L’unica via è: componenti runtime. Questa soluzione risolve anche il problema delle dipendenze a pioggia, perché non permette una referenza diretta tra elementi di componenti diversi.

In pratica, si scompone il software in più componenti, un po’ come fossero delle sotto-applicazioni. Ogni componente risiede in un progetto separato (risolvendo quindi il problema della mole di codice nello stesso progetto). L’applicazione risiede in un ulteriore progetto e utilizza i componenti sottoforma di dll.
Questa soluzione si scontra però con alcuni problemi:

  • L’ide non è a conoscenza del contenuto delle dll.
  • Alcune parti dei componenti sono in comune (database, liste valori), e devono mantenersi allineate.
  • L’intero ciclo di vita del software (sviluppo, aggiornamento di versione, test, rilascio, distribuzione) deve lavorare con più progetti (per la nostra applicazione ne abbiamo individuati circa 15) e più dll (ognuna con versioni differenti).

L’ide non è a conoscenza del contenuto delle dll
Questo aspetto fa nascere diversi problemi:

  • Non potendo referenziare direttamente il codice diviso in componenti, è necessario gestire l’interazione tra essi tramite un sistema di messaggistica. Se l’interazione tra i componenti è forte, il sistema di messaggistica cresce notevolmente, aumentando la complessità dell’applicazione e la sua manutenzione, nonché i tempi di sviluppo.

  • Non sarà possibile istanziare una classe che non si trovi all’interno dello stesso componente, né quindi utilizzarla all’interno di qry di lookup.

  • La divisione in componenti deve quindi tenere conto di questi aspetti, dividendo l’applicazione in moduli il più possibile standalone, con il conseguente rischio che anch’essi, ad un certo punto, raggiungano una quantità di codice non gestibile dall’ide.

  • Non c’è modo di sapere dove viene usato il singolo elemento, perché Trova dove usato lavora a livello di progetto.

  • Non è più possibile utilizzare l’RTC, perché il file DDL non contiene le qry di aggiornamento degli elementi appartenenti alle dll. In linea teorica, ci dovrebbe essere un ulteriore progetto che importa tutti i componenti senza sorgenti, da cui ricavare il DDL con le qry di aggiornamento del’RTC per poi eseguirle in qualche modo. Abbiamo quindi un aumento sostanziale del lavoro e del tempo per la pubblicazione.

Alcune parti dei componenti sono in comune
Avendo smontato il progetto in sottoprogetti, questi devono avere la stessa struttura database e le stesse liste valori. Quindi, le modifiche di questi elementi effettuate su uno dei progetti devono essere riversate su tutti gli altri progetti, in tutte le versioni in sviluppo.
Per questo, è possibile utilizzare la funzionalità componenti di TW. In pratica (se non ricordo male), un progetto viene battezzato come principale e condivide alcune sue parti. Gli altri progetti sottoscrovono queste parti. E` quindi possibile eseguire una sorta di push delle modifiche, dal progetto principale a TW, che a sua volta ribalta le modifiche (al suo interno) ai progetti sottoscrittori. Da qui sarà possibile recuperarne l’ultima versione.
Il problema di questo meccanismo riguarda i tempi di TW. Quando sono in sviluppo avrò aperti nell’ide sia il progetto principale che il sottoprogetto a cui sto lavorando. Modifico quindi le parti in comune nel progetto principale, eseguo la push su TW e attendo che TW finisca il suo lavoro per poter recuperare le modifiche nel sottoprogetto.
La soluzione, in linea teorica, è eseguire tutti questi passaggi ma non attendere TW, e trascinare le parti modificate direttamente dal progetto principale al sottoprogetto.
Inoltre, la sottoscrizione dei componenti hai il problema delle costanti che non vengono inviate ai sottoscrittori.

Ciclo di vita del software
L’ambiente Foundation nella sua interezza (TW, IDManager, RTC…) permette di avere sotto controllo e gestire in modo integrato l’intero ciclo di vita del progetto, in modo centralizzato. Spezzando il progetto in più sottoprogetti questo non è più vero.
Usando i componenti runtime, introduciamo la gestione delle dll. A sua volta, questo introduce un problema di gestione delle dipendenze tra il progetto e le dll:

  • Versionamento.
  • Distribuzione all’interno del team di sviluppo.
  • Test.
  • Distribuzione in produzione.

Questo porta ad un aumento sostanziale del tempo impiegato al mantenimento dell’intera struttura, senza che questo porti alcun valore aggiunto al software sviluppato.

Impressioni generali
L’impressione generale è che Foundation accompagni gli sviluppatori, occupandosi di tutto il sottostrato tecnico e del relativo micromanagement, sgravandoli quindi di una mole di lavoro considerevole.
Ma, una volta che il progetto raggiunge dimensioni ragguardevoli, questo accompagnamento decade, lasciandone tutta la gestione in mano agli sviluppatori.

A questo aggiungo:
Foundation è un’applicazione a 32 bit.
I branch in TW non prevedono meccanismi di push/pull e merge con la copia master.
E` possibile che il superamento di questi due limiti possa essere uno dei passi avanti per permettere a Foundation di gestire in modo integrato e completo progetti di classe Enterprise?

Proposta
Considerando le problematiche nella loro interezza, ipotizzo questi miglioramenti:

  • Rivedere algoritmi TW per aumentarne le performance. Considerato che c’è un limite alla “scomponentibilità” dei progetti, e che quindi potrebbero esserci componenti corposi. Tra questi segnaliamo che la validazione IDE/TW valida gli stessi componenti più e più volte.

  • Correggere il meccanismo delle sottoscrizioni di TW in modo che comprenda le liste valori sottoscritte.

  • Esportazione componenti non più a 32bit ma a 64bit. Ora i componenti corposi non posso essere esportati per i limiti di memoria di Foundation.

  • Indicazione di massima della configurazione hardware consigliata per poter gestire progetti di classe enterprise, sia postazione di sviluppo che server TW. Indicazione, se esiste, di opportuna configurazione di Server DB per poter ottimizzare il lavoro di TW.

  • Aggiungere al progetto Foudantion una lista delle dipendenze, in cui si specificano i file .idp dei progetti dei componenti da cui dipende, e il loro percorso. In fase di compilazione/pubblicazione, Foundation verifica se sono cambiati dall’ultima volta e se è così, procede alla loro compilazione, prendendone le dll e mettendole in una cartella specifica (la bin dell’applicazione o altra).
    Se attivo, integra le qry RTC con quelle dei progetti da cui dipende.
    Sarà possibile forzare un ricompila tutte le dipendenze.
    Su TW, sarà possibile eseguire un lock temporaneo su questa lista, in modo che ogni versione possa avere la sua (sviluppo/test/produzione).

  • Creare facilmente una classe DO “proxy” da un’altra classe DO (ad esempio AnagraficaClienteProxy da AnagraficaCliente) e sostituire la classe DO originale con la classe proxy, potendo selezionare in quali punti del progetto (codice e form) fare questa sostituzione.

Community
So che l’argomento è vasto, e che ognuno di noi ha una lista di richieste verso Progamma lunga un chilometro, ma vi chiedo di non divagare e rimanere coerenti con l’obiettivo fisato in testa al post: cosa manca a Foundation per gestire in modo integrato e completo progetti di classe Enterprise?
Vi chiedo quindi di aggiungere le cose che secondo la vostra esperienza mancano e io non ho elencato, oppure di segnalare soluzioni alternative a quelle che ho elencato.
Ho reso questo post una wiki, grazie a chi vorrà contribuire.

4 Mi Piace

Sottoscrivo in pieno quanto detto, aggiungendo che reputo la soluzione di “spezzare” il progetto sia solo un workaround per superare i limiti tecnologici che ci sono attualmente. La speranza che il processo di unificazione verso una versione “Cloud Style” si porti dietro quanto di buono presente su IndeCloud ovvero il teamwork in stile Git, anche se poi va visto come si comporta con progetti di dimensioni Enterprise…

2 Mi Piace

@sarcaz il Team Works di Instant Developer Cloud ha già un progetto di dimensioni Enterprise che è la stessa console di Cloud realizzata con Cloud!

È un progetto molto grande e complesso che gestisce tutta l’infrastruttura del sistema Instant Developer Cloud. Insomma un buon banco di prova del Team Works.

2 Mi Piace

Introduco un altra criticità:

Se utilizzi la sottoscrizione dei componenti hai il problema delle costanti che non vengono inviate ai sottoscrittori.
Ho dovuto abbandonare questo approccio proprio a causa di questo problema. Praticamente distribuisco solo l’applicazione e il db ai sottoscrittori perché se distribuisco i componenti questi si perdono dei pezzi perché le costanti, come dicevo, non vengono inviate.
L’unico modo che ho trovato è esportare ed importare. Ho creato su un disco di rete una sorta di ‘repository degli ultimi .idz’ e tutte le volte che vengono modificati questi componenti vengono esportati. I tempi si allungano enormemente e basta un attimo per perdersi le modifiche. Penso che bisognerebbe fornire ad INDE strumenti adeguati per gestire il processo di componentizzazione.

1 Mi Piace

Ho aggiunto una proposta.
Se avete integrazioni o correzioni, o soluzioni alternative.
Grazie.

Noi abbiamo usato la DO massicciamente sia per lettura che per la scrittura dati. Il progetto attualmente ha diversi componenti ma i componenti più grandi sono due:

  • uno che contiene le classi DO
  • uno che contiene le Form

Nel nostro caso un grosso problema che abbiamo è che risulta quasi impossibile fare il refactoring in componenti separati poiché alcune classi DO possono avere interazioni strette con altre classi DO e sono “centrali” per molti componenti o form (ad esempio Anagrafica clienti, Anagrafica articoli, ecc).

In questi casi andare a modificare le classi “centrali” per avere meno interazioni con le altre classi può essere molto complesso.

Una modo per facilitare il refactoring, potrebbe essere l’implementazione in INDE di un sistema per

  • creare facilmente una classe DO “proxy” da un’altra classe DO (ad esempio AnagraficaClienteProxy da AnagraficaCliente) e
  • sostituire la classe DO originale con la classe proxy, potendo selezionare in quali punti del progetto (codice e form) fare questa sostituzione.

La classe proxy dovrebbe internamente richiamare i metodi della classe originale (con un sistema di messaggistica tipo la sendAppMessage() / onAppMessage() )

E’ solo una idea di massima e non so fino a che punto sia realizzabile, ma potrebbe facilitare notevolmente la divisione del nostro progetto in più progetti separati.

2 Mi Piace

Aggiungo: abbiamo notato che la validazione IDE/TW valida gli stessi componenti più e più volte. Questo potrebbe essere uno dei punti da migliorare per aumentare le performance dell’ambiente.

3 Mi Piace