Das Notes Forum

Lotus Notes / Domino Sonstiges => Java und .NET mit Notes/Domino => Thema gestartet von: sudsaat am 07.12.10 - 12:42:46

Titel: Domino ThreadPool über Java Concurrent Framework
Beitrag von: sudsaat am 07.12.10 - 12:42:46
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
	}
});

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";
	}
});

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);
	}
	
}

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();

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
Titel: Re: Domino ThreadPool über Java Concurrent Framework
Beitrag von: flaite am 07.12.10 - 14:15:21
Hi,

Zitat
- Vorhalten weiterer Objekte (db, view, etc.)
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
Titel: Re: Domino ThreadPool über Java Concurrent Framework
Beitrag von: atbits am 07.12.10 - 14:21:51
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
Titel: Re: Domino ThreadPool über Java Concurrent Framework
Beitrag von: sudsaat am 07.12.10 - 15:47:41
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 :-)
Titel: Re: Domino ThreadPool über Java Concurrent Framework
Beitrag von: atbits am 07.12.10 - 15:51:05
 ;D
Offenbar hätt ich mir erstmal den Code anschauen sollen ...
Titel: Re: Domino ThreadPool über Java Concurrent Framework
Beitrag von: sudsaat am 08.12.10 - 13:24:12
Hi David,

kein Problem, ich bin für jegliche Anregungen dankbar, da kann man auch gerne mal daneben liegen  ;)

Ich denke ich werde mich heute abend/nacht ein wenig mit der Komponente beschäftigen, Ziel für heute ist:

- vorhalten von datenbank-objekten
- workingnumber entfernen und thread-namen einführen
- evtl. ein wenig exception-handling

Ich halte euch auf dem laufenden.

Grüße Thomas :-)

Update: Habs leider noch nicht geschafft, da eine andere Entwicklung höhere Prio bekommen hat. Ist aber noch in der Pipe :-)