Small talk about my experience with MongoDB

I’m interrupting the series of Ruby rants (somewhat) to talk about something that is slightly related but not too much. I’ve already written about my plan of writing a system to index and manage the boxes that I manage at various customers’ places. This system is half written for me to have something neater than GIT and HTML to manage the data, and half to get up-to-date with modern Rails development.

One of the decisions I made was to try for once a NoSQL approach. I had many questions on why I did it that way and the answer was for me pretty simple actually: I didn’t want to spend time in designing the relationships first and write the code later. The nice part about using MongoDB was that I’m able to add and remove attributes when I like, and still query for them without fetching huge amount of data to process Ruby-side.

Honestly, after seeing the kind of queries that Rails concocts to get me data that is normalised, but requires multiple many-to-many relationships to be resolved, I’m quite sure that it can’t be worse with MongoDB than it is with PostgreSQL, for this kind of data.

Of course it’s not all positive sides with MongoDB; beside the obnoxious requirement of a JavaScript engine (and there aren’t many), which is linked to the use of v8 (which is not ABI-stable, and thus each update is a rebuild and restart), I had some bad experience yesterday, but not something extreme, luckily. On the one server I use MongoDB on, I recently configured the locale settings in the environment — but I forgot to re-execute locale-gen so the locale was broken; as it turns out, Boost throws an exception in that case, and MongoDB does not try to manage it, aborting instead.

I guess the main blame here is on the init script that does not report an execution failure: the service is noted as started, and then crashed, which is technically correct, but not what you expect the init script to tell you. I guess if I have more time I should try to get more Unix-style daemon support to mongod so that it can be integrated better with our start-stop-daemon rather than left with the hacky script that it’s using now.

Add to that missing support for using the syslog protocol and you can probably figure out that the thing that worries me the most about MongoDB is the usual sense of “let’s ignore every previous convention” which seems to come with NoSQL projects. Luckily at least this project feels like technically, rather than politically, driven, which means I should be able to get them to at least partially implement those features that would make it a “good citizen” in an Unix environment.

Sigh, I really wish I had a bit more time to hack at it, since I know the few rough spots I found should be easily polished with a week or so of work; unfortunately I guess that’ll have to wait. Maybe after my coming US trip I’ll be able to take a couple of weeks to dedicate to myself rather than customers.

Extending libdaemon

As Luca wrote, since I came home from the hospital I’ve been working quite a bit on LScube, in particular working on porting feng to use glib, which is a very interesting thing considering that it also allowed to reduce the dependencies (no more need for libgcrypt for instance, which was a problem to me since it didn’t use pkg-config and I find that a bit medieval nowadays).

One other thing that feng lacked was support for running as a daemon; as git-daemon shown recently, having proper support is much better than faking it through start-stop-daemon.

A proper support for running as a Unix daemon mean quite a few different things: proper logging to either stdout/stderr (when not running as daemon) or syslog (when running as daemon); pid file generation (a file, usually in /var/run, where the process ID of the running daemon is written); proper check for forking (so that the user is told if the daemon failed to start; check for if the daemon is running already if trying to execute it again on the same pid file (multiple instances, where allowed, should use multiple pid files); privilege dropping (you don’t want your daemons to run with root privileges, although the ones who provide network service might need those privileges at once to open privileged ports (below the 1024 boundary).

Implementing all these things can easily be a boring task considering that is almost the same for each daemon you might be writing (feng is not the only daemon in lscube). Luckily, someone already thought about this and started working on a solution: Lennart’s libdaemon, which he used for the Avahi daemon.

But as it happens, although libdaemon 0.12 (which is not even the latest version) already provides enough of the basics needed for feng, there are a few things that would require further wrapping around in the code of feng itself. This includes verbosity handling (you might not want to have information output on stdout/stderr; while with syslog you can easily configure your logging to reduce the output, on stdout/stderr you either implement verbosity or you get everything that is logged through the daemon_log() function), and privileges dropping.

The nice thing of working with good maintainers, though, is that they are open to suggestions and extensions, so thanks to Lennart availability, I started implementing those parts that I was lacking. Hopefully in a not-so-long time, there will be a new libdaemon release, which feng will use, that will provide all the needed functionalities.

I really like this approach since it allows to do the things right once and for all, upstream, without having to reinvent the wheel every time, especially considering that it’s not rare that, trying to reinvent the wheel, you get it -octarine- octagonal rather than round.

For those who would like to take a look at the work in progress of my extensions, you can find them on my git repository together with some autotools fixes and some patches for OpenSolaris compatibility.

What about those .la files?

The other day I was trying to compile Amarok with the 32-bit compiler, as the Helix engine fails to build with GCC 4.3, and I dislike fixing stuff blindly. The problem with doing this from a 64-bit multilib setup is libtool.

When you do link with libtool to a given library with -lfoo and that library was built and installed with libtool, it will look up the libfoo.la file, and then use that to replace -lfoo option with the path to the library file. The problem is that libtool does not know about the arch the library was built for, and it uses an absolute path. So in most cases your -lfoo will be replaced, on an amd64 multilib system, with /usr/lib64/libfoo.so. Nothing bad unless you’re building a 32-bit ELF file, which will then fail.

But what are .la files used for, nowadays? This is a good question, and one that I’m sure most users and most developers don’t have a full answer for. And are these actually needed? The following two lines you can find in all .la files would suggest so, but I have a different answer.

# Please DO NOT delete this file!
# It is necessary for linking the library.

Let’s start with saying what libtool is/was designed for. Building shared libraries on Unix wasn’t always possible, older Unixes don’t support them, and almost every Unix version has its own way to handle shared libraries. While on today’s Unixes you mostly can just use the -shared option to gcc, this wasn’t always true, and still there are differences in naming scheme for instance between Linux and *BSD and Apple’s Mac OS X (which, even though people try to deny that, is Unix). libtool abstract all these issues.

Unfortunately, libtool is a hugely complex piece of code, and most people using it have no idea how it is supposed to work. The code also takes care of such old and nowadays mostly unused cases that proably a lot of people even knowing how it works wouldn’t know why it is done that way.

One thing libtool has to workaround is the fact that static libraries are just archives, and contain no metadata with respect to linking other libraries together with them (their dependencies). This is what .la archives are used. Unfortunately libtool can’t understand that if you’re not linking static archives you don’t need to provide the dependencies, at least on ELF-based systems, and that causes one of the problems you can get rid of with --as-needed (overlinking).

But .la files are nowadays mostly used by programs using libltdl for plugins loading (like PulseAudio). This is used again to abstract differences between the dynamic loader of different operating systems, like Unix and Windows for instance. This introduces quite some redundancy on Linux and modern *BSD, but it usually doesn’t create as many problems as .la files for shared libraries.

So do we need the .la files to link to the libraries or not? The answer is “not always”. If the library only installs a shared copy of itself, the .la file is unneeded on modern Linux and *BSD systems, if the library also installs a static copy, it might be needed for static linking to work properly, as the library can have extra dependencies.

In a perfect world, every static library needing dependencies would have its own .pc file for pkg-config, and every package trying to statically link to that library would be using pkg-config --static to get the libraries to link to. Unfortunately we’re not in a perfect world.

It would be nice if somebody had enough time to spend to try removing all the *.la files for shared libraries (not for plugins!) on his system, and see what does fail to link statically. I might consider spending some time on that as it would be a really nice improvement, and a good step forward to have one day proper multilib support, but it will have to wait for now. If any user also consider this a nice thing to do, please let me know, if I do see interest in it I’ll try to get more time on that.

Benvenuti nel 21mo secolo. X non morde.

Una breve panoramica semiseria di quegli aspetti che molti considerano «indispensabili» ad un vero «Unix H4x0r» ma che in realtà servono solo a far perdere tempo.

Mi capita spesso di rispondere, in IRC, via e-mail o di persona a chi mi chiede di risolvere problemi che sono facilmente risolvibili cambiando la propria linea di pensiero in una più moderna e meno «rinchiusa» dentro schemi classici, eppure queste persone non ne sono intenzionate.

Solitamente si tratta di utenti unices – Con «unices» voglio intendere tutti i dialetti Unix e Unix-like che sono disponibili attualmente, quindi Linux, *BSD, Darwin, Solaris… Unices è considerato il plurale di Unix per la maggior parte delle persone – che vogliono farsi vedere esperti agli occhi di utenti Windows.

Voglio tentare di smitizzare alcuni concetti che a volte sono radicati ad un punto tale da esser disposti a perdere più tempo per risolvere problemi futili che per fare qualcosa di buono davvero.

X non morde

Come già si vede dal sottotitolo che ho dato a questo articolo, il primo mito che voglio far cedere è quello che «il vero utente unices» non usa ambienti grafici.

Per quanto sia indiscutibilmente vero che X sia ormai un ambiente grafico assolutamente superato, in cui ogni supporto per concetti recenti come la ruota del mouse, la trasparenza delle finestre, le ombreggiature… viene reso tramite un’estensione aggiuntiva che appesantisce il sistema, non bisogna per forza starne alla larga. Specialmente, non è necessario starne alla larga a favore della console testuale.

A volte mi capita di parlare con persone che dicono che usare l’interfaccia grafica è da utonti. In realtà un’interfaccia grafica ben strutturata e bene organizzata è molto più comoda e più efficiente di una console testuale usata nel modo sbagliato. Per quanto ci siano logicamente delle cose che sono più semplici da fare in una console testuale, nessuna regola impone di utilizzare la console testuale per cose come ascoltare musica, guardare film, leggere la posta e navigare (quando se ne ha la possibilità, logicamente).

Cose come aalib – Libreria per il rendering grafico in ASCII art – e libcaca – Libreria per il rendering grafico a colori in ASCII art – sono esperimenti interessanti, ma la loro effettiva utilità è veramente bassa. Non credo ci sia veramente qualcuno che è interessato a guardarsi un film in ASCII art, tolta di mezzo la curiosità (in effetti ho provato una volta aatv, sotto debian dove veniva installato per forza di cose e avevo bruciato X, ma non è possibile riuscire a distinguere il video più che con una tv con un effetto neve molto pronunciato, quindi è pressoché inutile).

Le icone non fan venire le verruche

Al tempo stesso molta gente è convinta che se proprio si deve utilizzare un’interfaccia grafica, le icone sono il male assoluto, principalmente per il solo e unico motivo che Microsoft Windows è un sistema operativo ad icone.

Questo è un problema in realtà sottostimato, più grave di quello che appare. Molta gente è convintissima che l’idea stessa che sta dietro a Windows sia sbagliata. In realtà, per quanto la sua realizzazione tecnica lasci a desiderare, molti concetti che stanno dietro alla progettazione di Windows non sono del tutto errati. L’interfaccia grafica ad icone, che viene utilizzaa da Windows e MacOS, è stata ottimizzata e migliorata negli anni, fino a diventare un qualcosa di difficilmente sostituibile per l’utente medio, e di questo non si può fare una colpa a nessuno. Si tratta di un buon modo di gestire le cose in fondo, visto che funziona sicuramente meglio dei sistemi a schede perforate degli anni ‘60.

Riprenderò il discorso che riguarda direttamente Windows (e Mac) più avanti, nel frattempo vorrei aggiungere a riguardo delle icone, che anche le icone e i temi visivi in generale (sfondi, stili dei widget e via dicendo) possono aiutare nel lavoro, permettendo alle persone di rilassarsi, trovandosi di fronte un ambiente amichevole invece di una scarna console testuale.

Chiamarle cartelle non è reato

Per quanto io stesso sia abituato a chiamarle directories, chiamarle cartelle non è reato statale. Inoltre, se vogliamo scendere nei tecnicismi, se il termine directory è perfetto per indicare la singola struttura del filesystem, in molti ambienti grafici (perlomeno KDE e Gnome), e in taluni sistemi operativi (MacOSX e Windows), alle directory può essere associato un file contenente informazioni aggiuntive (metadata), che possono descrivere l’icona da utilizzare per rappresentare tale directory, informazioni su come visualizzarla nel navigatore …. In questo caso, la coppia di directory e file può benissimo chiamarsi cartella (folder).

Usare il mouse non fa venire l’artrite

Questa considerazione mi viene spontanea da fare dopo aver letto un vecchio thread sulla mailing list di KDE. C’era chi affermava che i veri «esperti» non usano mai il mouse per cancellare i file. In realtà, non è sempre così. Mi capita spesso di navigare sul disco semplicemente per guardare cosa ho dentro, e quindi mi risulta più comodo muovermi col mouse che con la tastiera. Quindi mi seccherebbe dover ogni volta che voglio cancellare qualcosa (non buttarla nel cestino), andare ad utilizzare la tastiera. Quindi non sottovalutate mai la possibilità di fare certe cose col mouse, è comodo, quando si ha fatto pratica.

Usare il cestino non fa rincretinire

Una delle novità più interessanti che sono uscite da FreeDesktop.org è la specifica per il supporto dei «cestini» (trashcan). Se prima era già disponibile una specie di cestino, all’interno della cartella home, era abbastanza inutilizzabile quando le homes fossero su una partizione diversa da dati che vengono spesso cancellati e creati, perché avrebbe richiesto molto più di una semplice modifica ai valori di posizione di un file: un vero e proprio trasferimento dei dati da una partizione all’altra (o addirittura da un disco all’altro), creando un rallentamento dell’operazione di cancellazione veramente ampio, inoltre, si sarebbe andati ad occupare spazio in una partizione che potrebbe essere, per esempio, limitata nelle dimensioni o nello spazio utilizzabile (cosa non rara per esempio nelle Università dove c’è a disposizione un’area scratch nel disco locale del computer con una quota molto più ampia di quella nelle home su NFS).

Per risolvere questo problema, la nuova specifica permette di utilizzare delle cartelle trash in ogni partizione, risolvendo i problemi della necessità di trasferimento e di occupazione dello spazio. Inoltre permette il salvataggio della posizione in cui un determinato file si trovava in precedenza, correggendo un altro grave difetto della precedente implementazione: l’impossibilità di recuperare un file direttamente.

Molti «esperti» potrebbero storcere il naso a riguardo di tale nuova funzione, pensando che sia solo un qualcosa utile per gli utonti. Al contrario, una funzione simile può venire molto utile specie quando si sta tentando di fare pulizia nel proprio disco, per evitare di cancellare dati importanti per una lieve distrazione.

Per coloro che ancora fossero pronti a storcere il naso ad una cosa «alla Windows» consiglio la lettura della sezione «Windows forse è il demonio, ma non le sue idee» più avanti.

Fare le cose da sé non sempre fa guadagnar tempo

Ci sono ancora quantità enormi di persone che utilizzano distribuzioni come, per esempio, Slackware, convinte che l’unico modo di essere veri «utenti esperti» sia imparare a far le cose completamente da soli. In realtà l’uso di Slackware come di ogni altra distribuzione o sistema operativo che non prevede alcuna gstione delle dipendenze, può diventare un vero problema, specie per workstation e computer quotidiani di tutti i giorni.

Rendiamoci conto che è inutile accendere un computer soltanto per passare tre ore a tentare di far funzionare una cosa da soli, come per esempio per sistemare una dipendenza di un pacchetto che non è più soddisfatta, quando ci sono distribuzioni come Gentoo, Debian, Fedora Core, Mandrake che gestiscono le dipendenze in modo automatico o semi automatico.

Chi non volesse la «pappa pronta» delle distribuzioni deb- o rpm-based, può benissimo scegliere una distribuzione come Gentoo che, per quanto lunga da installare, è automatizzata nella gestione degli aggiornamenti e delle dipendenze.
Per esempio passo spesso molto tempo a compilare, ma nel frattempo ho la possibilità di fare molte altre cose, compilo mentre sto chattando su IRC, compilo mentre guardo un DVD, compilo mentre guardo la TV. Non ho bisogno di passare le tre ore che il sistema mette a compilare guardando quello che fa e seguendo passo passo i problemi. Se vi intricate nei labirinti delle dipendenze dei sistemi operativi fai-da-te non è molto semplice venirne fuori senza perderci tempo e attenzione sopra.

Se ci possono essere ambienti unificati in cui una cosa del genere può essere utile, non credo proprio che una distribuzione come Slackware, nel ventunesimo secolo, sia adatta all’uso quotidiano.

Una delle repliche che mi viene fatta rispetto a questo mio pensiero è una citazione di Volkerding:

Besides, I think Slackware sounds better than 'Microsoft,' don't you?

Sicuramente Volkerding ha ragione da questo punto di vista, ma trovo, con molta sincerità, che quando si fa il salto di qualità, è inutile tenersi indietro e fare un salto minimo (di qualità, per quanto di comportamento, Windows e Slackware siano agli estremi opposti). Inoltre, non è raro che utenti Slackware cerchino aiuto per cose che in altre distribuzioni sono banali (problemi di compatibilità binaria sotto Debian non esistono, sotto Gentoo si possono risolvere utilizzando revdep-rebuild, che li risolve automaticamente, giusto per fare un esempio). Inoltre quando si tratta di persone che hanno effettivamente delle capacità che potrebbero essere impiegate per l’avanzamento del software libero, occupare il loro tempo per tentare di sistemare una macchina da soli, «da veri sysadmin», è uno spreco di energie che potrebbero essere meglio impiegate.

Programmare senza usare un editor non rafforza i vasi sanguigni

Un altro esempio che può essere portato, è la quantità di persone che pensano che programmare senza far uso di librerie di comodo, senza far uso di ambienti di sviluppo integrati (IDE), senza far uso di strumenti per la progettazione (CASE), e via dicendo sia l’unico vero modo di programmare.

In realtà l’uso di strumenti automatizzati per lo sviluppo di applicazioni può far sprecare molto meno tempo, che può essere utilizzato in maniere migliori.

Testi come «Il vero programmatore» sono divertenti, e di sicuro chi è capace di fare cose simili è bravo, ma questo non significa che sia il miglior modo di farle a questo mondo. C’è chi riesce a guidare a 300Km/h senza fare incidenti, bravissimo, ma questo non significa che debba farlo sulle strade urbane.

Windows forse è il demonio, ma non le sue idee

Come ho già accennato sopra, per quanto possa non piacere Windows, questo non significa che bisogna per forza di cose stare lontani da qualsiasi cosa che gli assomigli.

Nella realtà la maggior parte dei concetti e delle idee che stanno dietro a Widnows non sono il male in sé, e anzi sono ben pensati e ben strutturati. Tra l’altro molte cose che si reputano «di Windows» sono piuttosto prese prima da MacOS.

Idee come gli ActiveX, ripresi come dicevo dai KPart di KDE, le icone nella systray “nascondibili”, il cestino, l’automounting/umounting delle periferiche, il riconoscimento automatico dell’hardware, il browser integrato con il file manager, e altre idee simili sono state o stanno venendo ben integrate all’interno dei maggiori ambienti grafici e distribuzioni, e il loro supporto rende molto più semplice la gestione del sistema.

Anche il concetto di librerie dinamiche, che in Windows sono chiamate DLL, viene applicato sotto gli unices, anche se con estensioni diverse (abbiamo i .so di Linux e BSD e i .dylib di Darwin per esempio). Anche se qui è più Windows che riprende un’idea degli unices.

Allo stesso tempo, ci sono altre cose, come i programmi usati più recentemente (presenti in MacOS, KDE e solo per ultimo Windows XP), l’aggregazione delle entry nella barra delle applicazioni (presenti in KDE e GNOME e solo dopo in Windows XP), il blocco dei popup nel browser (presente in Mozilla prima che in IE), il tab-completition presente in quasi tutte le shell unices classiche e solo dopo su Windows XP, che la casa di Redmond ha usato dopo gli unices. Si tratta dell’ovvio scambio di ideee che c’è tra prodotti simili, siano essi liberi o meno (che viene ostacolato in questo caso non dalle leggi sul diritto d’autore, che non impediscono di sfruttare la stessa idea implementandola con codice differente, ma da quelle sui brevetti, quindi si potrebbe far notare a Microsoft che se anche il mondo libero avesse brevettato alcune cose, neanche loro potrebbero utilizzarle).

Per chi critica queste aggiunte alla stregua di bloat che non fanno altro che aggiungere codice senza aggiungere motivazioni, vorrei ricordare che la prima caratteristica degli unices è la modularità: è possibile creare un sistema disabilitando tutte queste funzionalità aggiuntive, in modo che resti funzionante su sistemi ormai vecchi ed obsoleti. In relazione a questo, anche moltissime funzionalità eye-candy, ovvero relative specificatamente alla «bellezza grafica» degli ambienti, possono essere tranquillamente rimosse, disabilitate o trascurate.

Postfazione

Questo articolo è sicuramente meno tecnico di tutti gli altri che ho scritto fin ora, e anche molto più «stringato», ma, come dicevo, voleva essere un testo semiserio. In verità penso che ognuno sia libero di decidere come vuole lavorare, questo testo vuole solo far notare come certe pratiche non siano da considerarsi da «veri h4x0r» e altre da «niubbi» ma semplicemente come diversi stili d’uso che hanno ognuno i suoi pro e i suoi contro.

L’unico consiglio che mi sento di dare, è di considerare quello che si sta facendo, se si passa più tempo a risolvere problemi banali che a fare qualcosa di utile, e di considerare l’idea di smettere di far le cose in modo arcaico, avendo più tempo a disposizione per aiutare il software libero.

Un’altra nota a margine di tutto questo che vorrei lasciare è rivolta a tutti gli utenti di queste pratiche a mio avviso astruse: se vi sentite in grado di fare queste cose perché siete «veri h4x0r», forse vi conviene non chiedere ogni 20 minuti aiuto perché c’è una cosa che è banalissima da fare per un utente normale, ma voi non riuscite a farla nel vostro modo di lavorare. Se lo sapete fare bene, altrimenti considerate l’idea di cambiare linea di pensiero.