Con WebSphere eXtreme Scale, puede proporcionar una prestación parecida a una cola FIFO (primero en entrar, primero en salir) para todas las correlaciones. WebSphere eXtreme Scale realiza un seguimiento del orden de inserción de todas las correlaciones. Un cliente puede solicitar una correlación para la siguiente entrada desbloqueada en una correlación en el orden de inserción y bloquear la entrada. Este proceso permite a varios clientes consumir entradas de la correlación de una forma eficaz.
Session session = ...;
ObjectMap map = session.getMap("xxx");
// esto es necesario establecerlo en algún lugar para detener este bucle
boolean timeToStop = false;
while(!timeToStop)
{
session.begin();
Object msgKey = map.getNextKey(5000);
if(msgKey == null)
{
// la partición actual se ha agotado, invóquela de nuevo en
// una nueva transacción para pasar a la partición siguiente
session.rollback();
continue;
}
Message m = (Message)map.get(msgKey);
// ahora consumir el mensaje
...
// es necesario suprimirlo
map.remove(msgKey);
session.commit();
}
Para la modalidad de cliente, si la JVM (Java Virtual Machine) es un cliente, el cliente se conecta inicialmente a un primario de partición aleatoria. Si no hay trabajo en esa partición, el cliente pasa a la siguiente en busca de trabajo. El cliente encuentra una partición con entradas o realiza un bucle y vuelve a la partición aleatoria inicial. Si el cliente realiza un bucle y vuelve a la partición inicial, devolverá un valor nulo a la aplicación. Si el cliente encuentra una partición con una correlación que tenga entradas, consumirá entradas de la misma hasta que no haya entradas disponibles durante el periodo de tiempo de espera. Una vez que ha transcurrido el tiempo de espera, se devuelve el valor nulo. Esta acción significa que cuando se devuelve nulo y se utiliza una correlación particionada, se debe iniciar una nueva transacción y reanudar la escucha. El fragmento de ejemplo de código anterior tiene este comportamiento.
Job.java
package tutorial.fifo;
import com.ibm.websphere.projector.annotations.Entity;
import com.ibm.websphere.projector.annotations.Id;
@Entity
public class Job
{
@Id String jobId;
int jobState;
}
JobEvent.java
package tutorial.fifo;
import com.ibm.websphere.projector.annotations.Entity;
import com.ibm.websphere.projector.annotations.Id;
import com.ibm.websphere.projector.annotations.OneToOne;
@Entity
public class JobEvent
{
@Id String eventId;
@OneToOne Job job;
}
El trabajo tiene un ID y un estado, que es un entero. Suponga que desea incrementar el estado cuando llega un suceso. Los sucesos se almacenan en la correlación JobEvent. Cada entrada tiene una referencia al trabajo asociado con el suceso. El código para que el escucha haga esto se parece al siguiente ejemplo: JobEventListener.java
package tutorial.fifo;
import com.ibm.websphere.objectgrid.ObjectGridException;
import com.ibm.websphere.objectgrid.ObjectMap;
import com.ibm.websphere.objectgrid.Session;
import com.ibm.websphere.objectgrid.em.EntityManager;
public class JobEventListener
{
boolean stopListening;
public synchronized void stopListening()
{
stopListening = true;
}
synchronized boolean isStopped()
{
return stopListening;
}
public void processJobEvents(Session session)
throws ObjectGridException
{
EntityManager em = session.getEntityManager();
ObjectMap jobEvents = session.getMap("JobEvent");
while(!isStopped())
{
em.getTransaction().begin();
Object jobEventKey = jobEvents.getNextKey(5000);
if(jobEventKey == null)
{
em.getTransaction().rollback();
continue;
}
JobEvent event = (JobEvent)em.find(JobEvent.class, jobEventKey);
// procesar el suceso, aquí sólo se incrementa el
// estado de trabajo
event.job.jobState++;
em.getTransaction().commit();
}
}
}
La aplicación inicia el escucha en una hebra. El escucha se ejecuta hasta que se llama al método stopListening. El método processJobEvents se ejecuta en una hebra hasta que se llama al método stopListening. El bucle bloquea la espera de eventKey de la correlación JobEvent y luego utiliza EntityManager para acceder al objeto de suceso, elimina la referencia al trabajo e incrementa el estado.
La API de EntityManager no tiene un método getNextKey, pero ObjectMap sí lo tiene. Por lo tanto, el código utiliza la ObjectMap para que JobEvent obtenga la clave. Si se utiliza una correlación con entidades, no almacenará más objetos. En su lugar, almacenará tuples; un objeto Tuple para la clave y un objeto Tuple para el valor. El método EntityManager.find acepta un Tuple para la clave.
em.getTransaction().begin();
Job job = em.find(Job.class, "Job Key");
JobEvent event = new JobEvent();
event.id = Random.toString();
event.job = job;
em.persist(event); // insert it
em.getTransaction().commit();
Para buscar el trabajo para el suceso, construya un suceso, haga que apunte al trabajo, insértelo en la correlación JobEvent y confirme la transacción.