Avec WebSphere eXtreme Scale, vous pouvez fournir une fonctionnalité FIFO (premier entré, premier sorti) similaire aux files d'attente pour toutes les mappes. WebSphere eXtreme Scale recherche l'ordre d'insertion de toutes les mappes. Un client peut demander à une mappe sa prochaine entrée déverrouillée, suivant l'ordre d'insertion, et verrouiller cette entrée. Ce processus permet à plusieurs clients d'utiliser les entrées de la mappe de manière efficace.
Session session = ...;
ObjectMap map = session.getMap("xxx");
// cela doit être défini quelque part pour arrêter cette boucle
boolean timeToStop = false;
while(!timeToStop)
{
session.begin();
Object msgKey = map.getNextKey(5000);
if(msgKey == null)
{
// la partition actuelle est épuisée ; appelez-la de nouveau dans
// une nouvelle transaction pour passer à la partition suivante
session.rollback();
continue;
}
Message m = (Message)map.get(msgKey);
// consommez maintenant le message
...
// doit être supprimé
map.remove(msgKey);
session.commit();
}
Pour le mode client, si la machine virtuelle Java est un client, ce dernier se connecte d'abord à un fragment primaire aléatoire de partition. S'il n'existe pas de travaux dans cette partition, le client passe à la partition suivante pour en rechercher. Le client trouve une partition contenant des entrées ou boucle sur la partition initiale aléatoire. Dans ce second cas, il renvoie une valeur null à l'application. Si le client trouve une partition avec une mappe qui contient des entrées, il utilise ces dernières jusqu'à ce qu'aucune entrée ne soit disponible pour le délai d'expiration. Une fois le délai d'expiration dépassé, la valeur null est renvoyée. Cette action signifie que si la valeur null est renvoyée et qu'une mappe partitionnée est utilisée, vous devez démarrer une nouvelle transaction et reprendre l'écoute. L'exemple de fragment de code précédent possède ce comportement.
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;
}
Le travail possède un ID et un état, qui est un entier. Supposons que
vous souhaitez incrémenter l'état chaque fois qu'un événement arrive. Les
événements sont stockés dans la mappe JobEvent. Chaque entrée possède une
référence au travail concerné par l'événement. Le code permettant au
programme d'écoute d'effectuer cette opération ressemble au suivant :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);
// traitez l'événement ; ici nous nous contentons d'incrémenter
// l'état du travail
event.job.jobState++;
em.getTransaction().commit();
}
}
}
Le programme d'écoute est démarré sur une unité d'exécution par l'application. Il est exécuté jusqu'à ce que la méthode stopListening soit appelée. La méthode processJobEvents est exécutée sur l'unité d'exécution jusqu'à ce que la méthode stopListening soit appelée. La boucle se bloque en attendant une clé d'événement de la mappe JobEvent, puis utilise l'API EntityManager pour accéder à l'objet d'événement, supprimer la référence au travail et incrémenter l'état.
L'API EntityManager ne possède pas de méthode getNextKey, contrairement à l'ObjectMap. Par conséquent, le code utilise l'ObjectMap du JobEvent pour extraire la clé. Si une mappe est utilisée avec les entités, elle ne stocke plus d'objets. Elle stocke à la place des nuplets ; un objet nuplet pour la clé et un autre pour la valeur. La méthode EntityManager.find accepte un nupplet pour la clé.
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); // insérez-le
em.getTransaction().commit();
Vous recherchez le travail de
l'événement, construisez un événement, pointez ce dernier vers le travail,
l'insérez dans la mappe JobEvent et validez la transaction.