Info:

twitter

Ultimi commenti: Comment feed

Tags:

Sponsor:

Archivio 2018:

Giu Mag Feb Gen

Archivio 2017:

Dic Nov Ott Mag Apr Mar Feb Gen

Archivio 2016:

Dic Nov Ott Ago Mag Mar Feb Gen

Archivio 2015:

Nov Ott Set Mar Gen

Archivio 2014:

Dic Nov Ott Set Lug Giu Mag Apr Gen

Archivio 2013:

Dic Nov Set Ago Lug Giu Mag Apr Feb Gen

Archivio 2012:

Dic Nov Ott Set Ago Giu Mag Apr Mar Feb Gen

Archivio 2011:

Dic Nov Ott Set Ago Lug Giu Mag Apr Mar Feb Gen

Archivio 2010:

Dic Nov Ott Set Ago Lug Giu Mag Apr Mar Feb Gen

Archivio 2009:

Dic Nov Ott Set Ago Lug Giu Mag Apr Mar Feb Gen

Archivio 2008:

Dic Nov Ott Set Ago Lug Giu Mag Apr Mar Feb Gen

Archivio 2007:

Dic Nov Ott Set Ago Lug Giu Mag Apr Mar Feb Gen

Archivio 2006:

Dic Nov Ott Set Ago Lug Giu Mag Apr Mar Feb Gen
Graceful Degradation

Qualche giorno fa, a causa di problemi sul server di hosting, lo sfortunato avventore s’è beccato qualche schermata di errore del tipo:

YSODconosciuta anche con il nome di ASP.Net YSOD (Yellow Screen of Death). In un paio di occasioni questo è capitato per una mancata risposta del backend SQL, magari beccato durante un riavvio di manutenzione, altre volte per problemi un po’ più seri come la carenza di spazio libero quando in realtà avevo teoricamente a disposizione più di 99GB rimanenti.

La YSOD è praticamente una schermata di debug utile per lo sviluppatore: nel caso in questione però saranno ormai diversi mesi che non vedo uno YSOD causato da problemi di codice, quindi ho deciso di disabilitarne l’uso in favore di una schermata più simpatica. Per imparare qualcosa ho cercato di fare le cose per bene, perché quando mi prende va a finire che anche per le puttanate son capace di spendere ore ed ore. Il risultato lo si può ammirare in questa pagina:

Gracefully degradeLa cosa più antipatica da realizzare è stato il centraggio della box in primo piano, cosa rivelatasi impossibile tramite CSS e basta. Un po’ di JavaScript + JQuery e la paura e passata; col senno di poi però arrivare a scrivere codice JS per una pagina statica di errore mi sembra pura follia…

-quack

Pubblicato giovedì 24 settembre 2009 alle 12:17 AM - 39 commenti so far
Archiviato in: Blog-Tech

Standard e trasparenza

Ieri giochicchiavo con una piccola feature da inserire in Blogoo che avevo stimato in mezz’ora di research and development (ma poi è andata a finire in leggera contro-tendenza). Volevo fare in modo che nel momento in cui si invia un commento comparisse una finestra trasparente con una ruota che gira stile boot loader di OS X. La parte più difficile dell’impresa è stata trovare la gif animata: l’avevo vista in giro usata come avatar in diversi forum, ma non ne ho mai annotato la URL e ritrovarla è stata una missione quasi impossibile. Come vuole Murphy oggi ho notato una GIF molto simile e a tratti meglio indicata navigando per caso.

Trovata la GIF è stato abbastanza semplice generare il codice JavaScript che implementasse la funzionalità voluta: un bel DIV in primo piano ma nascosto che diventa visibile con il click del pulsante, roba che si trova in giro al primo secondo colpo ravanando su stackoverflow.com.

Le ultime difficoltà le ho trovate implementando il livello di trasparenza in maniera tale che funzionasse con i tre motori di rendering principali e le varie sub-version. Il browser più problematico è stato – manco a dirlo – IE8, che nella modalità di rendering di default non ne voleva proprio sapere di gestire la direttiva. Bingolando tra i forum si trova solo gente incazzata e poca razionalità: se ci penso mi sono incazzato anche io pensando quanto fosse stupido scegliere di non supportare l’opacità così come era disponibile in IE7. La realtà invece è molto più pragmatica: la vecchia sintassi non è “conforme” e lo standard dice chiaramente cosa fare in presenza di tag non conformi e cioè vanno ignorati. I dettagli sono racchiusi in questo post. La cosa che mi ha fatto più riflettere è che la totalità delle lamentele di cui ho letto era critica nei confronti di tale scelta giustificando l’astio con qualche pregiudizio. E mi son reso conto che quanto avevo letto in passato e cioè che molti hanno chiesto a gran voce il supporto agli standard non sapendo neanche quanto di ciò che usassero lo fosse davvero; chi scriveva faceva l’esempio dei bordi arrotondati che “tutti gli altri browser” supportano tranne IE. Esempi che poi sono alla base di test suites come gli (in)famosi Acid Test v. 3.

Morale della favola: non sempre quello che si desidera è quello che si dice di voler desiderare. Si è desiderato a gran voce il pieno supporto degli standard quando in realtà si voleva “un rendering che fosse compatibile quanto più possibile tra i vari browser”.

L’ultimo ostacolo era la mancata animazione della GIF in IE8 su Win7/RC; ho notato subito che era un problema legato al caching delle GIF ed è bastato aggiungere un parametro casuale fasullo alla fine della URL per risolverlo. Questo ad ulteriore supporto del fatto che non ritengo che questo sia il miglior mondo possibile dal punto di vista dell’HTML e dintorni bachi inclusi. Come ci si muove da questo al prossimo (HTML 5? Flash/Gears/SL vNext?) è un problema per niente banale.

-quack

P.S. funziona?

Pubblicato martedì 2 giugno 2009 alle 10:07 PM - 89 commenti so far
Archiviato in: Blog-Tech, Codice

Messaggio di servizio #42

L’inevitabile è accaduto, ho cambiato ISP. Dal punto di vista pratico è un cambio di DNS ma finché la modifica sarà propagata potrebbe rispondere il vecchio ISP.

ISPChange

Sperando che almeno sia un po’ più affidabile del vecchio. Se i commenti sono bloccati, vuol dire che il DNS non è ancora rinfrescato. Intanto mi sto inventando qualcosa per rendere leggibile a tutti questo messaggio.

-quack

Pubblicato mercoledì 28 gennaio 2009 alle 2:57 AM - 7 commenti so far
Archiviato in: Blog-Tech

Caching

Come promesso in precedenza eccomi a parlare di codice e di come ho implementato il sistema di cache in blogoo. È diventato necessario quando il numero di commenti per post ha cominciato a superare una certa soglia: il mio ISP è molto generoso ma prevenire resta sempre meglio che curare. Senza la cache la pagina viene renderizzata ad-hoc ogni volta che viene invocata. Questo è un peccato perché buona parte dell’output restituito al browser è ‘facilmente’ sistemabile in una cache. Facilmente è tra virgolette perché gli elementi della sfida sono tanti:

  1. è interessante fare tenere nella cache sia le pagine che puntano ad un singolo post, sia le pagine che contengono più di un post (la home-page, gli archivi, le pagine per tag, ecc.), sia dei “pezzi di pagina” (gli ultimi commenti, tag-cloud, archivio, ecc.) 
  2. la cache deve gestire correttamente sia le pagine visibili solo dall’editor del blog, sia quelle visibili dagli utenti cercando di non fare confusione
  3. la cache deve essere invalidata solo quando necessario; nel dubbio se sia necessario o meno è meglio invalidare che servire contenuto “scaduto”.
  4. Se possibile è meglio invalidare solo lo stretto necessario: ad esempio la tag-cloud dovrebbe essere invalidata solo in caso di modifica/aggiunta di post o di categorie
  5. la cache deve essere invalidata quando del contenuto “post-datato” diventa automaticamente visibile

Analizzando la questione a tavolino sono emerse un paio di cose. Gli eventi invalidanti sono in generale 2: l’aggiunta/modifica di un commento, l’aggiunta/modifica di un post. Tutto il resto, ad esempio il punto 5., può essere ricondotto ad uno dei due casi. L’aggiunta/modifica di un post poi può a sua volta generare due tipi diversi di eventi: un evento che invalida la “collezione dei post” ed un evento che invalida il singolo post. Ad esempio un commento sul post X invaliderà la collezione dei post (in quanto tale collezione potrebbe mostrare il numero di commenti per quel post), invaliderà il post X ma non il post Y. Per cui se un utente clicca sul post Y dopo che è stato scritto un commento su un altro post, si ritroverà il post servito dalla cache.

L’invalidazione poi tiene conto di diversi fattori. Ad esempio cancellare un commento moderato non deve avere effetti sulla cache in quanto non visibile a priori. Stessa cosa per la pubblicazione di un draft e così via.

Fatto questo, il resto diventa un gioco da ragazzi: ogni elemento inserito nella cache porta in dote la sua lista di dipendenze. Un componente separato da me battezzato CacheManager si mette in ascolto dei vari eventi (creazione/modifica/cancellazione dei post/commenti) e in base allo stato della cache, al tipo di evento e le condizioni a contorno (era un draft? è diventato un draft? c’è qualche articolo postdatato in coda?) invalida zero, una o più dipendenze causando la rimozione a cascata di tutti gli elementi da esso dipendenti. L’unica accortezza è gestire correttamente la “scadenza” della cache: nel momento in cui del contenuto viene prelevato dalla cache va confrontata la data di “prelievo” con la data di "scadenza" e se la cache è scaduta la data di scadenza viene ricalcolata, ciò che va invalidato viene invalidato, e tutto il resto prosegue come prima.

Infine un’ultima nota: avrei potuto tenere una cache separata per gli editor, però mi è sembrato più saggio fare in modo che il contenuto fosse manipolato a posteriori.

I risultati sono sorprendenti: il post da quattro mucche caroline e 428 (!) commenti viene renderizzato in 5 secondi senza cache, appena 192 millisecondi se il post è già presente in cache. Considerato il tempo sprecato (mezza giornata circa) ed i risultati ottenuti, direi che ne è valsa davvero la pena.

Nota aneddotica: il baco più antipatico, l’Heisenbug che faceva sparire i commenti di Daniele B. dalla cache, era dovuto al fatto che il mio ISP usa un sistema arcano di load-balancing per cui le richieste al sito www finivano solo alcune volte per essere eseguite dallo stesso server che gestisce il sito senza www. Che poi non ho ancora capito perché a livello di hosting, visto che i due siti puntano allo stessissimo contenuto, sono configurati come due siti separati: individuato il problema, la soluzione è stata semplice e immediata. Redirect 301 di tutte le richieste www al sito principale. La cache è sempre sincronizzata e tutti i paperi (?) vissero felici e contenti.

-quack

Pubblicato sabato 29 novembre 2008 alle 6:28 AM - 4 commenti so far
Archiviato in: Blog-Tech

Commenti

[pippone semi-tecnico che un giorno ospiterò su un altro blog]

I commenti sono la parte più delicata ed importante di un blog. Importante perché un blog senza commenti è come il sale senza la pasta; delicata perché si può finire vittima di attacchi XSS: non che per me sia importante, ma visto che ho colto l’occasione per imparare a sviluppare un CMS quasi da zero tanto vale cercare di essere quanto più diligente possibile.

Nelle passate due settimane ho speso un sacco di tempo nel cercare una soluzione bilanciata per l’editing dei commenti: mi sono sempre meravigliato perché piattaforme di blogging importanti anche come Wordpress non supportassero l’editing in modalità Rich Text in maniera nativa anche se supportano un set limitato di tag HTML in maniera egregia. Pensavo, a dir la verità in maniera piuttosto naive, che bastasse includere un JavaScript (TinyMCE, FCKEditor o qualsiasi altro) per rendere la textarea magicamente user friedly. Fino a quando non ho provato l’esperimento in maniera diretta. Lo scopo di tutto questo spremermi di meningi era volto non solo nel rendere il sistema di commenti pratico e semplice, ma anche ridurre al minimo i miei interventi di post-editing necessari per un tag non chiuso o una sostituzione andata a male (:) –> ).

Un commento dal momento in cui viene premuto il tasto pubblica, al momento in cui viene “rivisualizzato indietro” subisce così tanti passaggi che alla fine la questione cresce di complessità in maniera geometrica: supporto degli smiley, supporto della creazione/accorciamento automatico dei link, supporto per alcuni tag (grassetto, corsivo, sottolineato e barrato; citazione e link), lettere accentate, varie ed eventuali.

Pensare che un search/replace/regex possa sistemare tutto tutto tutto si è dimostrato totalmente scorretto. Ad esempio l’accorciamento delle URL va fatto nel testo “normale” ma non all’interno di <A href>; la sostituzione degli smiley va fatta fuori dai tag; i tag invalidi vanno eliminati anziché essere HTML-codificati.

In seguito mi è venuto anche il pallino di rendere l’editor RichText configurabile come opzionale e supportare quello che io chiamo il semi HTML, ovvero l’ibrido tra HTML e plain text che quasi tutte le piattaforme supportano. Esempio:

Se l’input è HTML full il seguente HTML <b> &amp; </b> deve essere la rappresentazione di ciò che va renderizzato come &; se l’input è in semi HTML lo stesso diventa la rappresentazione di &amp; i line break (\r\n) vanno convertiti in <p> e <br/>, ecc. Ovvero tutto quello che c’è all’interno dei tag HTML va considerato plain text e come tale va passato attraverso un bel HTMLEncode/LineBrake.Convert. Ho considerato che tale pallino avesse costo limitato in quanto questo era esattamente il modo in cui operava la TextArea prima del lifting. Visto che c’ero ho voluto pure fare in modo che il backend fosse aware se il plugin Javascript fosse stato lanciato con successo o meno (JS magari disabilitato o altro): se il plugin non risulta inizializzato il backend tratterà l’input come semi-HTML anziché HTML full.

Infine ho anche cercato di evitare che il copia-incolla desse la falsa illusione di supportare anche tag non supportati, tipo le immagini. Il primo tentativo è stato quello di abilitare il cut-paste in modalità plain-text only. Con FCKEditor la cosa è supportata out-of-the-box, con TinyMCE ho dovuto fare qualche giro di troppo alla fine mi sono arreso.

Nel provare TinyMCE e FCKEditor mi sono reso conto dei limiti dell’uno e dell’altro. FCKEditor – prima che mi si accendesse la lampadina del distinguere completamente il semi-HTML dall’HTML full – era stato problematico per la sua estrema fedeltà all’HTML. Se si digitano due spazi consecutivi il secondo verrà giustamente e automaticamente convertito in &nbsp;. E questo creava non pochi grattacapi nella gestione degli smiley (o delle URL) che per essere interpretati correttamente hanno bisogno di essere “staccati” dal testo tramite uno spazio o equivalente (inizio riga, fine riga). TinyMCE invece mi ha dato non pochi problemi con il cut&paste, ma in compenso è stato abbastanza semplice fare in modo che prima di “pubblica” l’editor ci prefissasse una stringa nota per segnalare al backend che il JS era stato inizializzato correttamente. Tornando ad FCKEditor ho avuto molte difficoltà nell’editare il contenuto del testo e alla fine ho cercato una soluzione altrettanto pratica.

Alla fine il risultato è sintetizzabile nei seguenti passaggi:

  • filtrare tutti i tag HTML non presenti nella whitelist
  • iterare su tutto il contenuto che non è un tag HTML e fare le sostituzioni del caso (in realtà alcune sostituzioni sono applicabili anche all’interno di alcuni tag)

Questi due compiti non sono così semplici come si può immaginare, basta un esempio più banale per rendersi conto di quanti trabocchetti ci sono per la via. Io mi sono affidato a buona parte del codice di gestione dei commenti di DasBlog, anche se date le drastiche modifiche richieste sono in preda ad una tentazione di refactoring.

Se occorre ampi pezzi di codice C# sono a disposizione. Oltre al classico feedback per critiche, osservazioni, ecc.

Il prossimo post sull’argomento riguarderà i pericoli intrinseci del fare caching dei risultati.

-quack

Pubblicato venerdì 14 novembre 2008 alle 1:30 AM - 22 commenti so far
Archiviato in: Blog-Tech