sábado, 28 de junio de 2014

Synchronous Resource Sharing: Blocking Queue based approach

Recently I had to code an application which allows to send commands to a security device which only allows one connection at the time. Furthermore, there was several devices which want to send those commands concurrently, so there was a problem because N devices had to share one resource which works synchronously.

The solution what came to my mind was implementing a scheduler using a CommandQueue managed by a Thread. So as everytime an incoming request from a device arrives to my server, it defines which kind of request is, and push it into the CommandQueue if needed, then the command is sent by the manager Thread and retrieves the result to the requester Thread.

From now I will write my posts in english and I'm using GitHub to share my code and projects so here is the current example repository.

https://github.com/ivillalba/synchronous-resource-sharing.git

BlockingQueueManager Class




This class acts as a PriorityBlockingQueue wrapper. Its responsability is to handle every incoming task queued. It basically does two things:
  1. Waits for a queued task. If there is no tasks in the queue it remains blocked waiting for one.
  2. Processes a task in a synchronized block, when the task process is completed, the BlockingQueueManager wakes up the Producer thread by calling task.notify() which is waiting at the task.wait() sentence.

Producer Class



This class simulates a task producer. It just builds a random task using the task factory class and pushes it into the PriorityQueue by calling the this.taskQueue.add() method. Then waits for the task to be processed by calling newTask.wait() into a synchronized block.

Task Class


Tasks will have 3 properties.
  1. Priority: Sets the priority of the task.
  2. Name: Is the task name.
  3. Result: This property will be set by the manager with the task processing result.
Task implements Comparable interface since its needed by PriorityBlockingQueue to have a way to compare different instances of its queue collection items.

TaskFactory Class


This class allows us to easily create random Tasks. Its used by Producer to build tasks.

SynchronizedResourceSharing (Main Class)


Is the application entry point. It creates the BlockingQueueManager manager thread and starts five Producer objects. Then waits for them to finish and kills the manager thread.

Output


The result of the application execution is a non deterministic output since the tasks are randomly generated hence their priorities and names.

Task taken.
I'm cooking...
Task done.
Task taken.
Producer[3]: My task has been completed with result 1
I'm programming in JAVA...
Task done.
Producer[1]: My task has been completed with result 2
Task taken.
I'm programming in JAVA...
Task done.
Producer[0]: My task has been completed with result 3
Task taken.
I'm cooking...
Task done.
Producer[2]: My task has been completed with result 4
Task taken.
I'm programming in JAVA...
Task done.
Producer[4]: My task has been completed with result 5
Interrupt signal received. Finishing...

sábado, 12 de abril de 2014

JSF 2.1 Composite Components (LatencyIndicator)

Introducción

Actualmente me encuentro migrando un proyecto desarrollado en AngularJS a Java Server Faces (JSF) + Primefaces. Aún estoy aprendiendo las particularidades de ambos frameworks y debo decir que la curva de aprendizaje es bastante satisfactoria en lo que a la relación tiempo de aprendizaje / conocimientos aplicables se refiere.

JSF ofrece la posibilidad de crear componentes personalizados reutilizables conocidos como Composite Components. Los composite components son componentes web que se modelan una vez y ya están listos para ser utilizados en distintos proyectos de manera extremadamente sencilla. Me pareció una característica muy interesante desde un punto de vista de la reutilización del software y me decidí a hacer un ejemplo muy sencillo pero que creo que ilustra bien esta característica de JSF.

El componente LatencyIndicator

En este artículo vamos a desarrollar un componente sencillo que representa el estado de latencia de una conexión apoyándonos en composite components.

Para desarrollar un componente lo mas importante es determinar la manera en que se va a comportar. En principio nuestro indicador tendrá tres estados, baja latencia (representado como un piloto verde), latencia media (ámbar) y latencia alta (rojo).

Para comenzar a definir un componente debemos incluir el espacio de nombres de composite components al documento .xhtml del mismo.


LatencyIndicator.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:composite="http://java.sun.com/jsf/composite"
      xmlns:h="http://java.sun.com/jsf/html">

    <!-- INTERFACE -->
    <composite:interface>
        <composite:attribute name="latencia" type="java.lang.Integer" required="true"/>
        <composite:attribute name="umbralMedio" type="java.lang.Integer" default="75"/>
        <composite:attribute name="umbralAlto" type="java.lang.Integer" default="150"/>
    </composite:interface>

    <!-- IMPLEMENTATION -->
    <composite:implementation>
        <h:panelGrid columns="2" border="0" styleClass="latencia-grid">
            <h:graphicImage value="#{resource['images:rojo.png']}" rendered="#{cc.attrs.latencia ge cc.attrs.umbralAlto}"/>
            <h:graphicImage value="#{resource['images:ambar.png']}" rendered="#{(cc.attrs.latencia lt cc.attrs.umbralAlto) and (cc.attrs.latencia ge cc.attrs.umbralMedio)}"/>            
            <h:graphicImage value="#{resource['images:verde.png']}" rendered="#{cc.attrs.latencia lt cc.attrs.umbralMedio}"/>
            <h:outputText value="#{cc.attrs.latencia} ms."/>
        </h:panelGrid>
    </composite:implementation>
</html>
Simplemente se ha declarado que va a constar de tres atributos. El valor de la latencia y los umbrales medio y alto de latencia por defecto inicializados a 75 y 150 milisegundos. El comportamiento del componente consta de tres imágenes que se renderizan de forma condicional en función del rango de latencia en que se encuenta la conexión. ¿Podría haberse empleado la estructura c:choose de JSTL. Si, pero mezclar JSF y JSTL no es conveniente ya que se procesan en etapas distintas en el ciclo de renderizado del documento JSF y esto deriva en algunos problemas y comportamientos, a priori, no esperados como por ejemplo al incluir el componente en un iterable (datatable).


Ejemplo de uso del componente

Como ejemplo incluiré el componente en una tabla que representará distintos servidores y las latencias que hay con ellos.

index.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:miscomponentes="http://java.sun.com/jsf/composite/ezcomp"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui">
    <h:head>
        <title>Facelet Title</title>
        <style>
            .ui-widget, ui-widget ui-widget {
                font-size: 10pt;
            }
            
            .latencia-grid tr, .latencia-grid tr td {
                border: none;
            }
        </style>
    </h:head>
    <h:body>
        <h:form id="miForm">
            <h:commandButton id="boton" value="Generar Latencias">
                <f:ajax render="@form" event="click" listener="#{latencyBean.generarLatencias()}"/>
            </h:commandButton>
            <p:dataTable value="#{latencyBean.servidores}" var="servidor" style="width: 100px;">
                <p:column headerText="Latencia">
                    <miscomponentes:LatencyIndicator latencia="#{servidor.latencia}"/>
                </p:column>
                <p:column headerText="Nombre">
                    <h:outputText value="#{servidor.nombre}"/>
                </p:column>
                <p:column headerText="IP">
                    <h:outputText value="#{servidor.ip}"/>
                </p:column>
            </p:dataTable>
        </h:form>
    </h:body>
</html>
Servidor.java

package entidades;

public class Servidor {
    private String nombre;
    private String ip;
    private Integer latencia;

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public Integer getLatencia() {
        return latencia;
    }

    public void setLatencia(Integer latencia) {
        this.latencia = latencia;
    }
}

LatencyBean.java

package beans;

import entidades.Servidor;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean
@RequestScoped
public class LatencyBean {
    private List<Servidor> servidores;
    
    public LatencyBean()
    {
        generarServidores();
    }

    private void generarServidores()
    {
        Random rand = new Random();
        servidores = new ArrayList<Servidor>();
        
        for (int i = 0; i < 10; i++)
        {
            Servidor servidor = new Servidor();
            servidor.setIp("192.168.0." + i);
            servidor.setNombre("Servidor " + i);
            servidor.setLatencia(rand.nextInt(150 + 50));
            servidores.add(servidor);
        }
    }

    public final void generarLatencias() {
        Random rand = new Random();
        for (Servidor s : servidores)
        {
            s.setLatencia(rand.nextInt(150 + 50));
        }
    }

    public List<Servidor> getServidores() {
        return servidores;
    }

    public void setServidores(List<Servidor> servidores) {
        this.servidores = servidores;
    }
}

Resultado