06.24.09

Ejemplo de Maquetación con Capas

Posted in Web at 9:31 pm by Miguel

A continuación os dejo un pequeño ejemplo de una web que ha sido maquetada usando capas en lugar de tablas.

Como podréis observar, los diferentes elementos, además de ciertos cambios básicos de estilos obtenidos mediante CSS, han cambiado su posicionamiento totalmente, algo que mediante una maquetación por tablas hubiera sido imposible.

Cada página cuenta exactamente con el mismo contenido y esta enlazada a un CSS diferente, los cuales si supervisáis, podréis ver que cada una de las capas utilizadas explota los atributos de CSS “clear” y “float” para lograr el cambio en el posicionamiento de los objetos.

Se ha preparado la maquetación solo para Internet Explorer, compreded que se introducen los conceptos a modo didáctivo y que tampoco voy sobrado de tiempo :)

Página 1CSS 1

Página 2CSS 2

Página 3CSS 3

Un saludo.

Miguel.

Rating 3.00 out of 5
[?]

06.21.09

Las Partes Fundamentales de un Motor de Flujo – III Parte

Posted in BPM at 6:12 pm by Miguel

Tras haber repasado los conceptos básicos, y algunos conceptos algo más avanzamos como son las delegaciones, reenvíos y BAM, pasamos ahora a describir una de las piezas fundamentales en el uso de motores de flujo: la Bandeja de Tareas.

El concepto de tarea ya lo repasamos en el capítulo de conceptos básicos, donde pudimos ver que éstas se iban generando a medida que se van alcanzando las actividades de cada uno de los flujos que se han definido y son iniciables a través del motor.

Las tareas generadas, estén en el estado que estén, se almacenan en un repositorio específico, el cual es consultable a través del API del motor de flujo con el que estemos trabajando, y que retorna información básica asociada a las tareas del repositorio. Por ejemplo:

* Fecha de Creación
* Nombre de la Actividad a la que representa la tarea
* Estado: Finalizado, Pendiente, Reenviado, En Curso, Cancelado
* Nombre del Flujo asociado
* Fecha de Finalización
* Usuario o grupo que tiene la tarea asignada

Como comentábamos, a través de API pertinente, se pueden consultar las tareas existentes, incorporando además diversos filtros, como pueden ser, las tareas en un determinado estado, tareas creadas entre un rango de fechas, tareas pertenecientes a una determinada actividad o tareas pertenecientes a un determinado usuario. Las capacidades de filtro dependerá del motor de flujo sobre el que estamos trabajando. Existen dos tipos de filtros básicos empleados, como son las tareas pendientes de un usuario en concreto y el conjunto de tareas que aún no se han asignado a ningún usuario (también llamadas tareas de pool).

A partir de estas consultas ya podemos preparar una bandeja de tareas, la cual consistiría en una página (normalmente la inicial de la aplicación), donde un usuario, tras haberse autenticado, podría consultar qué tareas tienen pendientes para él. Otras opciones básicas de consulta para el usuario sería ver en la misma bandeja qué tareas no tienen aún asignación de usuario, pero están asignadas a uno de los grupos a que dicho usuario pertenece (hablaremos de usuarios, grupos y roles en próximos posts). El usuario podría realizar las tareas que tiene ya asignadas, o asignarse (tomar en propiedad) alguna de las tareas pendientes de asignar y pertenecientes a alguno de sus grupos.

Finalmente, otra de las características básicas que aparecen en una bandeja de tareas para un usuario, es la capacidad de finalizar una tarea de tipo “punto de control” de forma directa, desde la propia bandeja, sin necesidad de acceder a la tarea para poder finalizarla. Como ya hablamos en su momento, las tareas de tipo “punto de control” son las que únicamente es necesario marcar que se han realizado, sin necesidad de incorporar ningún tipo de información de negocio relacionada con la misma. Se suelen utilizar mucho en el caso de marcar entregas o recepciones de documentación. En estos casos, en la bandeja de tareas, existe la posibilidad de seleccionar las tareas de tipo “punto de control” para finalizarlas de forma masiva.

Otras opciones más avanzadas y ya desde una bandeja de tareas de un usuario administrador, sería contar con la posibilidad de reenviar tareas de la bandeja así como la de cancelar las mismas. Incluso, y ya dependiendo del negocio, la posibilidad de crear nuevos flujos, seleccionados del conjunto de flujos disponibles en la aplicación.

Información Adicional, propia del Negocio

Hasta ahora hemos cómo podría funcionar una bandeja de tareas, mostrando en todo caso información relacionada únicamente con el motor, pero, hemos de tener en cuenta que un motor de flujo es únicamente una herramienta que da soporte para la resolución de un determinado tipo de problema que se da en un ámbito en concreto, y una herramienta que tenga sentido por si misma. Por ejemplo, podríamos utilizar nuestro motor para la gestión de una pizzería, o de un call-center, y dicho “negocio” incluiría información propia que seguramente sería interesante que se mostrara en la bandeja. En el caso de la pizzería, por cada comanda lanzada y que aparecería en la bandeja en forma de tarea, a parte de mostrar la fecha y la hora en que la pizza fue pedida (fecha de creación de la tarea), sería interesante mostrar los ingredientes de la misma. En el caso del call-center, sería interesante mostrar el nombre y apellidos de la persona que ha realizado la llamada inicial, así como un indicador de si está asociado a alguna de las promociones existentes.

Esta situación nos plantea un pequeño problema, ya que la fuente de datos donde se almacenan las tareas con la fuente de datos donde se almacena la información del negocio, no suele ser la misma, y no tanto ya el respositorio, si no la tecnología con la que el respositorio se ha generado. De ahí que el mezclar la información propia del negocio con la información del motor de flujo, en tiempo real (hay que pensar que la bandeja de tareas es una herramienta que tiene que mostrar un estado actualizado real en todo momento), represente, a priori un problema, atendiendo además a los requerimientos de velocidad en el uso que este tipo de características plantea (teniendo en cuenta que va a ser la funcionalidad más empleada de la aplicación, es necesario que lo tiempos de repuesta sean manejables).

Ante todo esto, ¿soluciones? Pues a priori va a depender un poco de la topografía de vuestro sistema, y de los requerimientos de usuario, pero, en principio, lo ideal sería que al mostrar la información estemos consultando el menor número de sistemas, ya que cuantos más estemos consultando, más vamos a tardar en dar una respuesta. Para ello una opción sería incorporar al flujo y a las tareas la información que queremos mostrar en la bandeja. Por ejemplo, al dar de alta el proceso (instancia del flujo), podríamos incorporar ya de serie los ingredientes de la pizza, así cuando consultemos la bandeja de tareas nos bastaría atacar una fuente de datos para obtener toda la información.

Esta decisión a priori no es sencilla, y como os comentábamos va a depender directamente de vuestros requerimientos. Para que os hagáis una idea, en el último sistema de bandeja de tareas sobre el que he podido trabajar, se consultaban dos fuentes información diferentes y se mezclaba la información en memoria antes de mostrarla en la bandeja, y, este sistema, para la topografía  existente, era el más eficiente con diferencia.

Aprovecho la temática para comentar que al trabajar con un motor de flujo podemos encontrarnos con el mismo problema pero a la inversa, es decir, que al trabajar con la información de negocio, necesitemos mostrar cierta información relacionada que está almacenada en el motor de flujo. Por ejemplo, si queremos mostrar cuando una pizza fue entregada, podríamos consultar la fecha de fin del proceso. Pero esto nos obligaría a consultar primero el repositorio del negocio y a continuación consultar el proceso relacionado para obtener la fecha. Soluciones a esto sería que antes de cerrar el proceso se lanzara desde el mismo la actualización de la información del negocio, incorporando la fecha de fin de proceso a la fecha de entrega de la pizza. Tenemos una pequeña información redundante, pero, hemos ganado en eficiencia en cuanto a la consulta de la trazabilidad de la información asociada a  un pedido.

Terminamos por hoy. En el próximo post, hablaremos de Gestión de Usuarios, Grupos y Roles.

Saludos.

Miguel.

Rating 3.00 out of 5
[?]

06.19.09

Posts y Howtos sobre Team Foundation Server

Posted in Team Foundation Server at 3:47 pm by Miguel

Os dejo a continuación el link a un post muy interesante donde se detallan muchos aspectos a tener en cuenta en cuanto al uso y manejo de Team Foundation Server tanto 2005 como 2008.

http://geeks.ms/blogs/elbruno/archive/2009/06/19/tfs2008-posts-y-howtos-sobre-team-foundation-server-2008-y-2005-v.aspx

Saludos.

Miguel.

Rating 3.00 out of 5
[?]

06.13.09

Return String vs Return Enum

Posted in Buenas Prácticas at 9:31 pm by Miguel

Qué bonito y al mismo tiempo qué sencillo, bonito y barato.

function string GetTipoMarca(int idMarca)
{
// acciones pertinentes para retorna el tipo de marca
// relacionado al id pasado por parámetro, los tipos se devuelven como
// strings “Mercedes”, “Seat”, “BMW”
}

vs

function TipoMarcaEnum GetTipoMarca(int idMarca)
{
// acciones pertinentes para retorna el tipo de marca
// relacionado al id pasado por parámetro, los tipos se devuelven como
// un tipo enumerado que tipifica los valores “Mercedes”, “Seat”, “BMW”
}

Es un pequeño detalle, pero mejoramos así la encapsulación, la abstracción, el mantenimiento, el coste del cambio… ¿Tanto esfuerzo cuesta entonces no olvidarse de estos detalles cuando se está construyendo?

Saludos.

Miguel.

Rating 2.00 out of 5
[?]

06.09.09

Variables de Sesión en Memoria, Balanceos y Alta Disponibilidad

Posted in .NET, Arquitectura, Web at 5:56 pm by Miguel

Una de las herramientas más comunes a la hora de trabajar con aplicaciones web son las variables de sesión.

Dejando de lado en este capítulo las recomendaciones de arquitectura en el uso de las sesiones, simplemente plantear una solución a uno de los típicos problemas que se encuentran los arquitectos de software a la hora de definir el uso de sesiones, que son las limitaciones al uso relacionadas a entornos donde se cuente con una infraestructura que ofrezca alta disponibilidad cuando estamos trabajando con variables de sesión almacenadas en la memoria del servidor.

Para solucionar este problema, existen productos disponibles en el mercado, que lo que hacen es mantener también balanceado el contenido de la sesión de todos los servidores existentes en una granja, por lo que, aunque un usuario a medida que va lanzando peticiones, el balanceador lo vaya dirigiendo a servidores diferentes, podrá seguir trabajando con la información de sesión que haya generado, en memoria, en un servidor diferente.

Os dejo el link a uno de los productos que solventa este problema en entornos .NET: NCache

http://www.alachisoft.com/ncache/

Saludos.

Miguel.

Rating 3.00 out of 5
[?]

06.05.09

Google Wave y HTML 5

Posted in Noticias Actualidad at 4:00 pm by Miguel

Señores, la que se avecina.

http://www.cristalab.com/blog/google-wave-todo-lo-que-tienes-que-saber-c73716l/

Otras referencias:

http://wave.google.com

Gracias Pablo por la referencia.

Saludos.

Miguel.

Rating 3.00 out of 5
[?]

06.04.09

Team Foundation Sidekicks

Posted in Herramientas, Team Foundation Server at 6:34 pm by Miguel

Los usuarios que comunmente trabajamos con Team Foundation echamos de menos algunas características avanzadas que no están disponibles a través del interfaz de Visual Studio, como es por ejemplo el desbloqueo de archivos, que como ya comentamos en un artículo anterior, se debía hacer desde la consola.

Estay otras características están disponibles en la aplicación Team Foundation Sidekicks la cual provee de una serie de facilidades que ayudan al desarrollador a trabajar con Team Foundation y sacarle algo más de partido.

Os dejo el link a a la descripción ampliada del producto.

http://www.attrice.info/cm/tfs/index.htm

Gracias, Jaime y Guillermo, por la referencia.

Saludos.

Miguel.

Rating 3.00 out of 5
[?]

06.03.09

Web, Colas de Mensajería y Experiencia de Usuario

Posted in Arquitectura, Colas de Mensajería, Web at 7:34 pm by Miguel

Estrenando en el blog el mundo de las Colas de Mensajería, y la categoría recién inaugurada a tal efecto, hoy vamos a hablar cómo se está explotando en la actualidad las capacidades que ofrecen estos sistemas en entornos web.

A priori, y conociéndo únicamente las características básicas de funcionamiento de las aplicaciones cliente-servidor web y los sistemas de colas de mensajería, resulta de extrañar que pueda sacarse algún tipo de partido combinándolas, ya que:

  • La relación entre un cliente web y el servidor es síncrona y uni-direccional. El cliente solicita la comunicación con el servidor, quedando a la espera de respuesta antes de poder seguir el hilo de ejecución, de forma, insisto, totalmente síncrona.
  • En cambio un sistema de gestión de colas es en esencia asíncrono, ya que, a grandes rasgos, consiste en un punto de entrada que va almacenando peticiones en un determinado órden, y que garantiza que las peticiones van a llegar al destino, pero por defecto no garantiza cuándo. En cuanto la petición ha sido procesada, la respuesta se asocia a un punto de salida, el cual la aplicación llamante debe consultar para conocer el resultado del procesamiento.

Entonces, si el trabajo en web es síncrono, y los sistemas de colas de mensajería asíncronos, ¿como podemos obtener algún tipo de beneficio? Paso a enumerar escenarios:

  1. Se debe realizar un cálculo que requiere de tiempos no manejables en entornos web de manera síncrona (más de 1 minuto se podría considerar como inmanejable).
  2. La petición que se recibe en el servidor sólo es ejecutable en algunas ventanas de tiempo.
  3. No es necesaria la notificación de ejecución completa al usuario una vez lanzado un proceso, por lo que podemos gestionar internamente cuándo lanzararemos el proceso demandando para optimizar así el consumo de cpu y memoria.

Se pueden encontrar muchos ejemplos de estos usos por ejemplo en redes sociales como Facebook, donde en muchas ocasiones se proponen envíos masivos de notificaciones, invitaciones y noticias a un grupo muy grande de usuarios. Una vez realizada la petición, esta es encolada y ejecutada a posteriori.El usuario no tiene necesidad de conocer a ciencia cierta que la petición se ha ejecutado en el momento, se conformo en saber que los avisos, llegarán. Lo mismo ocurre con otros sistemas muy habituales como son los envíos de SMS a través de teléfono móvil.

La ventaja y moraleja del artículo respecto a todo esto, es que el uso sistemas basados en colas de mensajería ayudan a maximizar la experiencia de usuario en entornos web, ya que tras una petición que podría resultar en una larga espera síncrona hasta que el servidor haya terminado de ejecutar la petición, esta termina al momento (desde el punto de vista del usuario), y el usuario puede seguir utilizando la aplicación sin problemas. Mientras tanto, por detrás, el gestor de mensajes ha encolado la petición, la cual, en su momento, será ejecutada.

Si vuestro escenario es similar al aquí planteado, emplear una solución basada en sistemas de colas de mensajería, podría ser una buena solución de arquitectura.

Saludos.

Miguel.

Rating 3.00 out of 5
[?]

06.02.09

Consideraciones de Arquitectura respecto al uso de Variables de Sesión

Posted in .NET, Arquitectura, Web at 6:47 pm by Miguel

A continuación paso a enumera una serie de consideraciones a tener en cuenta y que os pueden ser útiles a la hora de tomar ciertas decisiones de arquitectura al respecto del uso de variables de sesión. Como veréis algunas de ellas tienen que ver con entornos .NET, ya que es la plataforma con la que suelo trabajar, pero la mayoría son aplicables a otros entornos tecnológicos no Microsoft.

Sesión en Memoria vs Sesión en Sistemas Persistidos (Base de Datos o Servicios del Sistema Operativo)

La forma más eficiente de trabajar con sesiones es manteniendo su contenido en memoria. En el caso de estar trabajando con una granja de servidores, pueden utilizarse soluciones existentes en el mercado como es NCache, para balancear el contenido de las sesiones en memoria entre todos los servidores de la granja.

En caso de no poder barajar esta alternativa existen soluciones que permiten almacenar el contenido de la sesión sobre sistemas persistidos. Esta solución es más lenta, pero permite compartir la información de sesión sobre diferentes servidores, además de garantizar que aunque se reinicie el servidor de aplicaciones, la información de sesión va a permanecer disponible cuando la aplicación vuelva a arrancarse.

Cantidad de Memoria en Uso

El uso de sesión afecta directamente al consumo de memoria del servidor que está ejecutando las llamadas del cliente, por lo que deberá almacenarse en sesión únicamente la información que se considera imprescindible y que, se recomienda, esté relacionada con alguna de las siguientes características:

  • Información básica relacionada con la autenticación o la seguridad del usuario y que es necesario comprobar en las llamadas o peticiones que realiza el usuario contra la aplicación.
  • Otro tipo de información funcional asociada al usuario, que va a permanecer estática a lo largo de toda la vida de la sesión y que es requerida de forma constante en las peticiones que realiza el usuario a la aplicación. El objetivo de este punto sería minimizar el número de llamadas a base de datos.

Tipos de Objetos en Memoria

Los objetos almacenados en la sesión deben ser en todo caso de poco peso, minimizando así la cantidad de información almacenada por sesión por cada objeto. Se recomienda el uso de objetos de negocio que incluyan tipos de datos básicos. No se recomienda el almacenamiento de objetos propietarios de .NET del tipo Dataset ó DataTable debido al tamaño asociado a los mismos.

Manejando Información Sensible

Si el contenido almacenado en la sesión contiene información sensible, como podrían ser contraseñas o información personal del usuario activo, ésta deberá permanecer encriptada durante todo el ciclo de vida de la sesión.

Usando Sesión a modo de Caché

No debe emplearse la sesión para almacenar catálogos de datos comunes de la aplicación, como podrían ser listados de países, regiones, provincias, etc, ya que éste no es el objetivo de  este tipo de objeto. Para estos casos se deberá recurrir a un objeto de tipo caché.

Usando Sesión a modo de Viewstate (específico .NET)

No se recomienda emplear la sesión para almacenar información que será necesaria explotar entre llamadas a la misma página, ya que para ello existe un objeto preparado específicamente para resolver esta problemática como es el Viewstate de ASP.NET.

Usando Sesión a modo de POST y GET

No debe emplearse la sesión para transportar información entre páginas de la misma aplicación, ya que para ello se deberá recurrir a los objetos POST y GET.

Liberando Información de Sesión

Siempre y cuando se detecte que la información almacenada en sesión deje de ser necesaria para la sesión de usuario actual, se debe solicitar la liberación de la memoria asociada al servidor.

Saludos.

Miguel.

Rating 3.00 out of 5
[?]

06.01.09

Patrones de Ajax: El Refresco Periódico

Posted in Arquitectura, Patrones at 11:28 pm by Miguel

En la sección de patrones de diseño inauguramos los patrones de Ajax, con la descripción del patrón: Refresco Periódico.

El patrón viene a describir la solución a un problema común y que parte de una de las principales limitaciones de la soluciones web, la uni-direccionalidad de la relación cliente-servidor. La parte cliente es la que siempre toma la iniciativa ante cualquier transacción, por lo que si en las situaciones en las que queremos mostrar un aviso de cuándo un proceso de cálculo complejo que se ha lanzado de forma asíncrona ha terminado, o cuando por ejemplo a los usuarios autenticados en nuestra aplicación queremos mostrarles un aviso de que se ha recibido stock de un determinado producto, no tenemos más remedio que utilizar diferente estrategias, siempre por parte del cliente, para “engañar al usuario”.

Una de las soluciones a este típico problema es el uso del Patrón del Refresco Periódico, que a grandes rasgos consiste en realizar llamadas periódicas a través de ajax al servidor, para ir solicitando el refresco del estado de la información que necesitamos consultar. Como al utilizar ajax la página no se refresca de forma completa, la experiencia de usuario da como resultado algo bastante similar a lo que puede aportar una aplicación de escritorio.

Más información en http://ajaxpatterns.org/Periodic_Refresh

Saludos.

Miguel.

Rating 3.00 out of 5
[?]