Primero tengo que aclarar que Faxinating.com está apoyado sobre varios proyectos de software libre. Esto no es ninguna novedad, pero merece una mención.
Como servidor web utilizamos Apache, como base de datos MySQL, y como lenguaje de programación utilizamos PHP y Perl. Se hizo de esta forma porque ya teníamos desarrollado el CMS en PHP, se llama ENSPEZI, será libre (aún no he publicado el código, pero lo haré). La ventaja del CMS es que es muy ligero, hace lo mínimo e indispensable y con soporte multi-idioma de forma nativa. Desarrollamos algunos plugins para manejar la cola de pedidos, las pasarelas de pago, etc..
El funcionamiento de la parte web es como cualquier otra web, no tiene casi nada de especial. Inicia sesión, sube ficheros, guarda el número de teléfono. La parte interesante fue el calculo de precio basado en el número de destino y el precio que debemos pagar por minuto a nuestros proveedores. La idea es que el usuario pague lo mínimo posible.
Comentaré cada problema que veía antes de empezar con este proyecto y el software que utilicé para solucionarlo.
Convertir documentos en diferentes formatos
Esta tarea consume mucha CPU y en según que casos mucha RAM. Son recursos que se requieren de forma puntual (solo para convertir los documentos, el resto de la web es ligera) y se debe resolver lo más rápido posible. Con este escenario no era muy buena idea intentar convertir los documentos en el mismos servidor web, podían pasar dos cosas:
- Si el proceso tardaba demasiado podía dar un timeout por parte del navegador o los routers que se encuentre en el camino.
- El servidor web podría quedar colapsado, entorpeciendo la navegación de otros usuarios.
El proyecto tenía que ser eficiente en todo sentido, técnico y económico. Contratar un servidor muy potente para no colapsar en los picos de trabajo no era una opción.
Las necesidades son:
- Que sea económico. No requerir potentes servidores.
- Que se comunique con la web de forma asíncrona.
La respuesta es “Cloud Computing”, nada nuevo, muy de moda. No voy a extenderme en la explicación sobre la instalación de los servidores de AWS porque está muy bien explicado por Ricardo Galli, de hecho, yo monté todo leyendo ese documento y los manuales de Amazon. Hice algo parecido pero solo para el worker que convierte los documentos.
Desarrolle un worker en Perl que procesa los documentos. Los convierte en formato fax y genera un thumbnail en JPG para que el usuario pueda ver sus documentos antes de enviar los mismos. Este worker trabaja con el gestor de colas Gearman (en su web hay más información sobre que hace y como lo hace). Es realmente ligero y rápido, da la sensación de que envías las peticiones al worker, sin intermediarios. Se puede añadir tantos workers como haga falta.
Esto se hizo en Perl porque llevo muchos años programando en este lenguaje, como tenía muy poco tiempo opte por el lenguaje en el que puedo programar mejor y más rápido. Si hubiera tenido tiempo lo habría hecho con Python, tengo una espina con este lenguaje.. hace tiempo quiero hacer algo con el pero no he tenido el tiempo necesario.
Para convertir los documentos utilizo LibreOffice, ImageMagick y ghostscript. Con este software puedo procesar muchos formatos, desde txt pasando por doc, pdf hasta un jpg.
Enviar los fax
Este proceso también podía dar los mismos problemas que la conversión de documentos, se realiza de forma asíncrona. Una llamada con varías páginas puede durar 30 minutos. Es un timeout asegurado si se realiza en el servidor web. Y también se resuelve con workers escritos en Perl que gestionan los modems con los que se realizan las llamadas. Sin embargo el consumo de CPU muy bajo, con un solo equipo se puede realizar cientos de llamadas simultaneas. Esta parte del proyecto ya no está en cloud porque ya va bien de recursos. En caso de que tuviera un éxito enorme, tampoco abría problema. Gearman iría encolando un envío tras otro y se realizaría uno tras otro hasta terminar con la cola. Los equipos no sufrirían y la comunicación sería estable.
Comunicación de la web con los Workers
Esta parte es muy simple. Con unas pocas lineas de PHP se realizan llamadas por HTTP hacia el servidor de gearman. No tuve que instalar módulos especiales para PHP ni nada parecido. Con curl tal como se haría para acceder a cualquier recurso HTTP.
El único detalle es que envío la cabecera “X-Gearman-Background: true” lo que permite enviar el trabajo y cerrar la conexión. Cuando el Worker termina el proceso se lo comunica por HTTP al servidor web. Esta llamada es recogida por uno de los plugins de ENSPEZI y guarda el cambio de estado en la base de datos.
Esto es toda la “vista área” de faxinating.com. Espero que sea de utilidad.