AOWS

Just another adrian’s weblog

Navegar por una revisión concreta de un repositorio Subversion

leave a comment »

Subversion incluye de serie una interfaz web para navegar por los repositorios, aunque es muy limitada en funciones y sobre todo en usabilidad.

Por defecto la web muestra la última revisión, pero… ¿cómo hacemos para navegar por una anterior? Pues “muy fácil”, añadiendo el parámetro !svn/bc/XXX/ a la url, siendo XXX el número de revisión.

Es decir, si por ejemplo el repositorio está en http://svn.local/mi_proyecto/ y queremos ver la revisión 123, la dirección sería http://svn.local/mi_proyecto/!svn/bc/123/.

De todas formas si vas a hacer uso intensivo de esta herramienta quizá te interese utilizar otras aplicaciones como WebSVN, que incluyen muchas más opciones.

Written by adrian

18 marzo, 2010 at 10:38

Publicado en Uncategorized

Tagged with

Efecto botón en un enlace con a:active

leave a comment »

Las pseudo-clases se aplican a ciertos selectores CSS para añadirles algunos efectos. Un buen ejemplo lo tenemos en los enlaces, a los que le podemos aplicar reglas según el estado en el que se encuentren:

  • a:link un enlace no visitado
  • a:visited un enlace ya visitado
  • a:hover el ratón está sobre el enlace
  • a:active el usuario hace click sobre el enlace

En este ejemplo vamos a usar a:active para darle un efecto botón a un enlace. Para ello tendremos que añadir las siguientes reglas a nuestro CSS, así cuando un usuario haga click en el enlace éste se desplazará ligeramente hacia abajo dando la impresión de que se ha presionado un botón (lo cual puede ser una interesante ayuda visual).

a:active {
  position: relative;
  top: 2px;
}

Como wordpress.com no deja insertar estilos propios en los posts, no me queda más remedio que dejar el ejemplo en mi dominio: ejemplo de efecto botón con a:active.

Visto en “The definitive guide to styling web links“.

Written by adrian

14 febrero, 2010 at 02:24

Publicado en Uncategorized

Tagged with

La web se decanta por Unicode

leave a comment »

Casi el 50% de la red usa Unicode

Casi el 50% de la red usa Unicode

El problema con los encodings está presente en los programas informáticos desde hace muchos años; el rápido crecimiento de Unicode en la web, cerca ya del 50% de las webs usan alguna variante de esta codificación (el gráfico proviene de estadísticas internas de Google basadas en las páginas indexadas por el buscador), nos permite ver algo de luz para aquellos cuyo idioma principal no sea el inglés. Puede que algún día dejemos de ver caracteres como ërnôn.

Written by adrian

13 febrero, 2010 at 01:46

Publicado en Uncategorized

Tagged with , ,

Logging con SLF4J

with one comment

SLF4JSLF4J (Simple Logging Facade for Java) proporciona una capa de abstracción sobre otros APIs de logging como log4j o LogBack. Esta librería permite cambiar la implementación de forma transparente, de un modo similar a Commons Logging. Sin embargo, ésta última elige el API en tiempo de ejecución (lo cual puede provocar algún que otro problema), mientras que SFL4J lo hace al desplegar la aplicación usando un JAR puente.

Una de las grandes ventajas de SLF4J es que no necesitamos inundar nuestro código con comprobaciones del nivel de log. Si usamos log4j, por ejemplo, podemos tener algo como:

log.debug("Esto es un " + texto + " muy largo, con " + variables[i] + " que se van añadiendo a una " + object.getCadena());

Por mucho que el compilador optimice este código (reemplazando las concatenaciones de cadenas usando StringBuilder), si se ejecuta muchas veces repetidamente sin necesidad (porque la aplicación está desplegada en producción y el nivel de log está por encima de debug, por ejemplo) podría llegar a afectar al rendimiento. Por lo que no es extraño ver código Java tal como este:

if (log.isDebugEnabled()) {
  log.debug("Esto es un " + texto + " muy largo, con " + variables[i] + " que se van añadiendo a una " + object.getCadena());
}

SLF4J nos permite parametrizar el log al estilo printf de C:

log.debug("Esto es un {} muy largo, con {} que se van añadiendo a una {}", texto, variables[i], object.getCadena());

Esto evita problemas de rendimiento al tratar con cadenas, pero evidentemente si los parámetros como object.getCadena() son costosos nada nos librará de tener que usar los dichosos if.

SLF4J tiene más ventajas, para conocerlas nada mejor que este artículo o el manual oficial.

Written by adrian

13 febrero, 2010 at 01:16

Publicado en Uncategorized

Tagged with , ,

Stand vertical casero para el MacBook

with 2 comments

Stand vertical para el MacBook

Me encontraba a un solo click de comprar este soporte vertical, cuando se me ocurrió la idea del servilletero. Cutre, pero barato y completamente funcional. Ahora bien, he de buscar uno un poco más acorde con el ordenador y que no cante tanto🙂

Written by adrian

11 febrero, 2010 at 23:07

Publicado en Uncategorized

Tagged with ,

Desplegando Twitter en producción usando BitTorrent

leave a comment »

Los problemas de mantenimiento que conllevan aplicaciones tan grandes como Twitter pueden pasar desapercibidos para los que no estamos acostumbrados a una escala de centenares (e incluso miles) de máquinas en producción. Y no se puede negar el que la solución adoptada no sea original: desplegar utilizando BitTorrent.

Se necesita una máquina que haga las veces de tracker y otra que sirva como seeder. Una vez creado el torrent, el resto de servidores comenzarán a descargar los archivos y a compartirlos entre sí; el despliegue es (obviamente) mucho más rápido que si subimos la aplicación servidor a servidor.

El proyecto, llamado Murder, está basado en BitTornado y está disponible en GitHub bajo la licencia Apache. Como ejemplo de despliegue dejan esta secuencia de comandos que usan Capistrano:

cap murder:distribute_files
cap murder:start_tracker
cap murder:create_torrent tag="Deploy20100101" files_path="/usr/local/twitter/production/current"
cap murder:start_seeding tag="Deploy20100101"
cap murder:peer tag="Deploy20100101" destination_path="/usr/local/twitter/releases"

Written by adrian

10 febrero, 2010 at 22:50

Publicado en Uncategorized

Tagged with ,

“null”, o una de las maldiciones de Java

with 5 comments

Tratar con valores nulos es, desde siempre, un dolor de muelas muy importante en el mundo de Java. En este artículo de Redcode nos lo recuerdan y proponen algunas de las pocas opciones que hay:

  • Confiar en que nuestras referencias nunca serán nulas y no realizar ninguna comprobación. Como es obvio, un tanto peligroso, sobre todo cuando utilizamos librerías de terceros cuyos resultados no conocemos con seguridad.
    List<Person> people = getPeople();
    for (Person person : people) {
      House house = person.getHouse();
      System.out.println("House price: " + house.getPrice());
    }
    
  • Inundar el código con condicionales anidados, uno detrás de otro según el número de objetos que tengamos.
    List<Person> people = getPeople();
    if (people != null) {
      for (Person person : people) {
        if (person != null) {
          House house = person.getHouse();
          if (house != null) {
            System.out.println("House price: " + house.getPrice());
          }
        }
      }
    }
    
  • Utilizar anotaciones (@Nullable y @NotNull) que nuestro IDE usará para advertirnos de posibles riesgos de obtener un NullPointerException. No nos evitará el tener que hacer comprobaciones, pero podemos fiarnos si no hay warnings.
    @Nullable
    private List<Person> getPeople() {
      // ...
    }
    
    // ... 
    
    List<Person> people = getPeople();
    // recibiremos un warning, y es que "people" puede ser nulo
    for (Person person : people) {
      House house = person.getHouse();
      System.out.println("House price: " + house.getPrice());
    }
    
  • Utilizar algún patrón como Null Object pattern o una versión más general (Special Case) propuesta por Martin Fowler. El problema es que esto no soluciona las interacciones con librerías externas (que pueden seguir devolviendo nulos) y complica el proyecto con un montón de objetos nuevos.

Por desgracia, la nueva versión de Java no incluirá ningún operador específico para solucionar esta situación. Estuvo en los planes incluir algo similar al operador Elvis safe navigation operator de Groovy:

List<Person> people = getPeople()
println people?.get(0)?.getHouse()?.getPrice()

pero finalmente todo seguirá igual. Una pena porque esto mejoraría enormemente la legibilidad del código; lo pondría incluso por delante de nuevas características como las closures (que llegan tarde, esperemos que no mal y arrastro).

Written by adrian

4 febrero, 2010 at 22:47

Publicado en Uncategorized

Tagged with ,