2007-07-08

En que gasto mi tiempo últimamente: Moodle, LDAP, PHP y C.

Aviso: esta entrada contiene jerga tecnológica a raudales y es uno de esos artículos que suele escribir la gente que usa pantalla negra y escribe palabras ininteligibles para el común de los mortales. Así que si el cuerpo te pide otras cosas, te puedes saltar el resto del artículo :-)

La última semana he dedicado una buena cantidad de horas de mi tiempo libre a programar. Y a programar en C. Hacía tiempo ya desde la última vez, casi dos años, y para intentar hacer más o menos lo mismo que esta vez, sólo que la cosa no llego a buen puerto. En los últimos años he dedicado una parte de mi jornada laboral a la administración de los sistemas y las comunicaciones de la Facultad de Empresariales de Mondragon Unibertsitatea, con lo cual la programación que hacía era básicamente de scripts para automatizar tareas (en lenguajes de scripting varios) y bastante PHP para retocar o desarrollar aplicaciones Web.

Vamos, pequeñas minucias cuando hablamos de programar. De vez en cuando me da la fiebre de la programación y durante unas semanas me centro en algún problema que me interesa (siempre dentro del ámbito del software libre) y dedico unas cuantas horas a tratar de resolverlo. Y como en los últimos 2 dos años he entrado a tope en el proyecto Moodle y hay un problemilla que afecta a quienes lo usan en entornos de muchos usuarios cuando utilizan validación de usuarios con un directorio LDAP, ahí he estado pasando unas cuantas horas (intempestivas).

La cosa empezo hace casi dos años (septiembre de 2005) cuando pusimos en producción la instalación de Moodle de la Facultad de Empresariales. Se decidió que los usuarios serían los mismos que los del Directorio Activo de Windows, así que tuve que ponerme las pilas en el tema de LDAP y todos sus entresijos. Y una de las cosas que descubrí en los foros de Moodle, porque alguien lo sufrió en sus propias carnes, es que hay algunos límites impuestos en el servidor que hacen que no se puedan recuperar más de N resultados en una consulta, aunque en realidad haya más de esa cantidad. Hay razones de peso para que sea así, por ejemplo que no dejemos sin recursos de memoria al servidor si lanzamos varias consultas simultáneas que tengan que devolver miles de resultados.

No es que nosotros tuviésemos ese problema (por la forma en que configuramos nuestra instalación no se daba ese tipo de consultas), pero me picó la curiosidad y empecé a investigar el tema. Y así me sumergí en las procelosas aguas del protocolo LDAP y sus entresijos. Y acabé llegando a una extensión opcional del protocolo que permite paginar los resultados, es decir, pedir que los envíe en lotes de un cierto tamaño (definible por quien hace la consulta) y te los vaya pasando de lote en lote, lo cual evita la situación potencialmente desastrosa mencionada arriba.

Claro, que las cosas no son nunca tan sencillas. Moodle está desarrollado en PHP, y para utilizar el protocolo LDAP hace uso de una extensión desarrollada por los propios creadores de PHP que permite tender un puente entre PHP y las bibliotecas que incorporan la funcionalidad del protocolo LDAP. Y la extensión en cuestión está escrita en C. Así que el siguiente paso era bucear en las entrañas de la extensión LDAP. Un poquito de C, un poquito de API de Zend para el desarrollo de extensiones de PHP, un poquito de API de LDAP para lenguaje C, ... Vamos, unas cuantas horas de diversión asegurada para los tipos de las pantallas negras y palabras ininteligible :-)

El resultado tras un par de semanas de búsqueda de información, estudio del código de la extensión LDAP, el API de Zend y demás parafernalia es un parche bastante primitivo, pero funcional, que incorporaba la funcionalidad de paginación al módulo estándar de LDAP para PHP. Un par de discusiones y un mes después, un parche como Tux manda que permitía usar la funcionalidad con comodidad y garantías. Envié el parche a las listas de desarrollo de PHP y al encargado de mantenimiento del módulo de LDAP para ver si lo podían incorporar, pero no hubo suerte.

Así que durmió el sueño de los justos durante unos cuantos meses hasta que decidí volver a intentar que lo incorporaran. Unos cuantos intercambios de email con uno de los desarrolladores de PHP para añadirle una serie de pruebas unitarias, y volvimos a la situación de partida: se siguió quedando guardado en el armario. Hace unos pocos meses lo intenté de nuevo, con idéntico resultado.

Y hace unas tres semanas me volvió a dar la fiebre. Y he vuelto a la carga. Y para darles más razones para que lo incorporen, me he liado la manta a la cabeza y he cogido un parche algo más completo que el mío, desarrollado por Pierangelo Masarati (desarrollador de OpenLDAP, lo que le da más empaque al parche) y que andaba dando tumbos por ahí más o menos desde las mismas fechas que mi parche original. Le he dado un lavado de cara, lo he actualizado para que se aplique limpiamente a la versión actual estable de PHP, le he corregido una fuga de memoria que tenía, le he añadido las pruebas unitarias de rigor y lo he enviado a la lista de nuevo.

Ha sido más fácil de lo que esperaba, pero me ha costado más tiempo de lo previsto. Todo compilaba bien, se lanzaba sin problemas y de repente ¡zas! el programa se moría con un bonito error: "Segmentation fault. Core dumped", que traducido al castizo vendría a ser: "me he dado una castaña como un piano y hasta aquí hemos llegado". Así que me dije: nada, esto lo arreglo yo en un periquete con mi debugger preferido. Y allá fui tan ufano. Y después de varias dos horas aquello seguía igual, y encima el programa se estaba muriendo en una función interna dentro de la biblitoteca, cuatro niveles de profundidad más abajo de la función a la que yo estaba llamando. De locos.

Y todo por una de esas cosas que nunca te esperas, pero que cuando todo falla y después de pegarte con el debugger un rato y no ver nada mal, es de lo primero que sospechas (sobre todo si ya te ha mordido el trasero alguna otra vez en el pasado): tienes varias versiones de la biblioteca de funciones que necesitas y estás usando la única que no te sirve (el linker, que es un tío muy simpático, ha decidido usar justo esa versión, en lugar de la que tu quieres). Claro que de eso te das cuenta a las tantas de la madrugada. O al menos así es en mi caso, ya que son un programador mayormente noctámbulo :-)

Pero bueno, la cosa ya está en marcha, funcionando 100%, testeada con al menos dos implementaciones de directorio LDAP diferentes, y enviada a las listas de desarrollo de PHP y al mantenedor de la extensión LDAP. Aunque 24 horas depués aún no han dicho nada, lo cual no es muy buena señal en este caso, ya que la lista es muy dinámica y los tiempos de respuesta, aunque sea para decirte que tu código es una porquería (que si lo es, te lo dicen sin ningún reparo :-), suelen ser cortos.

Así que ya veremos como se desarrollan los acontecimientos. Por si acaso, no voy a contener la respiración mientras espero.

¡Ah, sí! Se me olvidaba. Por si alguno está interesado o necesita la extensión se puede descargar en http://www.eteo.mondragon.edu/descargas/php-ldap/

Saludos. Iñaki.