Acabo de leer el último artículo de Joel Spolsky (debo confesar que soy un fiel seguidor de su web desde hace años).

Aunque no viene demasiado al caso, al final del artículo comenta los problemas de soporte que debe afrontar debido a que su software se ejecuta en distintas plataformas. Y claro, cada plataforma tiene sus programas, y a veces, surgen incompatibilidades entre estos y su software.

Según comenta, los servidores en Windows no suelen dar demasiados problemas, todo el mundo tiene configuraciones de equipos similares, los dolores de cabeza vienen por los sistemas *nix.

Esto me ha recordado lo extraordinariamente fácil que se instala Perforce en un ordenador Linux.

Realmente, la primera vez que lo instalé me quedé asustado. Bajar y ejecutar. Nada de dependencias de librerias. Nada de tengo Red Hat pero los paquetes son de Debian, ni viceversa, los paquetes son de Red Hat pero yo tengo Debian/Ubuntu. Nada de: ahora hay que bajarse el paquete tal, que a su vez depende del paquete cual.

La solución a este problema de incompatibilidades y problemas de instalación entre plataformas,es a la vez sencilla y genial. Lincado estático de código.

De cara al usuario es superfácil: solo debes bajarte el ejecutable correspondiente a la versión del kernel de linux que tengas instalada (la versión la puedes obtener con el comando: uname -a).

Perforce es un sistema de control de versiones extremadamente eficiente (recomiendo la lectura de los artículos de Eric Sink acerca del control de versiones). Pues bien, a parte de tratarse de una herramienta fundamental en el desarrollo de software, debo decir que es uno de esos programas sobresalientes. Su facilidad de instalación y su facilidad de uso desbancan a todas las demás soluciones con las que he trabajado (que recuerde ahora mismo: CVS, Subversion y MKS). Desde mi punto de vista, es la mejor solución que existe para el control de versiones, pero también la mas cara. El que quiera asustarse puede consultar su lista de precios.

Conclusión: Siempre existen soluciones sencillas incluso para los problemas más complejos ;)

Habrá quien no le importe lo que voy a decir, a otros les parecerá curioso, a unos pocos les sorprenderá y sólo unos cuantos probablemente lleguen a escandalizarse.Recientemente, tres años después de terminar una Ingeniería Superior en Informática, he aprendido lo que significa el Modelo-Vista-Controlador y como aplicarlo. Cuanto menos curioso, ¿no? Uno de los patrones por excelencia y no sabía como utilizarlo en la práctica.

Bueno, de hecho, lo conocía, sabía lo que era, pero no lo estaba aplicando bien.

¿Qué tiene que ver esto con reescribir código? Bueno, básicamente todo.

Con este conocimiento en mi poder, ahora sé como hacer las cosas mejor de lo que lo hacía, de una forma más organizada, así que puedo continuar añadiendo código a la web de mecanografía tal y como venía haciendo, o puedo aplicar el MVC, haciendo así el código más mantenible para el futuro y más fácil de desarrollar para el presente.

Como siempre, cuando hay que hacer un gran cambio, uno se pregunta: ¿Vale la pena invertir todo este tiempo en ese cambio? ¿compensa el esfuerzo?

La respuesta correcta a esta pregunta sólo se conoce unos meses más tarde de haber tomado una elección. Si después de unos meses la reimplementación y/o reestructuración de código no ha sido beneficiosa de alguna manera, entonces no merecía la pena el esuerzo.

Hasta el momento, he tenido que tomar esa decisión 3 veces en mi carrera profesional. Considero que todas ellas han sido acertadas.

Para el que no se haya parado a pensarlo nunca, a continuación pongo una lista con los pros y las contras para reescribir o reestructurar código.

Las contras de reescribir/reestructurar código:

  • Se invierte tiempo
  • Surgen nuevos bugs (y luego tienes que invertir más tiempo extra en arreglarlos)
  • Dejas de implementar nuevas funcionalidades (y la competencia te come)

Las ventajas de reescribir/reestructurar código:

  • entiendes mejor tu programa
  • tu código se hace más mantenible
  • es más fácil escribir nuevas funcionalidades
  • y en definitiva, te encuentras más agusto con tu código y con ello más feliz :)

Todos los días se aprenden cosas nuevas, uno no puede pasarse la vida reimplementando cosas sólo porque sabe hacerlo un poco mejor. Normalmente suele ser más importante implementar nuevas funcionalidades que aporten algo más al producto, que reescribir o reestructurar código.

¿Cuando pesa más pararse a reescribir código? Cuando sepas que a medio o largo plazo te va a aportar una ventaja competitiva o te haga tan conocedor de tu producto que seas capaz de implementar nuevas funcionalidades en la mitad de tiempo.

Un artículo muy interesante, relacionado parcialmente con el tema y que recomiendo sin lugar a dudas, son las 7 razones por las que Derek Sivers volvió a PHP después de pasar 2 años desarrollando en Ruby On Rails (en inglés – y desde aquí gracias a Héctor por el enlace).

Conclusión: al final voy a readaptar y reestructurar artypist usando MVC porque considero que voy a acabar con un código más estructurado, más mantenible y donde voy a poder añadir nueva funcionalidad más fácilmente (por no hablar que voy a meter todo el código de nuevo en mi cabeza).

Esta tarde he estado trabajando en la página de mecanografía.

El caso es que he perdido muchísimo tiempo para realizar una tarea que en principio parece una chorrada.

Quería hacer una barra de progreso normal y corriente, con un color de fondo, el borde en negro (de un pixel de grosor) y el texto que yo eligiera en el centro.

El problema, como siempre ha venido con la incompatibilidad de los navegadores. Lo que funcionaba en Firefox no funcionaba en Internet Explorer y viceversa. Además también funciona de categoría para Opera.

Finalmente, tras muchos intentos de prueba y error, he conseguido lo que quería. A continuación se puede ver el resultado:

Barra de progresos

Para los interesados, pinchad aquí para ver el ejemplo de la barra de progresos. Si mirais el código fuente vereis lo sencillito que se ha quedado al final.

Nota: Al final he perdido casi más tiempo tratando de poner la barra de progresos en este artículo (WordPress no me deja poner HTML en plano) que programando la barra de progresos. Finalmente he optado por pasar olímpicamente de poner el ejemplo HTML embedido en este artículo y he puesto la imagen.

Actualización: acabo de leer un artículo bastante completo sobre otras soluciones para dibujar barras de progreso y gráficos. Muy interesante :)

Tras la primera entrada sobre de copias de seguridad aquí va otra entrada sobre cómo hacerlo para el caso de servidores web.

Para realizar backups, primero se necesita una cuenta de usuario en la máquina. Si no tienes cuenta de usuario, poco puedes hacer.

En mi caso básicamente tengo dos webs de las que quiero hacer backup: artypist.com y este blog.

Este blog utiliza wordpress, por lo que realmente, hacer un backup de los archivos tampoco aporta mucho valor, ya que en caso de perder los ficheros, se podrian volver a bajar de internet.

Lo más importante de este blog, y de cualquier otro, es la base de datos y los ficheros de imágenes o datos que se puedan haber subido al servidor.

Guardar un backup de los ficheros que puedes conseguir por otra parte es importante en dos casos:

  • Para minimizar el tiempo de reacción cuando te das cuenta de que todo ha dejado de ir: imagina que este blog se borra por arte de magia. Si yo tenia un backup, es mejor restaurar el backup, que tendrá las contraseñas de la base de datos, etc, antes que reinstalar y configurar todo wordpress, ya que se tarda mucho menos en que el servidor vuelva a estar en pleno funcionamiento.
  • Para prevenir pérdida de datos que no recordábamos que habíamos modificado: imagina que cambias el estilo de la página o que has subido archivos y desconoces si se guardaban en la base de datos o el sistema de ficheros. Si tienes una copia de todo, sabes que luego podrás recuperarlo todo. Fácil.

En el caso de Artypist, el punto crítico sería la base de datos, ya que la web, las lecciones, etc… se podrían recuperar del sistema de control de versiones.

En cualquier caso lo mejor es realizar un backup de todo y así uno se cura en salud, por lo que pueda pasar.

Una vez vistos los motivos, el script ideal que soluciona nuestros problemas debería hacer las siguientes cosas:

  • Crear un archivo comprimido (.tgz) para los archivos de cada dominio
  • Crear un archivo comprimido (.gz) por cada base de datos de cada dominio
  • Eliminar copias de seguridad antiguas (p.ej. eliminar copias de hace más de 10 dias)
  • Mandar las copias de seguridad creadas a otro servidor

Una vez se tiene el script, hay que hacer que se ejecute automáticamente de forma periódica. ¿Por qué automáticamente? Porque manualmente se nos olvidaría, o lo iríamos dejando pasar hasta un día en que nos hiciera falta el backup y por pereza ese backup no existiera.

Para ejecutar comandos automáticamente, en linux se usa cron. Así que, nos vamos a una consola y hacemos:

$ crontab -e

Suponiendo que el script de copias de seguridad se encuentra en “/home/usuario/backup.sh”, editamos el archivo de cron para que contenga algo como:

30 3 * * 2,4,7 /home/usuario/backup.sh

Este script se ejecutaría todos los Martes, Jueves y Domingos a las 3:30 de la madrugada. Con lo que tendríamos 3 copias de seguridad a la semana.

Para más información podeis leer este artículo de backups automátios de DreamHost (en inglés)

Para el que quiera echarle un ojo: este es el script de backup en cuestión: Script de Backup

Finalmente, el último paso del script compromete un poco la seguridad, ya que para que no pida passwords hay que crear unas claves y copiarlas en ambos sistemas, así que si el entorno no es del todo seguro, lo mejor es borrar estas lineas.

No soy ningún experto en servidores, y soy consciente de que todo puede hacerse mejor, así que si teneis alguna sugerencia será más que bienvenida.

Nota: dado que el script de backup contiene passwords, etc, hay que ser muy cautelosos acerca de dónde se ubica (para que no sea visible y alguien se lo pueda bajar desde tu web), y acerca de los permisos del archivo (para que otros usuarios del hospedaje no puedan ver su contenido). La recomendación es ejecutar el comando: chmod 700 backup.sh

La pérdida de información debido a que un disco duro falle, o incluso a un error humano (vease “rm -rf *” en el directorio raiz) es algo que pasa más a menudo de lo que a uno le gustaría.

El otro día leí un post acerca de la importancia de los backups en el blog de Canguro Rico y recordé que realmente es importante tener una política de backups y yo, ahora mismo, no hacía backups en mis servidores.

Si uno tiene los medios, lo mejor es tener dos discos duros en RAID-1 por hardware. Así, cuando un disco duro falla, el otro te permite reemplazar el primero y los datos se copian del segundo disco duro, al disco duro reemplazado automáticamente. Cuesta el doble de dinero, pero tienes muchisimas menos probabilidades de perder datos por que un disco duro decida fallar.

Sin embargo esto tampoco previene el fallo humano, ya que un script, con un fallo tonto, nuevamente ejecutar rm -rf * en el directorio raiz, te puede hacer perder todos tus datos. Y ya no hablo de virus para sistemas operativos Windows.

Así pues, lo mejor es guardar backups periódicos y la mejor elección es guardar estos backups en soportes distintos a los que se trabaja. Es decir, no guardes un backup en el propio disco duro que estás intentando proteger.

Para una persona o empresa que viva del software, tener backups no es recomendable, es fundamental.

En todos los sistemas operativos existen ya muchos programas para hacer backups. En mi caso, dado que siempre que puedo uso linux, utilizo el backup-manager, que es muy muy sencillo y hace lo que yo quiero.

Para el caso de los servidores, dado que estoy en un hospedaje compartido y no puedo instalar aplicaciones extra, he realizado un pequeño script que se ejecuta de forma periódica y realiza un backup tanto de los ficheros especificados como de las distintas bases de datos.

En el próximo post, el script en cuestión.

Actualizado: aquí teneis la segunda parte