Mit WebSphere eXtreme Scale können Sie eine Funktion für alle Maps bereitstellen, die einer FIFO-Warteschlange (First In/First Out) gleicht. WebSphere eXtreme Scale überwacht die Einfügereihenfolge für alle Maps. Ein Client kann eine Map nach dem nächsten nicht gesperrten Eintrag in der Einfügereihenfolge abfragen und den Eintrag sperren. Dieser Prozess ermöglicht mehreren Clients, Einträge effizient aus der Map zu konsumieren.
Session session = ...;
ObjectMap map = session.getMap("xxx");
// Zum Stoppen der Schleife muss folgende Zeile irgendwo definiert werden.
boolean timeToStop = false;
while(!timeToStop)
{
session.begin();
Object msgKey = map.getNextKey(5000);
if(msgKey == null)
{
// Aktuelle Partition ist abgearbeitet. Erneut in einer neuen
// Transaktion aufrufen, um mit der nächsten Partition fortzufahren.
session.rollback();
continue;
}
Message m = (Message)map.get(msgKey);
// Jetzt die Nachricht konsumieren.
...
// Eintrag entfernen
map.remove(msgKey);
session.commit();
}
Wenn die Java Virtual Machine (JVM) ein Client ist, stellt der Client zunächst eine Verbindung zu einem zufällig ausgewählten primären Shard der Partition her. Wenn keine Arbeit in dieser Partition vorhanden ist, sucht der Client in der nächsten Partition nach Arbeit. Entweder findet der Client eine Partition mit Einträgen, oder er kehrt wieder zur ersten zufällig ausgewählten Partition zurück. Wenn der Client wieder zur ersten Partition zurückkehrt, gibt er einen Nullwert an die Anwendung zurück. Findet der Client eine Map, die Einträge enthält, konsumiert er bis zum Ablauf des Zeitlimits Einträge aus dieser Map, bis keine Einträge mehr verfügbar sind. Nach Ablauf des Zeitlimits wird null zurückgegeben. Wenn null zurückgegeben und eine partitionierte Map verwendet wird, bedeutet dies, dass Sie eine neue Transaktion starten und den Empfangsvorgang fortsetzen müssen. Das vorherige Codebeispielfragment hat dieses Verhalten.
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;
}
Der Job hat eine ID und einen Status (eine ganze Zahl). Angenommen, Sie möchten
den Statuswert um jeweils eins erhöhen, wenn ein Ereignis eintritt.
Die Ereignisse werden in der Map "JobEvent" gespeichert. Jeder Eintrag hat eine Referenz auf
den Job, den das Ereignis betrifft.
Der Code für den entsprechenden Listener gleicht dem folgenden Beispiel:
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);
// Ereignis verarbeiten. Hier wird nur der Jobstatus erhöht.
event.job.jobState++;
em.getTransaction().commit(); }
}
}
Der Listener wird von der Anwendung in einem Thread gestartet. Der Listener wird ausgeführt, bis die Methode "stopListening" aufgerufen wird. Die Methode "processJobEvents" wird im Thread ausgeführt, bis die Methode "stopListening" aufgerufen wird. Die Schleife blockiert beim Warten auf ein eventKey-Objekt aus der Map "JobEvent" und verwendet dann den EntityManager, um auf das Ereignisobjekt zuzugreifen, den Job zu dereferenzieren und den Status zu erhöhen.
Die API "EntityManager" hat keine Methode "getNextKey", wohl aber die API "ObjectMap". Deshalb verwendet der Code die API "ObjectMap" für JobEvent, um den Schlüssel abzurufen. Wenn eine Map mit Entitäten verwendet wird, werden keine Objekte mehr gespeichert. Stattdessen werden Tupel gespeichert: Ein Tupelobjekt für den Schlüssel und ein Tupelobjekt für den Wert. Die Methode "EntityManager.find" akzeptiert ein Tupel für den Schlüssel.
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); // Einfügen
em.getTransaction().commit();
Sie finden den Job für das Ereignis, erstellen
ein Ereignis, zeigen auf den Job, fügen ihn in die Map "JobEvent" ein und schreiben dann die Transaktion fest.