Lotus Notes / Domino Sonstiges > Java und .NET mit Notes/Domino
Domino ThreadPool über Java Concurrent Framework
sudsaat:
Hallo zusammen,
wie der Titel bereits sagt, bin ich dabei, eine Komponente für Domino-Thread-Pooling zu entwickeln.
Was bietet die Komponente:
- NotesThreadPooling über Concurrent-Framework
- Vorhalten von Session-Objekten für jeden eintreffenden task
- 3 Zugriffsmodi (IIOP, http, local)
- Recycle der Session nach abgearbeitetem Task
- Konfiguration über property-file
- Logging über SLF4J -> Log4J (leicht zu ändern)
- Tasks können Runnable oder Callable sein
- Junit-Tests (siehe oben)
- Ant-Tasks zum Bauen der komponent.jar
- viel debugging-output um das Verhalten von Concurrent nachzuvollziehen
- ShowCase mit zufälliger ABM :-)
Was bietet die Komponente noch nicht:
- Vorhalten weiterer Objekte (db, view, etc.)
- Verarbeitung der Future-Objekte falls Callables verwendet werden
- Exception-Handling (da hoffe ich auf Feedback von euch, um gleich den richtigen Weg einzuschlagen :-)
Warum diese Komponente?
- schnelles Abarbeiten synchroner Requests
- schnellen Zugriff für hochfrequentierte Anwendungen
Voraussetzungen
- mind. Java 5 wegen Concurrent-Framework
- Zugriff auf einen Domino-Server oder -Client (je nach Zugriffsart)
Ich habe aus der Komponente ein Archiv gebaut und eine readme.pdf als Leitfaden zum Einrichten in Eclipse erstellt.
Die Konfiguration der Komponente erfolgt über das property-file "src/java/domino.properties
Die möglichen Konfigurationen sind dort dokumentiert.
Um die Komponente in Projekten zu verwenden, kann ein .jar über ant erstellt werden. Die Property-Dateien sind bewusst nicht bestandteil des .jars und müssen in jeder Entwicklung selbst angelegt werden.
Eine vorgebaute Version befindet sich im /dist Verzeichnis (erstellt mit java 6)
Wie ist die Komponente zu verwenden?
1. Möglichkeit: direkte Implementierung der abstrakten Klassen
1a: Beispiel Runnable:
--- Code: ---NotesThreadPool.getInstance().doSomeNotesWork(new NotesRunnableTask(i) {
@Override
public void runNotes(Session session) {
// use session to do some work
}
});
--- Ende Code ---
1b: Beispiel Callable:
--- Code: ---NotesThreadPool.getInstance().doSomeNotesWork(new NotesCallableTask(i) {
@Override
public Object runNotesAndCallback(Session session) {
// use session to do some work
return "call back";
}
});
--- Ende Code ---
Diese beiden Beispiele sind im ShowCase.java ersichtlich. Der Parameter "i" ist ein Zähler für den ShowCase und wird später entfernt.
2. Möglichkeit: Ableiten der abstrakten Klasse (notwendig, falls weitere Objekte benötigt werden.
Hier ein kleines Beispiel das ich aktuell in einem Workflow teste:
--- Code: ---public class CreateInvoice extends NotesRunnableTask {
private Invoice invoice;
public CreateInvoice(Long workingnumber) {
super(workingnumber);
}
@Override
public void runNotes(Session session) {
// do some work with invoice
}
public void createInvoice(Invoice invoice) {
this.invoice = invoice;
NotesThreadPool.getInstance().doSomeNotesWork(this);
}
}
--- Ende Code ---
Der Parameter workingNumber dient nur für den ShowCase und wird langfristig entfernt. Zum Test kann einfach irgendein Long-Wert (z.B. 0L) übergeben werden.
Der komplette Pool kann über folgendes snippet beendet werden:
--- Code: --- NotesThreadPool.getInstance().shutDown();
--- Ende Code ---
Da ich keinen Domino-Server lokal installiert habe, konnte ich den Zugriff via http noch nicht testen.
Ich freue mich euer Feedback und Vorschläge zur Verbesserung der Komponente :-)
Grüße Thomas :-)
PS: Download befindet sich im Fuß dieses Threads.
Update: Beispielkonfigurationen:
Single-Threaded über eine Session:
domino.threadpool.size=1
domino.threadpool.sessionAchieve=true
Single-Threaded mit jeweils neuer Session:
domino.threadpool.size=1
domino.threadpool.sessionAchieve=false
Multi-Threaded über eine session pro thread für alle tasks:
domino.threadpool.size=50
domino.threadpool.sessionAchieve=true
Multi-Threaded mit jeweils neuer session pro thread für alle tasks:
domino.threadpool.size=50
domino.threadpool.sessionAchieve=false
flaite:
Hi,
--- Zitat ---- Vorhalten weiterer Objekte (db, view, etc.)
--- Ende Zitat ---
Wenn ich mich recht erinnere ist db das teuer zu initialisierende Objekt und nicht session, d.h. es würde Sinn machen, das ebenfalls vorzuhalten. Kann mich allerdings auch täuschen.
Vor Weihnachten werde ich ganz sicher keine Zeit haben, mir das einmal genauer anzusehen. Aber so ist das insbesondere am Jahresende. Danach werd ich das auf jeden Fall einmal zu Gemüte führen.
Danke
atbits:
Ist es nicht sogar so, dass das Session Objekt schon bereits dominoseitig nur einmal pro Thread gehalten wird und nicht jedesmal neu instanziert?
Ich meine das mal so gelesen zu haben.
Und da das so ist muss man meiner Meinung nach auch beim Session.recycle sehr aufpassen, dass man die Session nicht irgendetwas anderem, was in diesem Thread läuft unterm Hintern wegzieht...
Grüße David
sudsaat:
Hi Axel,
freue mich schon auf dein Feedback kommendes Jahr, denke bis dahin wird die Komponente weiter gewachsen sein.
Hallo David,
session-Objekte werden von Domino sogar über mehrere Threads geshared - sofern nicht die Threads eine eigene session initialisieren, daher stimmt deine Einschätzung mit dem session.recycle().
Genau dieser Punkt ist aber im Aspekt der Komponente unwichtig:
Entweder:
- läuft in einem Thread über eine Session nur ein Task und die session bleibt für einen (zeitlichen) Folgetask offen
oder:
- für jeden Task wird eine separate Session initialisiert und wieder recycled.
Dadurch ist die Gefahr, dass ein session.recycle() einen anderen Thread oder Task beeinflusst hinfällig.
Grüße Thomas :-)
atbits:
;D
Offenbar hätt ich mir erstmal den Code anschauen sollen ...
Navigation
[0] Themen-Index
[#] Nächste Seite
Zur normalen Ansicht wechseln