Autor Thema: Zugriffe auf Document in parallelen Threads  (Gelesen 3359 mal)

Offline exratt

  • Frischling
  • *
  • Beiträge: 13
Zugriffe auf Document in parallelen Threads
« am: 29.09.06 - 15:52:58 »
Guten Tag allerseits :)

Ich habe mal wieder ein Problem, wenn ich ein wenig mit mehreren Threads herumexperimentiere. Ich greife per DIIOP auf einen Domino-Server zu, lasse mir eine Session geben, suche mir eine Datenbank raus und lass mir zu dieser alle Views in einem Vector geben. In einer Schleife, in der ich durch diesen Vector durchiteriere, starte ich für jeden Durchlauf einen neuen Thread und übergebe die jeweilige View. Dieser Thread soll jetzt einfach nur mal durch alle Documents, die in der View sind, durchgehen und die NoteID ausgeben.

Probleme treten auf, wenn kurz nacheinander zwei Threads auf das selbe Document zugreifen, falls dieses in beiden Views vorhanden ist. Einer der Threads wirft eine NotesException in der Zeile, in der er das nächste Document aus der View holen soll.

Zeile:
Code
nextDoc = view.getNextDocument(thisDoc);
thisDoc und nextDoc sind Documents, view ist (wie überraschend) eine View

Exception:
Code
NotesException: The Document is not in View By _Certifier Name
	at lotus.domino.NotesExceptionHelper.read(Unknown Source)
	at lotus.domino.NotesExceptionHolder._read(Unknown Source)
	at lotus.priv.CORBA.iiop.RepImpl.invoke(Unknown Source)
	at lotus.priv.CORBA.portable.ObjectImpl._invoke(Unknown Source)
	at lotus.domino.corba._IViewStub.getNextDocument(Unknown Source)
	at lotus.domino.cso.View.getNextDocument(Unknown Source)
	at test.ThreadTests$1TestThread.run(ThreadTests.java:69)

Dieser Fehler is insofern etwas merkwürdig, als dass
1. das Document sehr wohl in der View ist,
2. der Fehler nur auftritt, wenn zum selben Zeitpunkt ein anderer Thread auf dieses Document zugreift,
3. jedes Document auch eine eigene C-Reprästentation hat (weil beide in unterschiedlichen Threads sind) und
4. dieses Problem nicht auftritt, wenn ich jedem Thread dieselbe View übergebe, was mich wohl am meisten verwundert.

Was mir auch noch auffällt ist, dass auch Threads, die keine Exception geworfen haben, nicht immer alle Documents auflisten, sondern vorher aufrufen, als wenn der nextDocument-Aufruf null geliefert hätte (was aber nicht sein dürfte).

Kommt mir aber nicht mit Recycling, das habe am Anfang als Übeltäter vermutet und die Dokumente erst ganz zum Schluss recyclet, aber da es sich bei den Documents jeweils um unabhängige Objekte handelt (handeln sollte), hat sich dadurch nichts geändert.

Leider komme ich nicht um Multithreading herum, so dass ich wohl in irgendeiner Art und Weise eine Lösung für dieses Problem brauch, auf welche Weise auch immer das sein mag. Also dann, ich hoffe auf die ein oder andere Meinung oder Anmerkung, vielleicht hab ich ja auch nur mal wieder Tomaten auf den Augen, wer weiß ;)
« Letzte Änderung: 29.09.06 - 16:07:59 von exratt »

Offline flaite

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.966
    • mein del.icio.us
Re: Zugriffe auf Document in parallelen Threads
« Antwort #1 am: 02.10.06 - 09:46:19 »
Gegen konkurrierenden Zugriff schützt du das Dokument-Objekt am einfachsten über synchronized. Das wird in jedem Java Einführungsbuch erklärt. Natürlich mußt du darauf achtgeben, dass du keine Race Conditions, Dead Locks oder verwandtes einbaust.
Wofür brauchst du mehrere Threads?
Das managen von vielen Threads ist ein faszinierenden Thema, vor dem ich in den letzten Jahren klugerweise zurückgeschreckt bin. In den meisten aktuellen Anwendungen braucht man das nämlich gar nicht. Und in J2EE, Swing, SWT/JFace gibts eingebaute Framework die es einfacher machen. Ein Verständnis für Threads ist grundsätzlich immer eine gute Sache. Die Weigerung, selbstgemanageten multithreaded code zu schreiben aber auch (solange man nicht wirklich weiss, was man tut). Erwarte also nicht, dass es einfach ist.
Ich les zur Zeit 2 Bücher: Java Concurrency in Practice von Brian Goetz sowie Essential C# 2.0 by Mark Michaelis. Das C# Buch dient dabei eindeutig der Entspannung.  ;)

Am vielversprechendsten sieht für mich erstmal aus, dass du ein synchronized auf das doc (notes-document) setzt. In Kapitel 22.4 im Handbuch der Javaprogrammierung wird das ziemlich gut erklärt, find ich. (http://www.javabuch.de/)
Code
synchronized (doc) {
ur action
}
Ansonsten hören sich deine (besonders beim 2ten Lesen sehr interessanten Anmerkungen) so an, dass die Probleme etwas mit der internen Implementierung von Notes-RPCs zu tun haben. Notes ist ja bis heute nicht multithreaded. Das System ist eben anders designed. Dokumentiert sind die Probleme aber auch nicht. Vermutlich, weil sehr wenige Leute versuchen, darauf multithreaded zuzugreifen (is auch komplex).

Gruß Axel
« Letzte Änderung: 02.10.06 - 09:48:14 von Axel Janssen »
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 exratt

  • Frischling
  • *
  • Beiträge: 13
Re: Zugriffe auf Document in parallelen Threads
« Antwort #2 am: 02.10.06 - 14:45:08 »
Die Sache mit dem synchronized wird vermutlich nicht funktionieren, da es sich bei den Docs jeweils um eigene Java-Objekte handelt, so dass zumindest auf ein und dasselbe Dokument nur auf C-Basis zugegriffen wird (obwohl laut einem schicken Buch hier für gleiche Dokumente unterschiedliche C-Objekte existieren, wenn sie in verschiedenen Threads erzeugt werden). Ich hab jetzt einfach einen statischen Semaphore eingebaut, so dass nur einer der Threads in der Schleife die enthaltenen Dokumente einer View rausholt (und damit das Multithreading bissl sinnlos wird).

Dann musste ich auch noch feststellen, dass ich Probleme bekomme, wenn ich in einem Thread das Dokument recycle und in einem anderen noch brauche (obwohl wie gesagt laut Buch die beiden Objekte unabhängig sein sollten, da in unterschiedlichen Threads erzeugt). Ist im Moment alles ein wenig doof...

Verzichten kann ich nicht aufs Multi-Threading, da ich nur Praktikant hier bin und ein existierendes Programm dahingehend erweitern soll, dass es auch auf Domino-Datenbanken zugreifen kann. Dafür implementieren meine Klassen ein paar Schnittstellen, über die darauf zugegriffen wird und es kann aber vorkommen, dass mal mehr als ein Thread parallel auf der Datenbank rumwuselt, weshalb ich eben den oben von mir beschriebenen Test-Code gebastelt hab, mit dem die Fehler auftauchen.

Übrigens scheint es mir so, als wenn der Punkt 4 oben hinfällig wäre, denn nachdem ich an einer Stelle mal ein Random-sleep eingebaut habe, gab es auch dort besagte Probleme. Also wohl nicht unbedingt ein Problem mit der Api, aber eines mit meinem Code, denn mir ist noch nicht ganz klar, wann ich die Dokumente recyclen soll :(

Offline flaite

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.966
    • mein del.icio.us
Re: Zugriffe auf Document in parallelen Threads
« Antwort #3 am: 02.10.06 - 15:17:38 »
Verzichten kann ich nicht aufs Multi-Threading, da ich nur Praktikant hier bin und ein existierendes Programm dahingehend erweitern soll, dass es auch auf Domino-Datenbanken zugreifen kann. Dafür implementieren meine Klassen ein paar Schnittstellen, über die darauf zugegriffen wird und es kann aber vorkommen, dass mal mehr als ein Thread parallel auf der Datenbank rumwuselt, weshalb ich eben den oben von mir beschriebenen Test-Code gebastelt hab, mit dem die Fehler auftauchen.
Deine Stellung in der Organisation (Praktikant) beeinflußt das Design der Anwendung, ja führt sogar zu einer komplexeren Design?
Byschen Paradox, oder?   ;D

Nach all diesen Dingen, die du erzählst, würde ich das mit dem multithreaded sein lassen und das an entsprechender Stelle bekanntgeben. Für konkurrierenden Zugriff mehrerer Anwendungen auf einen Backend-Dienst gilt die allgemeine Regel, dass man Verbindungen (bei Notes:lotus.domino.Session) immer nur möglichst kurz offenhalten sollte.
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 exratt

  • Frischling
  • *
  • Beiträge: 13
Re: Zugriffe auf Document in parallelen Threads
« Antwort #4 am: 02.10.06 - 16:36:18 »
Hm. Meine Formulierung ist offenbar nicht allzu günstig gewählt... Die Anwendung läuft multithreaded, unabhängig davon, was ich mache. Das ist schon so und wird auch nicht mal eben geändert, ich selber muss nur damit leben.

Da ich ein Objekt habe, von dem ich meistens die Domino-Objekte beziehe, synchronisiere ich jetzt eben immer über dieses, wenn ich wie auch immer Daten aus der Datenbank ziehen will (auch, wenn ich nicht über das Objekt gehe, wie z.b. beim holen aller Views einer Datenbank, da ich das nicht so regeln kann). Damit wird in meinem Fall wohl nicht mehr allzu viel von der Parallelität übrig bleiben, aber hauptsache, es entstehen erstmal keine Fehler.

Im übrigen würde ich eine Session auch nur kurz offen halten, aber es dauert doch einige Zeit, alles aus der Datenbank zu holen und anschließend gleich zu verarbeiten (Attachements per InputStream holen und eventuell vorhandenen Text parsen etc. dauert bei allen Attachements aller Datenbanken unter Umständen recht lang). In nächster Zeit sollte ich mir mal Gedanken darüber machen, was passiert, wenn ein Session-Timeout auftritt... Bisher ist das nicht passiert, aber das wird sicher noch kommen.

Offline flaite

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.966
    • mein del.icio.us
Re: Zugriffe auf Document in parallelen Threads
« Antwort #5 am: 02.10.06 - 17:03:58 »
Wenn es noch um das selbe Design wir hier geht, dann führt einfach das Design zu Connections, die zu schwer zu managen sind:

http://atnotes.de/index.php?topic=32458.0

Ich predige seit 5 Jahren:
1. xml nur, wenn es wirklich Vorteile bringt und nicht weil sich die buzzwords so doll anhören.
2. connections dürfen nicht zu langlebig sein oder man weiss wirklich was man tut und das ist schwierig.
3. EJBs sind kein Quatsch (mit der Version 3.0 erhalte ich vielleicht sogar Recht)
4. Eigene Frameworks zu bauen ist schwierig.

Vor allem mit 1 und 2 habe ich mir kurzfristig gar nicht so wenig Feinde geschaffen und einiges an triumphierenden Grinsen geerntet ("Naaatüüürliiiich geht das"). Im Nachhinein haben die lieben Kollegen dann aber oft gemerkt, dass es cross-country oft ziemlich rauh zugeht. Gerade mit Domino.
Kannst du vielleicht das ganze stateless machen? D.h. Du versuchst irgendwie keine Session und sonstigen Objekte über einen Request-Response Zyklus zu halten?
Natürlich ist das "schlecht für die Performance". Aber du bewegst dich in Bereiche, in denen es schwer wird mit gegebenen Ressourcen, eine stabile Anwendung hinzubekommen. Und das ist das eindeutig größere Problem.

Gruß Axel
« Letzte Änderung: 02.10.06 - 17:09:12 von Axel Janssen »
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 exratt

  • Frischling
  • *
  • Beiträge: 13
Re: Zugriffe auf Document in parallelen Threads
« Antwort #6 am: 05.10.06 - 08:57:56 »
Also es geht hier nicht um das Programm, das ich in dem anderen Thread angesprochen habe. Das war nur ein Versuch, mich mit der API ein wenig vertraut zu machen und rumzuprobieren.

Was genau kann eigentlich passieren, wenn eine Session "zu langlebig" ist? Oder ist das schlimme daran, dass man gar nicht genau sagen kann, was dann passiert? Zumindest im Server-Dokument gibt es für DIIOP nur eine einstellbare "Idle Timeout", die in meinem Fall besagt, dass die Session nach 60 Minuten nichts tun verworfen wird, aber kein allgemeines Timeout, das auch dann in Kraft tritt, wenn noch Verkehr im Netz ist. Also zumindest macht einen diese Einstellmöglichkeit glauben, dass eine lang geöffnete Session etwas stinknormales ist, was keine Probleme aufwirft...

Offline flaite

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.966
    • mein del.icio.us
Re: Zugriffe auf Document in parallelen Threads
« Antwort #7 am: 05.10.06 - 09:44:55 »
Was genau kann eigentlich passieren, wenn eine Session "zu langlebig" ist?
1. Sessions sind ein knappes Gut. Du kannst nicht unendlich viele davon benutzen. Dies schränkt die Skallierbarkeit des Systems ein.
2. Ich würde mich niemals auf ein automatisches Timeout verlassen. Gerade im Zusammenspiel mit JNI führt das zu Problemen (und Domino beruht darauf). Selbst wenn die Session irgendwie von Notes beendet wird, werden möglicherweise nicht alle Ressourcen freigesetzt. Java (und .NET) setzen hier auf automatische Garbage Collection und die funktionieren (aus allgemeinen Performance-Gesichtspunkten) komplizierter als viele Leute glauben. Sprich: Die Connection wird vielleicht gar nicht geschlossen, auch wenn du es glaubst.

Ich würd immer mit einem System anfangen, dass eine Session mit einem externen Programm eindeutig innerhalb eines durch den Anwender (oder ein automatatisch geschedulten) initiierten Request/Response Zyklus hält. Erst wenn das unter Performance-Gesichtspunkten nicht geht, mach ich was anderes. Vor dem anderen habe ich aber Respekt und verlasse mich nicht auf irgendwelche Automatismen. 


Oder ist das schlimme daran, dass man gar nicht genau sagen kann, was dann passiert? Zumindest im Server-Dokument gibt es für DIIOP nur eine einstellbare "Idle Timeout", die in meinem Fall besagt, dass die Session nach 60 Minuten nichts tun verworfen wird, aber kein allgemeines Timeout, das auch dann in Kraft tritt, wenn noch Verkehr im Netz ist. Also zumindest macht einen diese Einstellmöglichkeit glauben, dass eine lang geöffnete Session etwas stinknormales ist, was keine Probleme aufwirft...
In der realen Welt nicht.
Wie gesagt. Es gibt diese Garbage Collection Probleme.
Die Garbage Collection Mechanismen sind (in .NET und Java) so, dass kleine Objekte aus Optimierungsgründen bei Garbage Collector Läufen nicht berücksichtigt werden, obwohl sie eligible for garbage collection sind. Objekte, die bereits bei einem Lauf übersehen wurden, werden beim nächsten Lauf auch aus Optimierungsgründen oft nicht berücksichtigt. D.h. die Session wird in Wirklichkeit gar nicht geschlossen.

In dem DIIOP Prozess des Domino Servers sind die Anzahl der Sessions beschränkt. Wenn du ein paar ungenutzt herumschwirren läßt, vermindert das die Skallierbarkeit des Systems.
« Letzte Änderung: 05.10.06 - 09:49:31 von Axel Janssen »
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

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz