Libri sul debugging


Quanto tempo dedicate durante lo sviluppo al debugging? Quante volte avete la necessita di debuggare un problema su un server di produzione?

Bene, nel mio caso durante lo sviluppo dedico circa il 40% di tempo al debugging ed ogni volta che vi sono problemi servi (hang, crash, memoria...) sul server di test, staging o produzione, mi debbo analizzare il mini dump.

Le tecniche di debugging possono essere estremamente sofisticate o piu' semplici, dipende dal contesto, dal codice e dall'accesso alle risorse. Un valido aiuto arriva sicuramente dai libri, i quali possono dare indicazioni chiare su come muoversi in questa difficile arte.

Cito quindi "Advanced Windows Debugging" per il debugging di codice nativo e "Debugging Microsoft .NET 2.0 applications" per il codice managed.

Ovviamente non deve mancare nel vostro RSS reader il blog della mitica Tess: http://blogs.msdn.com/tess/

 

author: Pierre Greborio | posted @ sabato 28 giugno 2008 0.41 | Feedback (0)

A volte l'eleganza del linguaggio fa la differenza


Poche ore fa stavo rivedendo una 'vecchia' classe che 'simula' il concetto di map. In pratica e' una sorta di dictionary che permette di avere duplicazioni di chiave. Niente di veramente speciale, di fatto usavo una List di KeyValuePair; si pou' fare di meglio, ma qui l'accorcio :-)

Per estrarre i valori data una chiave, ho usato il buon vecchio foreach che andava a riempire una lista di stringhe. In altre parole qualcosa del tipo

List<string> result = new List<string>();
foreach(KeyValuePair<string, string> parameter in parameters) {
  if(parameter.Key.Equals(param))
    result.Add(parameter.Value);
}
return result.ToArray();

Dato che il progetto e' migrato a FX 3.5, ho improvvisato una soluzione LINQ:

return parameters.FindAll(kv => kv.Key.Equals(param)).Select(kv => kv.Value).ToArray();

Devo dire che risulta decisamente piu' chiaro e compatto.

author: Pierre Greborio | posted @ martedì 20 maggio 2008 23.43 | Feedback (6)

[ROA] Contratto


Nel precedente post ho parlato della lacuna della definizione del contratto nel mondo ROA rispetto al mondo SOA. E' bene che faccia qualche precisazione, ma prima di parlare di questo fatemi fare un escursus sul concetto di contratto e come questo si applichi oggi nel mondo SOA (Service Oriented Architecture).

Se chiediamo ad un avvocato di scrivere un contratto, garantendo un certo introito :-), ci innondera' sicuramente di domande e probabilmente scrivera' 40/50 pagine di documento dove ogni singola parola ha un suo peso specifico. In sostanza la regola e', ogni aspetto non 'normato' o definito rappresenta un threat.

In ambito IT si tende ad essere piu' lassisti ed il tempo dedicato a definire il contratto risulta quasi sempre insufficiente. La domanda che ci dobbiamo porre inizialmente e', che cos'e' un service contract? Mi piace molto la definizione data in "SOA: Principles of Service Design" che dice: "A service contract establishes the terms of engagement, providing technical constraints and requirements as well as any semantic information the service owner whishes to make public.".

In termini pratici un contratto viene rappresentato attraverso un insieme di documenti, ognuno dei quali rappresenta un aspetto del servizio. I principali sono

1. Definitzione  del WSDL
2. Definizione dello schema XML
3. Descrizione della WS-Policy
4. SLA, Service Level Agreement

Il WSDL definisce quali funzionalita', in termini di operation e metodi, il nostro servizio espone. Lo schema XML definisce la struttura del payload fra consumer e provider. WS-Policy definisce le modalita' di accesso al servizio (es. sicurezza, crittografia, ecc.). Lo SLA definisce il livello del servizio che siamo in grado o vogliamo mantenere (es. 24x7, 99.99%).

Se noi sviluppassimo un Web Service (con ASP.NET o WCF) seguendo scrupolosamente questa procedura potremmo garantire di avere dei servizi molto solidi e scalabili nel tempo, almeno a livello contrattuale. Purtroppo questo processo oggi non avviene praticamente mai. Il processo che usiamo solitamente e' quello di partire dal codice, applicare gli attributi necessari e fare in modo che il framework esponde i contratti per noi. Il risultato e' che abbiamo contratti molto weak e poco durevoli. I principali motivi sono:

1. Si e' concentrati sul codice e non sul contratto, quindi le funzionalita' che il servizio deve veramente erogare
2. Il contratto e' impreciso in quanto molti frameworks non supportano pienamente le restrizioni degli schemi XML e WSDL
3. Diventa troppo 'facile' cambiare il contratto, edit and build
4. In molti frameworks non vi e' alcuna validazione a runtime dello schema
5. I deserializzatori del payload SOAP sono molto spessi troppo flessibili

Sebbene abbiamo un certo tipo di supporto dai tool di sviluppo per il mondo dei servizi basati su SOAP, meno evidente e' la definizione dei contratti nel mondo ROA (o REST). Sun ha pubblicato una proposta nel 2006 chiamata WADL, Web Application Description Language. Dopo due anni mi sembra sia rimasta abbastanza lettera morta. L'alternativa consiste in WSDL 2.0, nella quale vi e' una buona apertura al binding sul protocollo HTTP.

Quindi, se andiamo a stilare la stessaa lista usata per SOA in ROA, possiamo scrivere:

1. Definitzione  del WSDL 2.0
2. Definizione dello schema XML
3. Descrizione della policy su protocollo HTTP
4. SLA, Service Level Agreement

Che manca allora? Direi una buona coperyura da parte degli strumenti di sviluppo.

 

author: Pierre Greborio | posted @ domenica 11 maggio 2008 15.08 | Feedback (0)

ROA


ROA sta per Resource Oriented Architecture e si contrappone sotto molti punti di vista a SOA, cioe' Service Oriented Architecture.

In realta' non c'e' un modello migliore dell'altro e so potrebbe tranquillamente affermare che un 'servizio' e' necessario per creare una 'risorsa' ed una 'risorsa' e' necessaria per fornire un 'servizio'. Ciononostante possiamo altresi' affermare che il contesto delle risorse e' decisamente predominante.

Quali sono le caratteristiche di ROA:

  • Addressability: intesa come capacita' di identificare una risorsa addraverso uno URI ben definito
  • Statelessness: mancanza di supporto nativo per la gestione dello stato
  • Connectedness: ogni chiamata e' indipendente dalle altre
  • Uniform interface: verbi (GET, HEAD, POST, PUT, ecc.) uniformi per ogni risorsa

Dal mio punto di vista ROA ha molti piu' vantaggi di SOA:

  • Interfacce piu' chiare e facili da testare
  • Modello decisamente piu' conosciuto rispetto a SOAP e molte specifiche WS-*
  • Non ha bisogno di alcuna tecnologia particolare per consumare un servizio
  • Supportato da molti frameworks, come WCF
  • Piu' facilmente tracciabile attraverso i logs di IIS
  • Payload piu' decisamente leggero

Lo svantaggio principale sta nella mancanza di strumenti per formalizzare il contratto.

author: Pierre Greborio | posted @ sabato 10 maggio 2008 20.11 | Feedback (8)

Creare un HttpContext al volo


In queste ultime due ore stavo prototipizzando un micro framework per implementare servizi REST based mediante delle Http handlers. Niente di eccezzionale, ma l'idea di avere qualche cosa di simile a WCF, cioe' dei metodi con una firma prolissa e molto OO, mi piace.

Dopo aver trascorso un'oretta di codifica (refactoring a gogo), ho iniziato a scrivere qualche test. Per testare un Http handler ci vuole un Http context! E come lo creo? Non voglio tirar su tutta la 'baracca' ASP.NET e voglio avere un oggettino dove posso verificare il contenuto della risposta.

Per creare un HttpContext ci vuole un HttpWorkerRequest. Quest'ultima e' una classe astratta dalla quale deriva SimpleWorkerRequest. Creo la mia FakeWorkerRequest con gli ingredienti minimali per il mio scopo, che ricordo essere:

  • Avere un HttpContext valido
  • Poter verificare l'output (string based) della risposta

Con l'amico Reflector identifico in 5 minuti gli ingredienti minimali e implemento la mia classettina

public class FakeWorkerRequest : SimpleWorkerRequest  {
  public FakeWorkerRequest(string relativeUri, StringBuilder output)
    : base("", "", relativeUri, "", new StringWriter(output)) {  }
}

A questo punto sono pronto ad instanziare l'HttpContext che usero' per testare il mio Http Handler (REST + POX):

StringBuilder output = new StringBuilder();
HttpContext.Current = new HttpContext(new FakeWorkerRequest("shows/23", output));

HttpContext.Current.Response.Write("This is a simple test");
HttpContext.Current.Response.Flush();

Console.WriteLine(output);

author: Pierre Greborio | posted @ mercoledì 30 aprile 2008 1.11 | Feedback (0)

Dimensione di un oggetto managed


Recentemente stavo lavorando su un servizio che alloca un oggetto di grandi dimensioni. La domanda che mi son posto era, si ma quanto e' grande e dove posso ottimizzare?

Ho aperto Visual Studio profiler ed ho fatto partire il servizio. Dato che l'applicazione, quando parte, deve deserializzare questo oggettone, ci stava mettendo una vita (ho fatto tempo a pranzare ed era ancora li a macinare). Abbandonato il profiler di Visual Studio ed ho usato CLR profiler, niente da fare, stesso problema!

L'unica soluzione che mi e' rimasta in canna e' WindDbg con le estensioni SOS. Faccio partire il processo e carico WinDbg agganciandolo al mio processo. Inizio con leggere le statistiche degli oggetti managed nello heap:

!dumpheap -stat

Da li vedo il mio oggetto in questione con il numero di instanze (1 per l'occasione) e la dimensione. La dimensione che vedo e' quella dell'oggetto da solo, e non include gli oggetti che contiene. Mi serve quindi ricavare l'indirizzo fisico del mio oggettone, richiamo quindi

!dumpheap -mt 0x...

Una volta che ho l'indirizzo fisico del mio oggetto (puntatore), basta chiamare objsize

!objsize 1dd7a55c

E voila', ecco la dimensione reale del mio oggetto. Ora che so quanto e' grande, vorrei sapere quale degli oggetti che referenzia consuma piu' memoria. Faccio il dump dell'oggetto:

!dumpobject 1dd7a55c

Ok, ho tutti gli elementi per procedere nell'ottimizzazione dell'uso della memoria.

author: Pierre Greborio | posted @ martedì 22 aprile 2008 23.16 | Feedback (1)

Professional IIS 7


E' uscito recentemente un nuovo libro su IIS 7, Professional IIS 7, di cui ho fatto da technical editor. Lo considero un libro di buona qualita' (non posso dire eccellente!) che copre molto bene la parte architetturale, di deployment e management. E' un libro che consiglio anche agli sviluppatori in quanto e' sempre necessario conoscere dove va a finire il nostro codice :-)

Buona lettura a tutti...

author: Pierre Greborio | posted @ venerdì 18 aprile 2008 1.17 | Feedback (0)

Edge caching


Il tema dell'edge caching e' un tema estremamente intrigante e sotto molti punti di vista complesso. Si parte dalla soluzione null cache, dove in pratica non si mette nulla in cache, per proseguire alla cache uniformemente distribuita, in stile ASP.NET per intenderci, fino ad arrivare alle collaborative edge cache networks.

Qual'e' la soluzione ideale? Tutte e nessuna. Dipende totalmente dal contesto, ed in particolare dalla dinamicita' delle modifiche dei dati, dalla loro dimensione e quantita', dal modo di essere consumati, dal livello di sicurezza, dalla scalabilita', dalla topologia di rete del sistema di distribuzione, dall'uniformita' di distribuzione dei dati sull'edge, consistenza e delays.

1. Dinamicita' di modifica

Vi e' una notevole differenza fra dati che variano in tempo reale e dati che cambiano a scadenze prolungate (una volta al giorno o una volta alla settimana). I primi si adattano poco ad essere messi in cache, i secondi decisamente. Mi pare solamente una basilare regola i buon senso :-)

2. Dimensione e quantita'

Immaginiamo di avere un catalogo prodotti. Mettere il catalogo in cache porta sicuramente dei vantaggi, ma dipende dalla dimensione dei catalogo. Immaginate di mettere tutto il catalogo di Amazon in cache su ogni singolo server! Non ha senso ovviamente. Si puo' quindi ragionare in termini di partizionamento dei dati frammentandoli con algoritmi statistici. Ad esempio caricare in memoria solamente i piu' venduti/consultati e leggere on demand i meno venduti/consultati.

3. Modalita' di consumo

Se abbiamo una applicazione ASP.NET sicuramente l'opzione memoria e' difficilmente sostituibile, ma se abbiamo uno smart client perche' non pensare ad un file precompilato? Sicuramente una chiamata HTTP GET su IIS sara' decisamente piu' performante e scalabile di qualsiasi web service.

4. Livello di sicurezza

Trattare la lista dei codice fiscale piuttosto che i risultati delle partite di calcio e' molto diverso. Si possobo adottare algoritmi di crittografia e/ firma digitale. Da questo punto di vista l'erogazione attragerso una HTTP GET piuttosto che un web service o la memoria fa poca differenza.

5. Scalabilita'

Immaginate di avere il vostro catalogo prodotti che cambia una volta al giorno ed e' salvato nel DB. Avere 1000 o piu' server che richiedono la nuova lista nello stesso momento potrebbe afere un impatto negativo nel DB. Ecco allora che produrre con un agent la cache su file e renderal disponibile ai fari edge via HTTP GET os network share potrebbe risolvere il problema.

6. Topologia di rete del sistema di distribuzione

In alcuni ambienti distribuiti l'edge non ha accesso diretto alla fonte informativa. Ecco allora che si possono introdurre delle cache intermedia, o dei beacon points in stile collaborative edge cache. In pratica si suddivide la rete in rings, all'interno dei quali ci sono dei server privilegiati (beacon points) che fanno da 'ponte'.

7. Uniformita' di distribuzione dei dati sull'edge

Non sempre abbiamo bisogno di tutti gli stessi dati su tutti i server dell'edge. Ecco quindi che dobbiamo razionalizzare i dati e decidere a design time come definire le regole di partizionamento in modo da distribuire partizioni differenti su server differenti.

8 Consistenza e delays

In sistemi distribuiti e' perfettamente accettabile vi siano dei delay, lo e' meno la mancanza di consistenza. Ad esempio e' accettabile che quando si cambi un prodotto nel catalogo questa modifica arrivi sui server anche con minuti o ore di ritardo, ma e' fondamentale che tutti i server propongano le stesse modifiche in modo consistente. Immaginate due server in NLB che prima propongono 10 euro e al secondo click 11 euro! La soluzione consiste nella collaborazione fra i server e nel versioning dei dati.

In questa lista ho ovviamente guardato al problema solamente in modo superficiale e ogni singolo aspetto andrebbe analizzato in profondita'. Diciamo che e' uno spunto di pensiero :-)

author: Pierre Greborio | posted @ martedì 15 aprile 2008 10.07 | Feedback (0)

String replace


Da 4 mesi a questa parte sto scrivendo un nuovo servizio che fa pesante uso di manipolazioni di stringhe. Parlo di replace, wrod braking, stemming, ecc. ecc.

Questa mattina mi son letto un interessante post sulle prestazioni delle varie funzioni Replace disponibili nel framework: Comparing RegEx.Replace, String.Replace and StringBuilder.Replace – Which has better performance? Il post mi pare un pochetto incompleto in quanto non da riferimenti sull'uso delle risorse, in particolare della memoria. Nell'analisi delle prestazioni e' infatti fondamentale verificare sia il tempo che il consumo della memoria.

Abbandonato il post torno ai miei compiti quotidiani. Una delle funzioni che maggiormente uso, e' il multi string replace, cioe' devo sostituire piu' stringhe contemporaneamente. Ovviamente mi sono basato sullo strategy pattern in quanto probabilmente un domani trovero' un algoritmo piu' efficiente. La prima strategia di base alla quale mi sono affidato e' di evocare String.Replace per ogni sostituzione. Dato che la soluzione non mi piaceva in quanto prevede di dover fare N scan per ogni stringa da sostituire ho iniziato ad investigare alternative. Una di queste e' sicuramente basata sull'algoritmo di Aho-Corasick il quale viene solitamente utilizzato per il multi-string matching.

Non ho ancora fatto misurazioni di performance, ma se avete dei suggerimenti su alternative lasciatemi un messaggio. Molte teste sono meglio di una :-)

 

author: Pierre Greborio | posted @ mercoledì 2 aprile 2008 9.37 | Feedback (2)

Servizio al cliente


Ho sottoscritto l'abbonamento a NetFlix un annetto fa. Per capirci funziona come un normale video noleggio solo che va tutto per posta. Chiedi un film, te lo mandano (in un giorno ce l'hai a casa), quando hai finito di vederlo lo lasci nella cassetta della posta (con la bandierina alzata) e ritorna indietro. Prosegue lo stesso processo a ciclo continuo.

Lunedi' dovevano partire i nuovi DVD che avevo richiesto e per un disguito non sono partiti. Ecco quindi che trovo un'email:

We're Sorry Your DVD Was Delayed
Dear Pierre,

As you may have heard, our shipping system was unexpectedly down for most of Monday. We should have shipped your DVDs but were unable to. Your DVDs were shipped today, Tuesday, March 25th, instead.

We are sorry for any inconvenience this has caused. We will issue a 5% credit to your account in the next few days. You don't need to do anything. The credit will be automatically applied to your next billing statement.

Again, we apologize for the delay and thank you for your understanding. If you need further assistance, please call us at 1 (888) 638-3549.

-The Netflix Team

Non avevo chiesto nulla!! Chiedono scusa, mi rimborsano il 5% e mi inviano il DVD. Molte aziende dovrebbero imparare...

author: Pierre Greborio | posted @ mercoledì 26 marzo 2008 9.57 | Feedback (1)