Bicing y usabilidad.

Alzado.org ha publicado una buena reseña de bicing desde el punto de vista del diseño y usabilidad.
Reconozco muchos de los aciertos de los diseñadores de bicing que se mencionan en el artículo, pero en los "aspectos a mejorar" se han olvidado del detalle más importante de todos. El detalle que puede hacer que yo deje de considerar y utilizar bicing como medio de transporte público diario para relegarlo solo a momentos de ocio.

Muchas veces no hay lugar para dejar las bicicletas.

Que es peor desde el punto de vista de la usabilidad?
1) que el usuario llegue a una estación y no encuentre bicicletas.
2) que el usuario siempre encuentre bicicletas en las estación de partida, pero que no encuentre lugar para dejarla en la estación de destino (o en las 4 estaciones más cercanas).

Ergonomía por Geert Bevin

Ando en la búsqueda constante de la configuración ideal de mi espacio de trabajo. La silla más cómoda, el mejor teclado, un buen monitor, un mouse ergonómico, etc. Una incansable lucha en contra de las contracturas y del dolor de espalda.
En esa búsqueda estaba cuando un conocido programador me recomendó el AlphaGrip , un muy buen teclado, que todavía me cuesta manejar y que me ha convertido en blanco de las más viles bromas y cargadas. Mi amiga Itxaso se queja: "pero que freakies que sois".

El programador que me recomendó el AlphaGrip se llama Geert Bevin, es el creador del framework web Rife y ayer mismo comentaba en su blog que se vio obligado a ir un paso más adelante en la batalla por la ergonomía.

Gracias Geert por ir abriendo el camino. Espero que te mejores pronto de las hernias de disco.

Ahora me pregunto, que me diría Itxaso si me viera programando en esa posición?

ZTT y Tapestry4

Este es el cuarto en una serie de posts donde hablo de ZTT en mi proceso de desarrollo.

1) Desarrollador ágil JAVA. ¿Oxímoron?
2) ZTT y Tapestry5
3) Matt Raible acerca de ZTT

Live Template Reloading

Tapestry4 tiene un muy promocionado "modo desarrollador" en el cual los cambios en los templates html se reflejan en la aplicación sin necesidad de reiniciar el servidor de aplicaciones.
Basta con agregar -Dorg.apache.tapestry.disable-caching=true al comando de ejecución del servidor de apps.

Si bien esta simple configuración es muy útil, tiene sus inconvenientes. El primero es que recarga todos los templates por cada request, hayan o no sido modificados. Cuando la cantidad de componentes en una página es muy grande (como suele ser mi caso) y cuando la cantidad de requests es mucha (como cuando se utiliza AJAX) la velocidad de respuesta de la aplicación se vuelve intolerable y después de la 5 o 6 recargas de la página suele dar algún que otro problema de memoria.

Una mejor alternativa es habilitar el servicio de reset usando -Dorg.apache.tapestry.enable-reset-service=true. Con este servicio habilitado es posible resetear la caché de templates y el pool de componentes simplemente accediendo a la URL /app?service=reset&page=Home o /reset.svc?page=Home

Existen varias propuestas de mecanismos para facilitarle al programador el acceso al servicio de reset. La opción tradicional es dejar abierto un tab del firefox en esa URL y hacer F5 cada vez que se quiera hacer reset. Andreas Andreu (uno de los commiters de tapestry) propone hacerlo desde un script de greasemonkey. Yo, en cambio, prefiero usar una tarea de ant:


<telnet port="8080" server="localhost" timeout="20">
<read>
<write>GET /reset.svc?page=Home HTTP/1.0</write>
<write></write>
</read>
</telnet>


El servicio de reset está desabilitado por defecto porque en producción podría ser muy fácilmente explotado para obtener una denegación de servicio.
Para habilitar reloading de templates en producción fui un paso más allá de lo documentado y expuse el servicio de reset via JMX (gracias a HiveMind) de tal manera de poder automatizar el reset de la cache tomando las mayores precauciones de seguridad (y así evitar un posible DoS).

hivemodule.xml


<contribution configuration-id="hivemind.EagerLoad">
<load service-id="hivemind.management.MBeanRegistry"/>
</contribution>

<contribution configuration-id="hivemind.management.MBeans">
<mbean service-id="TapestryMBean"/>
</contribution>

<service-point id="TapestryMBean" interface="
org.amneris.tapiz4.jmx.TapestryMBean">
<invoke-factory>
<construct class="org.amneris.tapiz4.jmx.TapestryMBeanImpl">
<set-object property="resetEventHub" value="infrastructure:resetEventHub"/>
</construct>
</invoke-factory>
</service-point>

<contribution style="font-weight: bold; font-style: italic;" id="hivemind.EagerLoad"><load id="hivemind.management.MBeanRegistry"></load></contribution><contribution style="font-weight: bold; font-style: italic;" id="hivemind.management.MBeans"><mbean id="TapestryMBean"></mbean></contribution><service-point style="font-weight: bold; font-style: italic;" id="TapestryMBean" interface="com.amneris.muba.jmx.TapestryMBean"><invoke-factory><construct class="com.amneris.muba.jmx.TapestryMBeanImpl"><set-object property="resetEventHub" value="infrastructure:resetEventHub"></set-object></construct></invoke-factory></service-point>java
import org.apache.tapestry.services.ResetEventHub;

public class TapestryMBeanImpl implements TapestryMBean
{

ResetEventHub resetEventHub;

public void resetTapestryCache()
{
resetEventHub.fireResetEvent();
}

public void setResetEventHub(ResetEventHub resetEventHub)
{
this.resetEventHub = resetEventHub;
}
}


Live Class Reloading

En cuanto a class reloading en Tapestry4, ya comenté en el post anterior que solo conozco 2 alternativas (si alguien de alguna más por favor que me lo comente).

1) Sysdeo tomcat launcher plugin (open source)
2) JavaRebel de ZeroTurnaround (software de pago, altamente recomendado)