Autor Thema: Mit java eine SessionFactory für Notes implementieren  (Gelesen 13687 mal)

Offline sudsaat

  • Junior Mitglied
  • **
  • Beiträge: 78
Hallo community,

für eine komponentenbasierte Entwicklung bin ich gerade dabei ein technisches Konzept zu erarbeiten. Mitunter ist eine Notes-Komponente, die den Zugriff auf Domino kapselt ein Thema.

Mein Ansatz (denke da liegt mein Fehler) ist folgender:

1. Konfiguration der Komponente über ein property-file

Code
# WeberT: properties for the domino-access component.

# generally set the type of access. Following types are available
#	IIOP	-	using CORBA to access domino-server.
#	local	-	using locally installed notes-client to access domino-server 
domino.access.type=IIOP oder local
domino.access.host=serverIP oder HostName
domino.access.user=vollständiger benutzer
domino.access.password=passwort

2. Eine "generische" Factory entscheidet, welche Factory (Corba oder local) die Komponente verwendet

Code
import java.util.ResourceBundle;

import lotus.domino.Session;

public class GenericDominoFactory {
	
	// WeberT: the name of the property-file
	private static final String DOMINO_FACTORY_RESOURCE_NAME = "dominofactory";
	
	// WeberT: the key to get access-type from property-file
	private static final String DOMINO_ACCESS_TYPE_KEY = "domino.access.type";

	// WeberT: this are the available access-types 
	private static final String DOMINO_ACCESS_IIOP = "IIOP";
	private static final String DOMINO_ACCESS_LOCAL = "LOCAL";

	private static DominoFactory factory;
	
	private GenericDominoFactory() {
		
	}
	
	public static Session getDominoSession() {
		if (factory==null) {
			ResourceBundle resources = ResourceBundle.getBundle(DOMINO_FACTORY_RESOURCE_NAME);
			String accessType = resources.getString(DOMINO_ACCESS_TYPE_KEY);
			if (accessType.equalsIgnoreCase(DOMINO_ACCESS_IIOP)) {
				factory = new RemoteCorbaDominoFactory();
			} else if (accessType.equalsIgnoreCase(DOMINO_ACCESS_LOCAL)) {
				factory = new LocalDominoFactory();
			} else {
				System.out.println("DOMINO: no valid access-type was given, please check " + DOMINO_FACTORY_RESOURCE_NAME + ".properties for key " + DOMINO_ACCESS_TYPE_KEY);
			}
		}		
		return factory!=null ? factory.getDominoSession() : null;
	}
	
}

3. Die beiden konkreten Factories folgen dem Interface "DominoFactory"

Code
import lotus.domino.Session;

public interface DominoFactory {

	public abstract Session getDominoSession();
}

4a. Entweder übernimmt die Corba-Implementierung das Erzeugen einer Session

Code
import java.util.ResourceBundle;

import lotus.domino.NotesException;
import lotus.domino.NotesFactory;
import lotus.domino.Session;

public class RemoteCorbaDominoFactory implements DominoFactory {

	private static final String DOMINO_FACTORY_RESOURCE_NAME = "dominofactory";
	
	private static final String DOMINO_HOST_KEY = "domino.access.host";
	private static final String DOMINO_USER_KEY = "domino.access.user";
	private static final String DOMINO_PASSWORD_KEY = "domino.access.password";
	
	@Override
	public Session getDominoSession() {
		ResourceBundle resources = ResourceBundle.getBundle(DOMINO_FACTORY_RESOURCE_NAME);
		Session session = null;
		
		try {
			session = NotesFactory.createSession(	resources.getString(DOMINO_HOST_KEY), 
													resources.getString(DOMINO_USER_KEY),
													resources.getString(DOMINO_PASSWORD_KEY));
		} catch (NotesException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return session;
	}

}

..anschließend kann ich die session verwenden und muss nur an "recycle" aller erzeugten Objekte und der Session selbst kümmern.

4b. Oder die Local-Implementierung erzeugt die Session

Code
import java.util.ResourceBundle;

import lotus.domino.NotesException;
import lotus.domino.NotesFactory;
import lotus.domino.NotesThread;
import lotus.domino.Session;

public class LocalDominoFactory implements DominoFactory {

	@Override
	public Session getDominoSession() {
		
		NotesThread.sinitThread();
		Session session = null;
		try {
			session = NotesFactory.createSession();
		} catch (NotesException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
//		NotesThread.stermThread();
		
		return session;
	}

}

Neben dem Problem, dass ich eigentlich gerne die Session über die überladene static-Methode NotesFactory.createSession((String)null, user, pwd) erzeugen würde (da bekomme ich user is not a server?!? - dazu habe ich aber einen weiteren Thread hier eröffnet), stehe ich vor der Problematik, wie ich das mit dem stermThread() am besten handhabe.

Wenn ich das bereits in der Implementierung aufrufe, erhalte ich logischerweise später die Meldung:
Object has been removed or recycled

wenn ich es nicht aufrufe, besteht die Gefahr, dass Notes crashed.

Meine Vermutung ist, dass mein Ansatz für Notes nicht praktikabel ist?

Welche Ansätze gibt es, um eine solche Komponente zu entwickeln (einen globalen Thread der die Session aufrecht hält? Einen finally-Block? etc...).

Bin für jeglichen Input dankbar.

Grüße Thomas :-)
« Letzte Änderung: 30.11.10 - 01:16:01 von sudsaat »

Offline Ralf_M_Petter

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.879
  • Geschlecht: Männlich
  • Jeder ist seines eigenen Glückes Schmied
    • Ralf's Blog
Re: Mit java eine SessionFactory für Notes implementieren
« Antwort #1 am: 30.11.10 - 12:47:55 »
Hallo Thomas!

So wie du willst, wirst du das nicht hinbekommen. Das Notesthread.sinitThread und NotesThread.stermThread muss in jedem Thread extra gemacht werden. Das heisst, wenn du dein generiertes Session Objekt in einem anderen Thread verwenden willst, dann muss auch dieser Thread erst initialisiert werden und wieder deinitialisiert werden.

Ich verwende ein anderes Modell das einige Vorteile hat.

Ich habe einen Threadpool generiert, in dem x Threads automatisch für Domino initialisiert und eine Session erstellt werden. Wenn ich nun Code habe der Domino verwendet packe ich den in einen Runnableblock und übergebe in dem Threadpool. Zur Übergabe des RunnableObjekts gibt es eine Methode für Asynchrone Ausführung und auch Warten bis der Block abgeschlossen ist.

Der grosse Vorteil ist, dass in allen Thread die Session immer schon bereit steht und auch zuverlässig von dem Threadpool recycelt wird. Das heisst, wenn ich in einem Runnableblock mal auf das Recyceln vergesse, dann ist nichts verhaut, da die Session am Ende der Ausführung automatisch recycelt wird. Man kann den Threadpool natürlich auch so programmieren, dass er nicht nur das Session Objekt vorhält, sondern auch noch andere Objekte schon voraus generiert, wie Datenbanken oder View Objekte.

Wenn meine Anwendung beendet wird, ruft sie eine Methode des Threadpools auf, die alle Threads ordnungsgemäß beendet.

Grüße

Ralf
Jede Menge Tipps und Tricks zu IT Themen findet Ihr auf meinem Blog  Everything about IT  Eine wahre Schatzkiste sind aber sicher die Beiträge zu meinem Lieblingsthema Tipps und Tricks zu IBM Notes/Domino Schaut doch einfach mal rein.

Offline sudsaat

  • Junior Mitglied
  • **
  • Beiträge: 78
Re: Mit java eine SessionFactory für Notes implementieren
« Antwort #2 am: 30.11.10 - 13:34:55 »
Hallo Ralf,

das habe ich mir schon gedacht das ich irgendwie auf dem Holzweg bin.

Dein Ansatz klingt sehr gut, hast du da eventuell ein code-snippet auf dem ich aufbauen könnte parat? Gerade der Pool mit der asynchronen Ausführung würde mich interessieren.

Vielen Dank.

Grüße Thomas :-)

Offline Ralf_M_Petter

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.879
  • Geschlecht: Männlich
  • Jeder ist seines eigenen Glückes Schmied
    • Ralf's Blog
Re: Mit java eine SessionFactory für Notes implementieren
« Antwort #3 am: 30.11.10 - 14:18:24 »
Kann leider keinen Code posten, da der Code für meinen Arbeitsgeber entwickelt wurde. Ist jetzt etwas zu viel Arbeit es hier nachzuprogrammieren. Ausserdem wenn ich es nocheinmal machen müsste würde ich es mit dem Concurrent Framework probieren, dass ja mittlerweile verfügbar ist.

Für einen ersten Einstieg in das Concurrent Framework von Java lies dir mal http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html#terminated%28%29 durch oder du kaufst dir gleich das Buch  über Concurrency in Java http://www.amazon.de/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601/ref=sr_1_1?ie=UTF8&qid=1291122897&sr=8-1
 

Grüße

Ralf
Jede Menge Tipps und Tricks zu IT Themen findet Ihr auf meinem Blog  Everything about IT  Eine wahre Schatzkiste sind aber sicher die Beiträge zu meinem Lieblingsthema Tipps und Tricks zu IBM Notes/Domino Schaut doch einfach mal rein.

Offline sudsaat

  • Junior Mitglied
  • **
  • Beiträge: 78
Re: Mit java eine SessionFactory für Notes implementieren
« Antwort #4 am: 30.11.10 - 15:11:04 »
Hi Ralf,

das mit dem Code posten ist kein Problem - kann ich nachvollziehen :-)

Das mit dem Concurrent-Framework ist eine gute Idee - auf die bin ich noch gar nicht gekommen.

Werde mich mal daran versuchen, wobei meine Hürde eher Domino als Java ist ;-)

Vielen Dank für dein Feedback, hat sehr geholfen!

Grüße Thomas :-)

Offline flaite

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.966
    • mein del.icio.us
Re: Mit java eine SessionFactory für Notes implementieren
« Antwort #5 am: 30.11.10 - 17:43:54 »
Zitat
gerne die Session über die überladene static-Methode NotesFactory.createSession((String)null, user, pwd) erzeugen würde (da bekomme ich user is not a server?!? - dazu habe ich aber einen weiteren Thread hier eröffnet)
Wenn ich mich recht erinnere kommt der Effekt, wenn du
a) Client und Server auf dem selben Rechner installiert hast.
UND
b) der Server im PATH des OS vor dem Client steht. Im PATH vom Betriebssystem muss der Client vor dem Server erwähnt werden.
Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile

Offline sudsaat

  • Junior Mitglied
  • **
  • Beiträge: 78
Re: Mit java eine SessionFactory für Notes implementieren
« Antwort #6 am: 01.12.10 - 15:50:13 »
Hallo zusammen,

ich brauche nochmal einen kleinen Gedankenanstoß für die Implementierung eines Thread-Pools.

Für das Java Concurrent-Framework habe ich mir einige Testklassen geschrieben, die soweit auch funktionieren:
- eine generische Pool-Factory die entscheidet ob Single-, Fixed- oder Cached-Pooling verwendet wird
- eine Test-Klasse MyNotesThread
- eine NotesThread-Factory für die initialisierung von MyNotesThread
- 2 Interfaces (MyNotesRunnable und MyNotesCallable für Rückmeldungen)

soweit so gut...

Wenn die Factory jetzt einen Thread erzeugt, kann ich dort beispielsweise die Session erzeugen und den Thread vorhalten bis ein "Worker" Arbeit liefert.

Das Concurrent-Framework übernimmt die Initialisieung und Wiederverwendbarkeit der Threads. Die Wiederverwendbarkeit der Threads ist gerade meine Denkblokade :-)

Folgender exemplarischer Code:
Code
ExecutorService executor = Executors.newFixedThreadPool(2, new NotesThreadFactory());

List<Future<Boolean>> list = new ArrayList<Future<Boolean>>();

for (int i = 0; i < 6; i++) {
	Future<Boolean> submit = executor.submit(new NotesCallable() {
		
		private Random generator = new Random();
		
		@Override
		public Boolean call() throws Exception {
			long sleepTime = generator.nextInt( 10000 );
			System.out.println("sleeping for " + sleepTime + " milliseconds");
			Thread.sleep(sleepTime);
			return true;
		}
	});
			
	list.add(submit);
}

erzeugt über die NotesThreadFactory initial 2 Threads der Klasse "MyNotesThread". Der Konstruktur der Klasse übernimmt hier exemplarisch die initialisierung:

Code
public NotesThreadData(Runnable r) {
	super(r);
	try {
		NotesThread.sinitThread();
		session = NotesFactory.createSession();
		System.out.println("Session initialized: " + session.hashCode());
	} catch (NotesException e) {
		e.printStackTrace();
	} 
}

und hält die session vor für die kommenden Worker.

Im obigen Beispiel werden 6 NotesCallable erzeugt, die parallel (immer 2 aktiv) abgearbeitet werden.

Wie schaffe ich es jetzt, dem Thread mitzuteilen nach jedem abgearbeiteten Worker die session zu recyclen, sTermTerm() aufzurufen und sich neu zu initialisieren?

Hab da gerade ne komplette Denkblockade und komme nicht weiter.

Freue mich auf eure Antworten.

PS: Wenn ich einen brauchbaren Stand habe, kann ich ihn auch gerne zum Test zur Verfügung stellen.

Grüße Thomas :-)

Noch was am Rande: Welche Funktionalität bietet die Klasse:
lotus.notes.addins.util.NotesThreadPool;

finde leider nichts brauchbares was diese Klasse betrifft?!?
« Letzte Änderung: 01.12.10 - 16:14:11 von sudsaat »

Offline MadMetzger

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.052
  • Geschlecht: Männlich
  • f.k.a. Alexis Pyromanis
Re: Mit java eine SessionFactory für Notes implementieren
« Antwort #7 am: 01.12.10 - 16:13:50 »
Du könntest unter das Interface direkt eine Abstrakte Implemtierung hängen, die eine Templatemethode (Müsste eines der GoF-Patterns sein) enthält: (Ich glaube, dass es geschickter ist, die Inititialisierung vielleicht nicht im Konstruktor schon zu machen)

Code
public void run() {
initSession()
doWork()
terminateSession()
}

public void initSession() {
// initialisiere NotesSession
}

public terminateSession() {
// terminate NotesSession usw.
}

public abstract doWork()

In der Methode doWork passiert dann die eigentliche Arbeit.

Das Ganze aus dem Bauch heraus, ohne deinen Code im Detail zu kennen.

Offline sudsaat

  • Junior Mitglied
  • **
  • Beiträge: 78
Re: Mit java eine SessionFactory für Notes implementieren
« Antwort #8 am: 01.12.10 - 16:27:32 »
Hallo MadMetzger,

vielen Dank für die schnelle Antwort, aber ich glaube wir reden ein wenig aneinander vorbei :-)

Mein Ziel ist (vereinfacht):
- Einen ThreadPool der x-Threads parallel abarbeitet (mit Concurrent kein Thema)
- Jeder Thread solle zumindest eine session (später auch db, usw.) vorhalten (also bereits initialisiert)
- Somit der Programmcode eines Worker (Runnable oder Callable) direkt ausgeführt werden ohne auf die initialisierung der Notes-Objekte zu warten
- Nachdem der Thread die Arbeit eines Workers beendet hat, soll er die Objekte recyclen und gleich für den nächsten Worker wieder initialisieren

..wenn ich es mit einem GoF-Pattern löse, erfolgt (wie in deinem Beispiel) die Initialisierung erst, wenn ein Worker-Objekt eingeliefert wird, d.h. diese Variante spart zwar Schreibarbeit was die Initialisierung und Terminierung angeht, dauert aber länger, da jeder Worker auf die Initialisierung warten müsste.

Hoffe ich habe es verständlich erklärt.

Hast Du hierzu eine Idee?

Problemstellung kurz zusammengefasst: Wie kann ein wiederverwendbarer Thread für kommende Worker immer eine neue Objekte (z.B. session) vorhalten?

Freue mich auf Feedback.

Grüße Thomas :-)

Offline MadMetzger

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.052
  • Geschlecht: Männlich
  • f.k.a. Alexis Pyromanis
Re: Mit java eine SessionFactory für Notes implementieren
« Antwort #9 am: 01.12.10 - 16:36:36 »
100%ig ist mir dein Modell noch nicht klar, aber natürlich kannst du das recyclen und neu initialisieren auch in der Methode terminateSession() machen. Diese hieße dann vielleicht sinniger recycleAndInitializeNew(). Das Templatemuster ginge dann trotzdem noch, denke ich. Oder ich habe gerade eine falsche Vorstellung von deinem Code. Lösbar ist deine Anforderung sicherlich, muss auch nicht die Templatemethod sein, die kam mir nur reflexartig in den Sinn, weil Teile bei der Abarbeitung immer gleich sind.

Wie sehen denn Pool, Thread und Worker usw ungefähr aus?

Offline sudsaat

  • Junior Mitglied
  • **
  • Beiträge: 78
Re: Mit java eine SessionFactory für Notes implementieren
« Antwort #10 am: 01.12.10 - 17:15:44 »
Ich versuche das ganze an einem "out-of-the-box" beispiel klarzumachen.

Ist stark vereinfact, hoffe es ist alles drin und wird deutlich:

NotesThreadData sieht folgendermaßen aus:
Code
package out.of.the.box;

import lotus.domino.NotesException;
import lotus.domino.NotesFactory;
import lotus.domino.NotesThread;
import lotus.domino.Session;

public class NotesThreadData extends Thread {

	private Session session = null;
	
	public NotesThreadData(Runnable r) {
		super(r);
		try {
			NotesThread.sinitThread();
			session = NotesFactory.createSession();
			System.out.println("Session initialized: " + session.hashCode());
		} catch (NotesException e) {
			e.printStackTrace();
		} 
	}
}

Diese werden von dieser Factory erzeugt:

Code
package out.of.the.box;

import java.util.concurrent.ThreadFactory;

public class NotesThreadFactory implements ThreadFactory {
	
	public Thread newThread(Runnable r) {
		return new NotesThreadData(r);
	}
}

das ganze wird über einen ThreadPool gesteuert:

Code
package out.of.the.box;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class NotesThreadPool {
	
	private static final int NTHREDS = 2;
	
	private ExecutorService executorService = null;
	
	public NotesThreadPool() {
		executorService = Executors.newFixedThreadPool(NTHREDS, new NotesThreadFactory());
	}

	public void doSomeNotesWork(Runnable r) {
		executorService.execute(r);		
	}
	
	public void shutDown() {
		// WeberT: make the executor accept no new threads and finish all existing threads in the queue
		executorService.shutdown();

		// WeberT: wait until all threads are finished
		while (!executorService.isTerminated()) {}

		System.out.println("Finished all threads");		
	}

}

Zum starten was passiert:
Code
package out.of.the.box;

public class Main {
	
	public static void main(String[] args) {
		
		NotesThreadPool pool = new NotesThreadPool();
		
		for (int i = 0; i < 10; i++) {

			pool.doSomeNotesWork(new Runnable() {
				@Override
				public void run() {
					System.out.println("Runnable run");					
				}
			});
		}
		pool.shutDown();		
	}

}

Beim Start werden für beide Threads eine Session initialisiert. Ich möchte, dass dies nach jedem Worker passiert (In diesem Beispiel sind die Worker simple Runnables).

Hoffe es wird deutlich.

Danke für die Unterstützung und verschneite Grüße
Thomas :-)

Offline MadMetzger

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.052
  • Geschlecht: Männlich
  • f.k.a. Alexis Pyromanis
Re: Mit java eine SessionFactory für Notes implementieren
« Antwort #11 am: 01.12.10 - 17:26:51 »
Okay, jetzt wird es ein wenig klarer. Vermutlich macht es Sinn die Methode run(), von der ich meine, dass sie run() auf dem im Konstruktor übergebenen Runnable aufruft, zu überschreiben: (nur eine grobe Skizze/Idee ohne zu probieren)
Code
@Override
public void run() {
    super.run();
    //session recycling and reinit
}

Offline sudsaat

  • Junior Mitglied
  • **
  • Beiträge: 78
Re: Mit java eine SessionFactory für Notes implementieren
« Antwort #12 am: 01.12.10 - 17:50:27 »
Meinst du in etwa sowas:

Code
package out.of.the.box;

import lotus.domino.NotesException;
import lotus.domino.NotesFactory;
import lotus.domino.NotesThread;
import lotus.domino.Session;

public class NotesThreadData extends Thread {

	private Session session = null;
	
	public NotesThreadData(Runnable r) {
		super(r);
		try {
			NotesThread.sinitThread();
			session = NotesFactory.createSession();
			System.out.println("Session initialized: " + session.hashCode());
		} catch (NotesException e) {
			e.printStackTrace();
		} 
	}

	@Override
	public synchronized void start() {
		System.out.println("start was called with session: " + session.hashCode());
		super.start();
	}

	@Override
	public void run() {
		System.out.println("run was called with session: " + session.hashCode());
		super.run();
	}
}

das Problem hierbei ist, dass die run() Methode ebenfalls nur einmal aufgerufen wird, output beim ausführen:

Session initialized: 16112134
start was called with session: 16112134
Session initialized: 18508170
start was called with session: 18508170
run was called with session: 18508170
Runnable run
Runnable run
Runnable run
Runnable run
Runnable run
Runnable run
Runnable run
Runnable run
Runnable run
run was called with session: 16112134
Runnable run
Finished all threads


ne idee?

vielleicht ein eigener ExecutorService implementieren, um die Threads dort zu initialisieren?

Danke und Grüße Thomas :-)

Edit: Ich ziehe mir gerade die Java-Sourcen und schaue mir die Implementierung des ExecutorService an - der könnte dann auch gleich zu beginn n-Threads initial erstellen bevor die ersten Worker vorbeischauen.
« Letzte Änderung: 01.12.10 - 18:12:18 von sudsaat »

Offline Ralf_M_Petter

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.879
  • Geschlecht: Männlich
  • Jeder ist seines eigenen Glückes Schmied
    • Ralf's Blog
Re: Mit java eine SessionFactory für Notes implementieren
« Antwort #13 am: 02.12.10 - 08:02:07 »
Mein Meinung nach musst du einen ThreadPoolExceutor http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html#terminated%28%29 verwenden und dort die Methoden initialize und terminate überschreiben. Diese sind doch für das einrichten und terminieren des Threads zuständig.

Grüße

Ralf
Jede Menge Tipps und Tricks zu IT Themen findet Ihr auf meinem Blog  Everything about IT  Eine wahre Schatzkiste sind aber sicher die Beiträge zu meinem Lieblingsthema Tipps und Tricks zu IBM Notes/Domino Schaut doch einfach mal rein.

Offline MadMetzger

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.052
  • Geschlecht: Männlich
  • f.k.a. Alexis Pyromanis
Re: Mit java eine SessionFactory für Notes implementieren
« Antwort #14 am: 02.12.10 - 08:43:14 »
Ich wusste gar nicht, dass Java schon was in der Art mitbringt, man lernt nie aus. Vermutlich ist das sogar noch sinnvoller, als wenn du das komplett selbst schreibst. Wozu das Rad zweimal erfinden...

Offline Ralf_M_Petter

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.879
  • Geschlecht: Männlich
  • Jeder ist seines eigenen Glückes Schmied
    • Ralf's Blog
Re: Mit java eine SessionFactory für Notes implementieren
« Antwort #15 am: 02.12.10 - 09:15:43 »
Das Concurrent Framework wurde erst mit 1.5 eingeführt. Ich habe selber auch eine eigene Lösung programmiert. Aber wie gesagt richtige nebenläufige Programmierung ist extrem schwierig und deshalb werde ich in Zukunft auch verstärkt auf das Fix und fertig Framework von java setzen.

Ralf
Jede Menge Tipps und Tricks zu IT Themen findet Ihr auf meinem Blog  Everything about IT  Eine wahre Schatzkiste sind aber sicher die Beiträge zu meinem Lieblingsthema Tipps und Tricks zu IBM Notes/Domino Schaut doch einfach mal rein.

Offline flaite

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.966
    • mein del.icio.us
Re: Mit java eine SessionFactory für Notes implementieren
« Antwort #16 am: 02.12.10 - 14:39:57 »
Das mit dem Concurrent Framework zu machen wär vermutlich eine gute Idee. Fragt sich nur, wenn man sowas schreiben soll.

Thomas,

ich mag die Idee eigentlich nicht, solche Connection Objekte mit einer fertigen Session in den Pool zu legen. Dann eher Sessions nicht schliessen und die im Pool zwischenparken.
Das mag ich eigentlich auch nicht.
Ich versuche solche Ressourcen immer möglichst kurz zu halten.
Erst wenn es performance-mässig überhaupt nicht anders geht, würd ich über solche Park-Lösungen überhaupt erst nachdenken.

Eine NotesSession ist für mich sowas wie ein InputStream und den parkt man ja auch nicht initialisiert in irgendwelchen Objekten.

Gruß Axel
Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile

Offline sudsaat

  • Junior Mitglied
  • **
  • Beiträge: 78
Re: Mit java eine SessionFactory für Notes implementieren
« Antwort #17 am: 02.12.10 - 20:26:59 »
Hallo zusammen,

vielen Dank für euer Feedback.

Ich habe heute eine kleine Test-Suite über das Concurrent Framework entwickelt - wer es mal testen möchte, bitte an mich wenden (weiß nicht, ob ich das hier so einfach posten darf?)

@Ralf_M_Peter:
Der beiden Methoden verwendet ThreadPoolExecutor selbst für initialisierung und terminierung (also wenn der Pool gestartet und beendet wird).

@Pitiyankee:
Ich benötige das um einen schnellen Zugriff für synchrone Requests mit Rückmeldung an den "Verursacher" (beispielsweise einen Benutzer) zu gewährleisten. Das erstellen der Session kann u.U. schon mal 2-3 Sekunden benötigen, und die sind in dem vorgesehenen Kontext "sehr teuer". Ich entwickel viele Schnittstellenprogramme zwischen ERP-System, Workflow-Systemen, Archiv-Systemen etc. und dort versuche ich immer einen Pool mit Anmeldungen (was eine Session in Notes im Wesentlichen ja ist) vorzuhalten. Ich sehe also die Session nicht als InputStream sondern eher wie ein Verbindung in einem ConnectionPool für Datenbanken). Der Performance-Faktor ist immens und der Benutzer glücklich, wenn er anstatt ca. 10 Sekunden nur 0,2 Sekunden auf das Ergebnis wartet :-)

Ansonsten gebe ich dir recht, bei nicht zeitkritischen kleinen Anwendungn ergibt das wenig Sinn, da der Overhead (ist die "geparkte" session noch gültig oder serverseitig bereits geschlossen blabla ) alles wegfällt.

Ich bastel noch ein wenig weiter, nächstes Ziel ist die Session generisch über DIIOP, Internet, local etc. zu beziehen und den Thread-Pool über properties zu konifigurieren (großes Ziel ist eine Notes-Komponente für den direkten Einsatz für weitere Entwicklungen zu erstellen).

so long... Thomas :-)

PS: Sollte das in einen neuen Forums-Thread? Hat ja mit dem jetzigen nur noch bedingt zu tun.
« Letzte Änderung: 03.12.10 - 02:15:28 von sudsaat »

Offline sudsaat

  • Junior Mitglied
  • **
  • Beiträge: 78
Re: Mit java eine SessionFactory für Notes implementieren
« Antwort #18 am: 02.12.10 - 20:42:53 »
Update: Generische Factory ist fertig für IIOP und local - jetzt ist der Zeitpunkt mich mit meinem Problem "user is not a server" für internet-sessions zu befassen :-)

Grüße Thomas :-)

------------8<---------(snip)-------------------------------

Edit: den generischen teil werde ich noch ein wenig umstricken...

Kurz was anderes: Ich bekomme ab und an den Fehler:
Notes initialization failure - err 41728

ist bei IBM auch schon durch einen anderen Benutzer gemeldet. Kennt jemand diesen Fehler?

------------8<---------(snip)-------------------------------

Edit: Suche jemanden, der Bock hat, die kleine Komponente zu testen. Mich würde interessieren, ob der Fehler auch bei euch auftritt. JUnit-Testklassen für den Verbindungstest sind vorhanden für:

- GenericSessionFactory (über property konfigurierbar)
- LocalSessionFactory
- RemoteCorbaSessionFactory
- InternetSessionFactory

..eine Test-Suite für alle Tests gemeinsam.

Die InternetSessionFactory wirft aktuell leider den Fehler (user is not a server) bei mir (Notes 8.5.2). Wäre für einen Tester dankbar :-)

Weiter bekomme ich wie gesagt ab und an den Fehler:
Notes initialization failure - err 41728

Wäre auch interessant, wie sich das bei euch verhält?

Grüße Thomas :-)

------------8<---------(snip)-------------------------------

Update: Zwischenstand für potentielle Tester :-)

Die Komponenten ist bisher ein Geflecht aus 16 Klassen und bitet folgende Features:
- NotesThreadPooling über Concurrent-Framework
- 3 Zugriffsmodi (IIOP, http, local)
- Vorhalten einer neuen Session für jeden eintreffenden task
- Recycle der Session nach abgearbeitetem Task
- Konfiguration über property-file
- Junit-Tests (siehe oben)
- Testlauf mit zufälliger ABM :-)

Konfigurierbar sind bisher folgende Optionen:

Code
# access type (IIOP, http, local)
domino.access.type=local

# connection-properties
domino.access.fullAccess=false
domino.access.host=172.30.41.115
domino.access.sslActive=false
domino.access.user=easyxbase easyxbase/comdms
domino.access.password=topS3cr3t
domino.access.inetPassword=topS3cr3t

# Thread-Pool config
#
#	domino.threadpool.size	- set maximal count of workers for incoming tasks
#
domino.threadpool.size=2

Aktuell in Arbeit:
- generische Rückmeldung von Tasks nach getaner Arbeit über "Callable" statt "Runnable"

ich halte euch auf dem laufenden.

Grüße Thomas :-)

------------8<---------(snip)-------------------------------

Update: callables sind nun auch möglich, bin mir aber noch nicht sicher, wie ich mit der Rückmeldung der Future-Objekte umgehe?

Habe mal testweise 10.000 Tasks über den Thread-Pool mit 50 Threads abarbeiten lassen - sieht soweit gut aus.

------------8<---------(snip)-------------------------------

Update: sessionAchieve hinzugefügt. Über properties kann bestimmt werden, ob die worker (threads) eine erstellte session beibehalten oder nach jedem Task recyclen und neu initialisieren.

Die Komponente deckt jetzt folgende Szenarien ab (exemplarisch):

Single-Threaded mit einer 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 mit einer session / thread für alle tasks:
domino.threadpool.size=50
domino.threadpool.sessionAchieve=true

Multi-Threaded mit jeweils neuer session / thread für alle tasks:
domino.threadpool.size=50
domino.threadpool.sessionAchieve=false


Muss mich jetzt anderen Themen widmen. Denke in der kommenden Woche werde ich folgende Themen angehen:
- Fehlerbehandlung über uncheckedExceptions
- Logging (evtl. über SLF4J)

Habe kein Feedback mehr erhalten, daher bin ich mir unsicher, ob das Thema von Interesse ist.

Falls nicht, bitte diesen Thread schließen.

Grüße Thomas :-)
« Letzte Änderung: 04.12.10 - 20:06:09 von sudsaat »

Offline sudsaat

  • Junior Mitglied
  • **
  • Beiträge: 78
Re: Mit java eine SessionFactory für Notes implementieren
« Antwort #19 am: 05.12.10 - 15:03:48 »
Die Komponenten verwendet jetzt SLF4J.

Im Paket wird aktuell Log4J als Logging-Framwework über SLF4J eingesetzt.

Grüße Thomas :-)

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz