Anche i SAP sbagliano

quando si timbra il cartellino elettronico, i dati sono raccolti dalla “macchinetta” e spediti a SAP, noto ERP. Bene, secondo voi, se sbagliate “verso di strisciatura” tra ingresso e uscita, cosa può succedere? si scombinano le ore di ingresso e uscita, e vengono fuori le cose più incredibili.
tipo questa: (clicca sull’immagine)
errori sap
risulta che merc. 21 ho lavorato dalle 17:59 alle 08:56 e poi dalle 32:56 (SIC!) alle 12:42, per un totale di 4 minuti di flessibilità, 4 ore di extra-orario e 14:42 ore di notturno!!!
In compenso giovedì mattina devo giustificare perché dopo la nottolata non sono venuto al lavoro…

Singleton Pattern per C#

Singleton Pattern per C#

piccolo esempio di pattern singleton thread safe per C#. dal momento che lo uso molto spesso e che devo copiarmelo di qua e di là, ho deciso di scriverlo sul sito, che almeno so sempre dove trovarlo =D
ciao

public class Oggetto 
{
   #region Singleton
   //singleton pattern
   private static bool _isInit;
   private static Exception _error;
   private static volatile Oggetto _instance = null;
   private static object _syncObj = new object();

   /// 
   /// Get the Oggetto Instance
   /// 
   public static Oggetto Instance
   {
      get
        {
           if (_instance == null)
           {
              lock (_syncObj)
	      {
                 if (_instance == null)
                    _instance = new Oggetto();
              }
           }
           if (_isInit)
              return _instance;
           else
              throw new Exception(
                 "Error initializing Oggetto", _error);
        }
   }

   private Oggetto()
   {
      try
      {
         InitData();
         _isInit = true;
      }
      catch (Exception ex)
      {
         _isInit = false;
	 _error = ex;
      }
   }
   #endregion

   private void InitData()
   {
      // qua ci va l'inizializzazione
   }

   // comodo per reinizializzare tutto, se serve
   internal void RefreshCache()
   {
      this.InitData();
   }
}

c#, dotnet, lavoro, pattern, singleton, best practices

regression test best practices ovvero come testare per bene le applicazioni

È inutile dire, spiegare, ribattere sul perché fare i test del software è utile ed importante: e se ne possono fare di molti tipi. Il semplice test su un caso d’uso, il test di integrazione (per le nuove funzionalità), il test di usabilità, molti altri poi, ma non ultimo test di regressione. Cioè quel test che serve a controllare che la nuova versione del programma faccia ancora le cose che faceva prima.
Sembra una scemenza, ma a volte le nuove funzioni possono interferire con le vecchie. E ovviamente non deve accadere.
Ora vediamo un caso di test egregiamente svolto.
Il server SQL che ospita i database di tutti i nostri programmi aveva bisogno di una bella rinfrescata al sistema operativo. Visto che aggiornare il S.O. (nel caso windows server 2003) è un’operazione di qualche ora, si è stabilito di fermare un pomeriggio tutte le attività e di lasciare agli amministratori il tempo di lavorarci su. Ieri era il giorno fatidico e le 12.00 l’ora X.

  • Ore 11 il capufficio ufficio CU ri-segnala ai nostri utenti che un’ora dopo il database sarebbe stato spento.
  • Ore 11.20 il dirigente dei nostri utenti (che chiameremo DU) ci scrive una email: “il programma DB_Uploader ha qualcosa a che fare con il database?” – quest’applicazione prende effettivamente dei dati e li carica sul database, e il suo gruppo lo usa quotidianamente
  • Ore 11.25 leggiamo l’email e decidiamo di rispondere: “Sì, come già scritto nelle email di lunedì e giovedì scorso”
  • Ore 11.35 DU risponde scrivendo a noi e ai suoi sottoposti: “Bene. Visto il fermo macchina del server sarebbe il caso di fare un test dell’applicazione DB_Uploader.” e conclude dicendo ad un utente (che chiamerò UT) “UT pensaci tu.”
  • Ore 11.36 io e CU ci guardiamo sbalorditi e diciamo: “Cosa vuole fare?”
  • Ore 11.37 io e CU rileggiamo l’email di DU
  • Ore 11.37 e 30 secondi io e CU, ancora più sbalorditi, ci chiediamo: “Cosa si aspetta da questo test? Il database è spento quindi l’applicazione non funzionerà!”. Ridiamo e decidiamo di non rispondere
  • Ore 12 come preventivato gli amministratori spengono il database e cominciano a lavorare
  • Ore 12.20 UT risponde: “Adesso non riesco a provare, perché sono molto occupato. Appena torno da pranzo lo farò subito”. Io e CU pensiamo “UT, mangia pure tranquillo…”
  • Ore 13.30 UT ritorna dal pranzo, e anche noi.
  • Ore 13.37 UT scrive un’email a tutti: “Ho provato più volte il DB_Uploader e non vuole saperne di partire. Vi allego una schermata… Dice che non riesce a collegarsi al database… “
  • Ore 13.37 e 1 secondo io e CU leggiamo l’email e in coro diciamo “MA VA’?”. Anche stavolta decidiamo di non rispondere…

Morale della storia

Quando prevedi di fare un test, devi più o meno immaginarti quale può essere il risultato.

Morale della storia 2

Se il capo ti chiede di fare un test scemo, devi più o meno immaginarti quale può essere il risultato. Il risultato può essere che passa per scemo solo il capo, solo tu, o tutti e due insieme…
PS: l’aggiornamento del server è andato a buon fine

per un punto Martin perse la data

tanto tempo che non scrivo. perchè il tempo non è tanto ma è poco…
allora aggiungo questa storiellina simpatica…
"com’è che ho scritto sul mio cv? "attitudine al problem solving"?
stamattina ci hanno segnalato un bug nei dati di un report. il capo mi dice "facciamo l’analisi insieme".
cominciamo a spulciare le query e taaaac, trovo il punto giusto e taaaaac, scopro che in una certa tabella c’è un errore sul campo data su un record che non sappiamo ancora qual è.
e taaaac dico "record 1287" e lui "come fai a saperlo?" e io "beh, se nella tabella di destinazione ci sono 1286 record su duemila e passa che dovrebbero esserci, il problema sarà sul 1287esimo!".
e taaac troviamo che la data del 1287esimo record è sbagliata 02/02/208 invece di 02/02/2008.
taaaac. corretta la data, rilanciata la procedura di importazione e risolto il problema sul report.
taaaaaaaac!"

a chi ha sbagliato a inserire la data ovviamente gliela faremo pagare!

Java vs C#

Da qualche settimana ho cambiato lavoro: ho lasciato la società di consulenza e adesso lavoro per un gruppo piuttosto grande, anche qui come sviluppatore.
I cambiamenti non sono stati solo esteriori, ma anche di contenuto. Infatti sono passato dallo sviluppo Java/Oracle a quello C#/SqlServer. “Oddio!” direte voi… beh, all’inizio lo dicevo anch’io.
Sto valutando le analogie e le differenze tra questi due mondi, cercando di riutilizzare al massimo l’esperienza che ho in Java nel nuovo ambiente. Ora, da utente e da contributore dell’Open Source, passare a M$ mi fa abbastanza impressione, ma considero il mio un lavoro che usa l’astrazione, quindi mi devo slegare dal pensiero del “basso” livello (linguaggi, compilatori, sistema operativo), e devo pensare al codice e a quanto bene sono capace di scriverlo, a come possa funzionare il programma che faccio, senza altro. Sì, questo potrebbe sembrare un esercizio di retorica o di teologia informatica…
Ora comincio con le considerazioni che sto facendo da quel poco che ho imparato nell’ambiente M$, spiegando un po’ l’effetto che mi fa.
Prima di tutto devo ribadire che lavoro per una grande azienda, quasi tutti gli utenti hanno client Windows, ci sono decinaia di server attivi, dall’AS/400 al Linux, da Sap con NetWeaver all’ultimo WS2003 con Sharepoint. C’è chi lavora in Cobol (ancora!), chi è espertissimo di VBA, c’è gente che fa in Excel robe che credevo impossibili (sul grado di affidabilità dei risultati non metterei la mano sul fuoco), c’è tanto lavoro in Java e altrettanto in C#.
Ora, quello che M$ permette, in virtù della sua posizione quasi monopolistica, è un altro grado di integrazione: condivisione dei dati, remote desktop, deploy delle applicazioni. Il lato negativo è che, come dice nonmiricordochi, “fai un programma a prova di stupidi e solo gli stupidi lo useranno”. Non siamo a questo punto, però il fatto che la programmazione per Window$ sia piuttosto semplice, corrisponde al fatto che i lavori non sempre sono eseguiti con rigore.
Faccio due esempi.
Comincio con la gestione delle eccezioni in C#: esiste ma non è obbligatoria. Cioè tu puoi eseguire un metodo che potenzialmente può generare un’eccezione e non prendertene carico. In Java è obbligatorio gestire l’eccezione, e l’errore di non farlo viene segnalato a compile-time. In C# puoi scrivere tutto il codice che vuoi senza usare mai try{} – catch(){}. È una cazzata! Un oggetto genera un’eccezione, non gestita, e si schianta tutto il programma. Ora questo modo di fare avvicina i “programmatori”, perchè è “facile” programmare così, ma il codice e il programma che ne esce è debole.
Secondo esempio: ASP.Net è la controparte web delle applicazioni Web, ed usa lo stesso paradigma degli eventi. Ogni pagina web è un “form” allo stesso modo che in un’applicazione client. E allo stesso modo risponde agli eventi, tipo button_click, che esistono sul client. Questo rende “facile” per un “programmatore” scrivere sia codice per client che per web, perchè sono praticamente identici. Ma in questo modo non c’è una chiara separazione del modello dalla presentazione e dal controller (ossia non c’è un paradigma MVC dietro) e lo “spaghetti code” imperversa. E inoltre la parte di presentazione, di default, è renderizzata con codice HTML 4.01, con un sacco di javascript auto-generato da visual studio. volendo si può costringere la pagina a usare codice XHTML 1.0, ma volendo usare XHTML 1.1 Strict, i controlli web non funzionano perchè sono fuori standard.
Il css non esiste. Questo perchè Visual Studio ti permette di definire le proprietà degli oggetti della pagina in modo “così semplice”, che scrive lui tutto lo stile per gli elementi in modalità “in-line”! Quindi se ti va di cambiare il colore delle pagine devi andare a modificarle tutte, invece di cambiare una riga nel css…
Insomma, l’approccio generale mi sembra questo: “guarda che bei bottoni colorati, clicca qui e là, è facilissimo programmare…” e il risultato è lo spaghetti-code.
In Java si può scrivere codice bruttissimo, ma un minimo di “metodo per fare le cose per bene” c’è, e questo in C# mi manca
ma io ormai sono in ballo, e cercherò di ballare meglio possibile… alla prossima (e via alla flame war!)

“per dipingere una parete grande…”

“…ci vuole un pennello grande!” diceva quel tale…
ma oggi ne ho sentita una ancora meglio: il mio collega R. sta lavorando su un form di un’applicazione. inserisce un bottone “Esegui”. passa il suo capufficio C., guarda il form e dice:

Quel bottone, fallo più grande. Così sembrerà che faccia pià roba…

e uno poi dice che non ci sono più gli sviluppatori di una volta… =)

l’importanza del logging

ho detto logging, non jogging. che fa anche lui bene.
fatto sta che metto in cron sul server di produzione l’ultima mia fatica in java. il programma legge dati da un web service e da un file ascii (circa 15000 record totali) e aggiorna se necessario i record su database.
sto simpatico programmino gira ogni ora per 12 ore al giorno. bene, log4j è il sistema di logging, classico, segnala con una mail se qualcosa va storto e scrive su un file di log gli eventuali record errati. tutto facile.
il programma entra in produzione il giorno 27/12. per qualche motivo il web service viene disattivato il giorno dopo, il 28. ritorno al lavoro mercoledì 3/1, sei giorni dopo: “non sarà successo niente…”. infatti. nessuna mail di errore… strano… ma neanche di successo… come mai???… controllo il file di log. eccolà! 524Mb di file di log!!! ogni inserimento di record sbagliato per 12 volte al giorno per 6 giorni ha generato una o più righe nel file di log, producendo un file assssurdo.
quindi ho riguardato il file di log4j e ho corretto l’appender modificandolo da FileAppender a RollingFileAppender.
e ho scritto 100 volte sulla lavagna: “stai attento a quello che metti in produzione”.
alla maggior parte di voi, di questa storiella non gliene sarà fregato un piffero, per alcuni invece sarà didattica.
per questi ultimi aggiungo allora anche una configurazione buona e valida di log4j, a futura memoria…

<appender name="file" class="org.apache.log4j.RollingFileAppender">
     <param name="File" value="${log.dir}/nome_del_file.log" />
     <param name="Append" value="true" />
     <param name="MaxFileSize" value="1024KB" />
     <param name="MaxBackupIndex" value="10" />
     <layout class="org.apache.log4j.TTCCLayout">
          <param name="dateFormat" value="ISO8601" />
     </layout>
</appender>

novità e progetti

non è che per l’anno nuovo tutti fanno progetti e quindi anch’io. io ce li ho da un bel po’. perlomeno due.
uno importante, roba proprio grossa, l’altro al confronto molto minore, ma che mi può dare soddisfazioni.
il primo è una scelta di vita, l’altro di lavoro.
sul primo potrete trovare info su davidaola, sul secondo metterò qualche notizia qui.
per intanto auguro a tutti, e anche a me, buona fortuna per il 2007