Monthly Archives: January 2009

Internet non è il WEB

Ogni giorno sento e leggo persone fare confusione tra “internet” e “web”. Usano il termine “internet” mentre intendono il Web, inconsapevole orribile sineddoche.

Eppure non è un concetto difficile: internet è una rete sulla quale si basa il sistema Web.

State parlando di siti? Allora “web”. State parlando di Facebook? Allora “web”. State parlando di servizi in rete in genere? (email, web, ftp)? Allora “internet”.

La colpa è anche, tremendamente, delle pubblicità fatte male e approssimative. Gli operatori telefonici ti fanno l’offerta per “email e internet” a 20€ al mese.

Mi fa rabbia, potentemente rabbia; l’ignoranza che tutto schiaccia e che non presuppone errori. Se fai notare l’errore ti prendono per scemo (“Ma tanto è uguale, ma tanto hai capito lo stesso, ma tanto… chi se ne frega”).

E no, non vale neanche il discorso “il linguaggio cambia”, perché qui si stanno confondendo termini che in ambito specifico (il mio lavoro, per esempio), hanno significati diversi e tali significati devono rimanere distinti perché stiamo parlando di COSE diverse.

Per cui, per favore, prima di dire “internet” tra un “LOL” e un “Facebook”, pensateci un momento.


Rispetto il Python, ma non lo amo

Il mio rapporto con il linguaggio Python è un matrimonio d’interesse. Lo uso perché nella mia fattispecie lavorativa credo sia la scelta più furba (più facile trovare programmatori Python che programmatori Ruby). Non lo amo, ma lo rispetto profondamente.

Tuttavia, avendo un (arrugginito) background Ruby di un certo spessore, ci sono cose che, tutte le volte che le incontro, mi fanno storcere la bocca e tappare il naso. In breve, Python mi sembra rozzo e molto più a “basso livello” di quello che si vorrebbe far credere.

Faccio un elenco brevissimo di quelle cosette che mi disturbano, per poi alla fine fare un concreto esempio. Premetto che so bene che questi non sono difetti, ma particolarità di un linguaggio che in onore della coerenza ha fatto delle scelte che, beh l’ho già detto, non mi piacciono.

  • I builtin. Mi spiace, ma non riesco a pensare al Python come un linguaggio puramente a oggetti
  • Il self come parametro esplicito
  • __init__ che è un metodo come tutti gli altri, ma anche no
  • Il fatto che esistano le classi “new style”, che inficia tra le altre cose il comportamento di super()
  • Il super(), concetto piuttosto importantino nella OO, il cui comportamento non è mica scontatissimo
  • L’ereditarietà, con effetti collaterali poco intuitivi. Vi pare elegante, poi, una cosa di questo tipo? super(AppdateHTTPRetriever, self).__init__()
  • Il modo esplicito per fare setters e getters dinamici (che dovrebbero invece essere impliciti), ovvero le property
  • Certe curiose caratteristiche dello scoping globale delle variabili
  • Il pass, che mi fa abbastanza ridere (Matz take on that)
  • la nausea da __ __ __
  • hasattr e has_key, che, oltre alla non consistenza del nome, uno è un builtin e uno è un metodo (sì, uno è per gli oggetti e uno è per i dizionari, ma allora vedi punto 1)

Ed ora un esempio.

Problema: data una directory dove risiedono dei “bot”, creare uno script che li esegua tutti uno ad uno. Ogni bot non è altro che una classe, che va dinamincamente istanziata ed eseguito il metodo “run” sulla stessa (la classe ha lo stesso nome del file Bot).

Fornisco due soluzioni, una in Python e una in Ruby. Quale vi sembra più leggibile?

Python:

# Richiede __init__.py nella directory dei bot
import glob, os
for filename in glob.glob("bots/Bot_*.py"):
  classname = modulename = os.path.splitext(os.path.split(filename)[-1])[0]
  package = filename.replace("/", ".")[:-3]
  mod = __import__(package)
  bot = mod.__dict__[modulename].__dict__[classname]()
  if hasattr(bot, "run"):
    bot.run()

Ruby:

Dir.glob('bots/Bot_*.rb').each() do | file |
  require file
  classname = file.split('/')[1].gsub('.rb','')
  bot = Object.const_get(classname).new()
  if (bot.methods.include?('run'))
    bot.run()
  end
end

Solr, Tomcat e UTF-8

Da un po’ di tempo sto sperimentando il motore di ricerca Solr e devo ammettere che le sensazioni sono (per ora) buone; ottime prestazioni, interfaccia HTTP, tonnellate di opzioni, faccette, boost dei risultati a query time, stemmer italiano, supporto Unicode nativo, eccetera.

Appena lo scarichi Solr è praticamente già pronto all’uso; è una webapp Java e insieme alla distribuzione ti viene dato anche Jetty giusto per poter scrivere “start.sh” ed essere online (beh, quasi…).

Quando le cose si fanno serie (leggi: andare in produzione), è sicuramente meglio passare a Tomcat.

Per farla breve (tornerò sull’argomento quando parlerò dell’integrazione tra Solr e Drupal che sto seguendo), oggi mi sono accorto che fallivano miseramente tutte le ricerche che contenevano caratteri àccèntàtì. Quando succede una cosa del genere, ogni programmatore italiano alza gli occhi al cielo e sospira (e/o dice cose non ripetibili in questa sede).

Scopro finalmente che il problema non è di Solr. Si verifica perchè le query in forma di URI che vengono mandate a Solr, non sono codificate UTF-8. Il simpaticone di Tomcat, di default, non codifica UTF-8 le URI.

E’ stato sufficiente aprire il server.xml di Tomcat e aggiungere al connettore principale l’attributo URIEncoding=”UTF-8″ così che il connector apparirà così:

<Connector port="8080" URIEncoding="UTF-8" protocol="HTTP/1.1"
                connectionTimeout="20000"
                redirectPort="8443" />

Fatto poi ripartire Tomcat è andato tutto a posto.


Drupal 7, velocissima preview via CVS

Sebbene si dica che Drupal 7 non sarà stabile prima dell’autunno di quest’anno, si può comunque andarselo  a prendere per farci un giretto. Prendersi il pacchetto DEV è abbastanza inutile, visto che lo cambiano quasi giornalmente. Molto più interessante è prendersi direttamente il branch CVS e poi magari tenerselo aggiornato. Ecco come fare.

Drupal, come tutti i progetti grossotti, fa esteso uso del tagging nel suo repository. Tutto sta dunque a capire quale sia il “tag” corrispondente alla versione 7 di Drupal. In questo caso è molto semplice, visto che il tag è HEAD (ovvero il branch di sviluppo). Fare il checkout con CVS è questione di eseguire il seguente comando nella directory dove si vuole venga creata la sottodirectory con drupal stesso (per esempio, public_html)

cvs -z6 -d:pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal checkout -r HEAD drupal

Pochi secondi dopo avrete il vostro Drupal 7 nella directory “drupal”. Successivamente, per vedere se ci sono aggiornamenti, sarà sufficiente entrare in quella directory ed eseguire

cvs up

Sarà opportuno eseguire, subito dopo il cvs up, anche un update.php per aggiornare eventualmente tabelle del database.

Gli step di installazione sono gli stessi di Drupal 6; dunque occorre:

  • creare un database (Drupal 7 supporta out of the box anche sqlite, volendo)
  • copiare sites/all/default.settings.php in sites/all/settings.php e dargli provvisoriamente un bel chmod 666 per fare in modo che l’installer lo possa aggiornare
  • andare con un browser sul nuovo sito

Vi verrà chiesto in che lingua installare e, successivamente, quale profilo. Anche questa seconda opzione è una novità: avrete la possibilità di scegliere un profilo “standard”, ovvero molto scarno, oppure un profilo un pochino più avanzato nel quale, per esempio, viene creato automenticamente il vocabolario “Tags” associato ai due tipi di documento di default.

Girovagando tra le opzioni, non mi è sembrato di vedere nessuna grossa novità. Mi è saltata all’occhio soltanto l’aggiunta di una descrizione ai permessi. Hanno anche rinominato “Story” in “Article”.

Naturalmente non andate a cercare, per ora, la traduzione italiana.


Piccoli incubi MySQL

Stamani arrivo in ufficio e mi dicono che il database è “impazzito”.

Trovo le solite due o tre tabelle crashate, le riparo e il sistema torna a pieno regime; soltanto per fermarsi poco dopo per un altro problema.

Una tabella di log che normalmente è tenuta “a bada” da uno script di cron è arrivata a 14 milioni di righe. Niente di spaventoso, ma so già quello che mi aspetta.

Non la posso troncare, e una DELETE su una tabella del genere è la morte di qualsiasi database [segue aneddoto]. Mi faccio coraggio e lancio dunque la delete dopo aver disabilitato le scritture su quella tabellaccia.

Quarantacinque minuti dopo, terminata l’operazione, la tabella conta 5000 righe.

Tutto a posto, dunque? Manco per niente.

Riattivo il sistema e noto che le JOIN con quella tabella continuano a bloccare il sito. Allora mi ricordo che dopo una cancellazione così pesante è sempre bene eseguire anche una ANALYZE TABLE.

15 minuti dopo (su una tabella di 5000 righe?) i problemi persistono. OK, allora facciamo anche una REPAIR TABLE. Altri 15 minuti dopo, finalmente, il sistema è tornato nominal.

Aneddoto: qualche anno fa lavoravo su un database SQL Server. Era un venerdì sera (circa le 18), e non ricordo perché decido di fare un po’ di pulizia su una tabella con diversi milioni di righe (in produzione, che idiota). Dopo un paio d’ore di esecuzione, decido che la faccenda si sta facendo ridicola e voglio spostare il problema al lunedì. Dunque fermo la DELETE, ma non mi rendo conto che quella DELETE era sotto transazione. Risultato? Altre tre ore di ROLLBACK, e un venerdì buttato via.


I contenuti di questo sito sono distribuiti con una licenza Creative Commons 2.5 eccetto dove diversamente specificato.

Tema WordPress Punto5 sviluppato da Claudio Cicali; icone del set famfamfam silk e komodomedia.

© 2005-2010
Claudio Cicali