Forse l'attacco di blogorroicità di Lorenzo non ha fatto notare ai più la mia assenza odierna, ma quest'oggi ho passato l'intera giornata lavorativa serrato in una stanza con un collega per farel'analisi di un modulo applicativo.

A parte che quando sono uscito alle 18:30, qualcuno mi ha scambiato per uno zombie, devo rilevare che la giornata è stata davvero produttiva. Sono sempre colpito dal notare la "potenza" liberata da due menti che lavorano in sinergia per smontare un problema pezzo per pezzo. Noi inoltre siamo stati supportati da Skype (eccelente) che ci ha permesso di tenerci in contatto con il cliente distante 1000Km, per porre domande e sottoporre soluzioni che si presentavano mano a mano che le componenti fondamentali del problema venivano erose.

Ne siamo usciti con un piano di lavoro ben dettagliato, e soprattutto con le idee chiare sulla struttura che dovremo dare al progetto, e su quelle che saranno le funziaonalità che per prime saranno realizzate. In consiglio che sta nel titolo è sacrosanto. Non affrontate mai un problema in completa solitudine, potreste perdere il doppio del tempo e non arrivare mai ad una soluzione efficace.

Indipendentemente da quanto abili siate.

powered by IMHO

tags: - categories:

Sembra che il team di sviluppo di Sql Server 2004, impegnato nella realizzazione della Service Pack 4, abbia la necessità di trovare dei beta tester per poter rilasciare il prodotto entro i prossimi mesi. Se qualcuno desidera provarci può tentare qui:

http://www.microsoft.com/sql/evaluation/betanominations.asp

Fonte: Do you want to help test SQL Server 2000 Service Pack 4?

powered by IMHO


Finalmente, dopo alcune settimane di test posso permettermi di dire la mia su SourceGear. Chi mi legge da un po' di tempo sa di certo che io sono sempre un accanito difensore di CVS, contro il concorrente diretto Source Safe, che considero tuttora una magra consolazione. Ho avuto occasione di confrontare questi due sistemi di controllo sorgente, e di metterne alla prova le caratteristiche in dei casi limite e CVS ha sempre vinto più che ai punti, per K.O. alla prima ripresa.

Oggi, posso dire con tutta tranquillità che SourceGear non ha nulla, ma proprio nulla da invidiare al blasonato CVS, del quale è addirittura in grado di emulare il funzionamento. SourceGear lavora totalmente attraverso il protocollo HTTP perciò è facilissimo configuralo per consentire il lavoro ad un team distribuito, addirittura meglio di CVS che utilizzando delle porte proprietarie richiede che si debba mettere mano al firewall. Inoltre la velocità di trasferimento dei file è di tutto rispetto. Con alcuni colleghi abbiamo trasferito 15MB di files con un Get Latest Version senza che il sistema battesse ciglio, naturalmente in un tempo decisamente congruo, è del tutto paragonabile a quello di CVS compresso al massimo grado (Z9).

Le feature di SourceForge sono moltissime e soprattutto di utilizzo facilissimo. Labes, sharing dei nodi, branches, pin, cloak, history, keywords, e chi più ne ha più ne metta. In azienda ho configurato un server con SourceGear e spero al più presto di poterlo usare esclusivamente, non appena avremmo acquistato le licenze necessarie. A casa naturalmente la versione free è già installata e configurata ed è diventata il repository ufficiale di IMHO.

L'integrazione con Visual Studio .NET è molto ben fatta ed è addirittura più solida di quella di Source Safe. Nelle prime fasi successive l'installazione ho smanettato parecchio per cercare di piegare il repository alle mie esigenze, e nonostante il recalcitrare di Visual Studio e gli innumerevoli ripensamenti, e correzioni alla fine tutto ha funzionato per il verso giusto e soprattutto senza perdere una riga di codice. Provateci con SourceSafe. Se siete fortunati potete al massimo consentire a Visual Studio di organizzare il repository come preferisce, e senza possibilità di replica da parte vostra.

powered by IMHO

tags: - categories:

All'inizio dello scorso dicembre ho postato nel blog due righe in riferimento SMS.AC che mi aveva visto vittima di un mailing selvaggio verso i miei contatti. Sono felice del fatto che a tutt'oggi continuo a ricevere commenti da naviganti che sono salvati dal subire la stessa sorte grazie al mio messaggio.

Lieto di essere un baluardo nella lotta agli spammer di ogni genere.

powered by IMHO 1.2

tags: - categories:

Ho seguito il suggerimento di Lorenzo e mi sono mappato. Quello che mi sembra strano è che pur non avendo indicato l'indirizzo, la faccina sulla mappa è situata nell'esatta posizione in cui si trova l'azienda per cui lavoro...

my blogmap

E' solo un caso?

powered by IMHO 1.2

tags: - categories:

In questi giorni sto lavorano per ideare una architettura di un nuovo progetto per una web application. Si tratta di un progetto abbastanza semplice, ma ormai non sono più in grado di scrivere del codice senza prima aver definito un minimo di dettaglio architetturale, anche perchè ad ogni nuovo progetto tento sempre di migliorare quello che può essere la base dell'applicazione con l'esperienza maturata nei progetti precedenti.

Così mi sono imbattuto in un comportamento che a dire la verità avrei dovuto immaginare, ma che di primo acchito mi ha sconcertato. In effetti più che in una categoria "lo sapevate che" questo post dovrebbe andare in "avete mai considerato che". Quello che è successo è che ho provato ad esporre lo strato di logica applicativa, quello intermedio tra data layer e interface per intenderci, per mezzo di un Singleton. Che Singleton e Web non andassero molto daccordo ne ero già convinto, ma gli eventi mi hanno rafforzato ancor di più questa convinzione.

Scritto il codice di base e fatti i dovuti test, mi sono posto di problema di che "scope" avesse il Singleton. Sbadatamente avevo considerato che una classe fosse Singleton nel thread che elabora la pagina, perciò questo non avrebbe avuto nessuna conseguenza sulle altre pagine. Tuttavia una verifica andava fatta, ed ho così deciso di creare un campo statico e di valorizzarlo con il SessionId del chiamante. Ovviamente quello che è successo è stato che l'id valorizzato da un thread era poi visibile da un'altra istanza di browser.

Quello che ne evinco è quindi che l'uso di una classe Singleton provoca "l'allocazione" (scusatemi il termine improprio) di una porzione di codice eseguibile nel processo host, e quindi anche del relativo spazio di allocazione per variabili & co. Morale sia quindi che i Singleton, almeno usati per lo scopo iniziale che avevo individuato, non si possono usare, soprattutto se essi devono mantenere uno stato al loro interno. Infatti in questo caso sarebbe necessario utilizzare dei lock esclusivi (un po' come si fa con le Application) per evitare delle situazioni di concorrenza e quindi ci si esporrebbe al decadimento delle performances.

La mia soluzione finale, è stata quella di creare una classe base per le pagine dell'applicativo, che inizializza un'istanza del controller della logica sull'OnInit e lo distrugge se necessario sull'OnUnload. Un po' più laborioso di un Singleton, ma certamente migliore.

powered by IMHO

tags: - categories:

Apprendo da una lettera Marco Cappato questa grande notizia. Alcuni scienziati sono riusciti a differenziare delle cellule staminali embrionali trasformandole in motoneuroni, proprio le cellule che la Sclerosi Laterale Amiotrofica attacca. Si apre così uno spiraglio di speranza per Luca Coscioni e tutti gli ammalati di questa orribile malattia. Peccato che ad oggi, questa ricerca sia del tutto vietata in Italia.

Un motivo in più per battersi per la vittoria completa sui referendum.

Link: Lettera di Marco Cappato al Foglio

powered by IMHO

tags: - categories: News

Devo frenare l'entusiasmo. Ho iniziato ad utilizzare in un progetto la Microsoft Enterprise Library e oltre ai benefici enormi che sembra si possano ottenere, ho appena scoperto un _fantastico_ tool che è incluso nell'installazione

Con questo configurator è possibile gestire ogni minimo dettaglio della configurazione degli Application Blocks che fanno parte della library. E' sufficiente aprire il file di configurazione dell'applicazione e il configurator andrà a prendere i vari spezzoni di configurazione referenziati e li mostrerà com è visibile nella figura.

Semplicemente fantascientifico!

powered by IMHO 1.2

tags: - categories: News

della mia vita e di altre amenità

L'asincronia sta ormai diventando una questione di tutti i giorni nelle applicazioni moderne così i linguaggi come C# si sono adeguati con costrutti come async/await. Javascript, pur essendo un linguaggio ormai antico secondo i tempi cui l'informatica ci ha abituato, gestisce da sempre molte attività in modo asincrono, utilizzando il meccanismo dei callback. Un esempio è il setInterval in cui uno degli argomenti passati è la funzione da chiamare ad intervalli regolari.

Librerie come jQuery e Angular stesso espongono numerosi casi di utilizzo di metodi asincroni. L'http service di Angular ad esempio è uno di questi casi. Esso però non utilizza normali callback ma un sistema molto simile al Task<T> di C#. Le promise. In effetti da ciascuna chiamata asincrona è ritornato un oggetto Promise che dispone dei metodi then, catch e finally. Questi servono per associare un callback a ciascuno delle condizioni che i nomi dei metodi evocano.

Ma la domanda cui vogli rispondere in questo post è la seguente: come faccio ad esporre una promise da un mio metodo asicrono se esso stesso no usa un servizio che la utilizzi? E' il caso ad esempio di un metodo che visualizzi una dialog modale. Essono mo potrà mai essere sincrono perchè oltre a risultare bloccante per il browser, non sarà comunque possibile gestire una eventuale "attesa" e ritornare dal metodo alla chiusure della dialog. Quello che ci viene in soccorso è il Q service. Esso è usato dallo stesso http service è ha come unico scopo la gestione asincrona. Vediamo un esempio:

   1: public showDialog(message: string, title: string = Constants.defaultModalTitle, commands?: IDialogCommand[]): ng.IPromise<string>
   2: {
   3:     var defer: ng.IDeferred<any> = this.$q.defer<string>();
   4:  
   5:     try
   6:     {
   7:         this.modalDialog.find('.modal-body').text(message);
   8:         this.modalDialog.find('.modal-title').text(title);
   9:  
  10:         var footer = this.modalDialog.find('.modal-footer');
  11:         footer.empty();
  12:  
  13:         for (var i in commands)
  14:         {
  15:             var cmd = commands[i];
  16:  
  17:             var button = $(Constants.modalButtonMarkup);
  18:  
  19:             button.text(cmd.text);
  20:             button.addClass(cmd.style == undefined ? 'btn-default' : cmd.style);
  21:             button.data('command-id', cmd.id);
  22:  
  23:  
  24:             button.click((ev) =>
  25:             {
  26:                 var id = $(event.srcElement).data('command-id');
  27:                 this.modalDialog.modal('hide');
  28:                 defer.resolve(id);
  29:             });
  30:  
  31:             button.appendTo(footer);
  32:         }
  33:  
  34:         this.modalDialog.modal('show');
  35:     }
  36:     catch (error)
  37:     {
  38:         defer.reject(error);
  39:     }
  40:  
  41:     return defer.promise;
  42: }

Diamo per assodato che questo metodo faccia capo ad una classe che ha ricevuto una istanza del Q service come argomento del costruttore. Come segue:

   1: constructor(private $q: ng.IQService)
   2: {
   3: }

Il metodo showDialog al proprio inizio crea una istanza di una classe di tipo IDeferred<any>, dove any è il tipo del valore ritornato dal metodo in questione. L'oggetto deferred è quello che ci serve per gestire l'asincronia. Al termine del metodo infatti viene ritornata la promise che esso contiene con "defer.promise".

A questo punto è necessario invocare i callback di successo (then) e quello di fallimento (catch). Per farlo sono utilizzati i metodi "resolve" e "reject" dell'oggetto deferred.

Così facendo è possibile usare il metodo come segue:

   1: this.showDialog(
   2:     'Are you sure you want to delete the item',
   3:     'Confirm operation',
   4:     sys.Constants.modalYesNo).then(
   5:         (id: string) =>
   6:         {
   7:             if (id == sys.Constants.Positive)
   8:             {
   9:                 // delete the item here
  10:             }
  11:         });

Il sistema è l'unico consigliato. Infatti l'utilizzo dei callback normali crea problemi al sistema di databinding di AngularJS. Invece il q service è perfettamente in grado di supportarlo.


Aggiungi Commento