alles klar dann versuche ich mal mehr da zu posten
ja da herrscht Chaos weil ich alles X mal umbauen musste weil nichts so lief wie ich es wollte
erst den Watchdog starten
→ watchdogserver.Watchdog
dann den AlarmServer starten
→ alarmserver.AlarmServer
Dann hast du den normalen Betrieb erreicht, killst du jetzt den Alarmserver kommt nach paar Sekunden beim Watchdog ne Exception, da der Alarmserver ja nicht mehr vorhanden ist (die ist vollkommen ok).
Startest du jetzt den Alarmserver wieder, hing sich im Original der SIMON Teil im Watchdog auf, hier in dem kleinen Beispiel wirft er weiter Exceptions als wäre der Alarmserver nicht da.
Ziel wäre es das er merkt „oh der ist ja wieder da, ich kann wieder mit ihm reden“
Ach ja. Sehe gerade deine “ping” Methode.
SIMON verwendet intern scho ein eigenes PING um zu erkennen wann der gegenüber “abraucht”. Darauf hin wird auch von der “unreferenced()” Methode gebrauch gemacht.
Verstehe also gerade nicht so den “Sinn” hinter deiner offensichtlich komplexen Implementierung.
Wäre hilfreich wenn du mal ein paar UseCases und Requirements aufstellst was das Ding machen soll.
- Alex
Mein Ping ist einfach nur dafür da, damit ich weiß ob er noch da ist. Weil raucht der Server ab ohne das ich ne Methode von ihm aufrufe wird mir Simon das ja nicht mitteilen oder?
Wie schon weiter vorn geschrieben war das mit den zwei Registrys weil ich die Callback-Sache nicht wusste/vergessen hab. Mittlerweile hab ich es so umgebaut und das scheint auf den ersten Blick auch besser zu laufen.
Mein Hauptproblem hier war einfach nur das sich SIMON nicht neu verbunden hat, bzw. sich aufgehängt hatte.
Mein Ping ist einfach nur dafür da, damit ich weiß ob er noch da ist. Weil raucht der Server ab ohne das ich ne Methode von ihm aufrufe wird mir Simon das ja nicht mitteilen oder?
Da hast du recht. Da „fehlt“ noch was. Hab dazu gleich ein Issue aufgemacht:
http://root1.de/mantis/view.php?id=27
Wie schon weiter vorn geschrieben war das mit den zwei Registrys weil ich die Callback-Sache nicht wusste/vergessen hab. Mittlerweile hab ich es so umgebaut und das scheint auf den ersten Blick auch besser zu laufen.
Prima.
Mein Hauptproblem hier war einfach nur das sich SIMON nicht neu verbunden hat, bzw. sich aufgehängt hatte.
Bezieht sich das war darauf, dass der Fehler jetzt nicht mehr auftaucht? Da ich ja hier und da änderungen gemacht habe, könnte das heissen dass das Issue mit einem „fixed“ geschlossen werden kann?!
Gruß
Alex
[QUOTE=tuxedo]
Mein Hauptproblem hier war einfach nur das sich SIMON nicht neu verbunden hat, bzw. sich aufgehängt hatte.
Bezieht sich das war darauf, dass der Fehler jetzt nicht mehr auftaucht? Da ich ja hier und da änderungen gemacht habe, könnte das heissen dass das Issue mit einem „fixed“ geschlossen werden kann?!
Gruß
Alex[/QUOTE]
Naja ich hab ja jetzt alles mit Callback gemacht, daher ist der Ablauf ja anders. Das Testprogramm muckt aber immer noch so rum (Watchdog schmeißt Exceptions und verbindet sich nicht neu zum Alarmserver)
Miniinfo „INFO: Simon lib loaded [version=@SIMON_VERSION@|rev=@SIMON_BUILD_REVISION@|timestamp=@SIMON_BUILD_TIMESTAMP@]“
da passt wohl was noch nicht ganz
Miniinfo „INFO: Simon lib loaded [version=@SIMON_VERSION@|rev=@SIMON_BUILD_REVISION@ |timestamp=@SIMON_BUILD_TIMESTAMP@]“
da passt wohl was noch nicht ganz
Das ist korrekt so. Du verwendest den Sourcecode und keine fertig gebaute Lib. Wenn du SIMON mit der beiliegenden build.xml baust, werden die Codestellen mit den entsprechenden Werten gefüllt.
- Alex
aachso alles klar wieder etwas schlauer
So, hab issue#22 auch erledigt. Die Globale Registry ist jetzt Schnee von gestern. Grund: Konsistenz. Wenn man noch “globalen” Zugriff auf die Registry für’s bind()/unbind() braucht, kann man sich ohne weiteres selbst zwei statische Methoden basteln.
Ein weiterer Grund war/ist das anstehende “server finden” und “serverstatistik” feature, welches unnötig kompliziert wird wenn man mit zweierlei registry-arten herumhantiert.
- Alex
Da du ja da drüben so schnell bist mitm Schließen und man nix mehr dazu schreiben kann, hab ich hier für dich nochmal das Testprogramm etwas verschlankt und an deine neuen Klassen angepasst. Du kannst ja mal sehen ob du das irgendwie hinbekommst.
Alles klar, ich versuchs.
Kleiner Tipp:
Sowohl Server als auch Client können benachrichtigt werden, wenn die Verbindung verloren geht.
Schau dir dazu am besten mal die sources im SVN zu
simon_testclient
simon_testserver
simon_testshared
an. Das sind drei einzelne Eclipse-Projekte die sich gegenseitig im Buildpath ergänzen. Sollte dir im übrigen auch als Style-Guide und erster Anhaltspunkt wie man SIMON anwendungen bastelt dienen. Versuche die immer auf dem laufenden zu halten was den Funktionsumfang betrifft.
Die “unreferenced()” Technik ist für das wa sdu vor hast wie geschaffen. Was man aber in “unreferenced()” nicht tun sollte, ist nochmals irgendwelche Remote Methodenaufrufe zu tätigen. Weil die schlagen ja gezwungener maßen fehl.
- Alex
erst den Watchdog starten
→ watchdogserver.Watchdogdann den AlarmServer starten
→ alarmserver.AlarmServerDann hast du den normalen Betrieb erreicht, killst du jetzt den Alarmserver kommt nach paar Sekunden beim Watchdog ne Exception, da der Alarmserver ja nicht mehr vorhanden ist (die ist vollkommen ok).
Startest du jetzt den Alarmserver wieder, hing sich im Original der SIMON Teil im Watchdog auf, hier in dem kleinen Beispiel wirft er weiter Exceptions als wäre der Alarmserver nicht da.Ziel wäre es das er merkt „oh der ist ja wieder da, ich kann wieder mit ihm reden“
So, hab mir das nochmal mit deinem neusten Testcode angesehen.
Ich bin allerdings immer noch etwas verwirrt, unter anderem wegen den Namen.
Watchdogserver ← Klarer Fall, ein Server.
Alarmserver ← ?? Nochmal ein Server? Warum verbindet sich ein Server mit einem Server? Wer verbindet sich denn mit dem Alarmserver?
Ich versuchs mal zu erraten und Requirements, sowie UseCases daraus zu stricken:
Req1) Eine Farm von Alarmserver soll auf Ausfälle kontrolliert werden. Hierfür wird ein sogenannter Watchdogserver eingeführt, welcher für alle Alarmserver zentrale Anlaufstelle ist: Alle Alarmserver melden sich regelmäßig beim Watchdogserver und geben bescheid dass sie noch leben
UseCase1) Ein Alarmserver fällt aus: Ein ausgefallener Alarmserver soll vom Watchdogserver erkannt werden, der darauf hin festgelegte Schritte einleitet
UseCase2) Der Watchdogserver fällt aus: Ein Alarmserver soll das Ausfallen des Watchdogservers erkennen, und in regelmäßigen Abständen versuchen die Verbindung wiederher zu stellen.
Ergänzung zu UseCase2) Was die Alarmserver tun, währen der Watchdogserver nicht da ist, ist noch offen und muss geklärt werden (aber tut hier evtl nichts zur Sache).
Sofern das korrekt ist, gehen wir jetzt an die Problemlösung ran.
Der Alarmserver übergibt beim „login“ am Watchdogserverein Client-Callback-Objekt. Als Antwort erhält er ein Server-Callback-Objekt.
Beide Callback-Objekte enthalten die „unreferenced()“ Methode, welche dem SimonUnreferenced Interface zu entnehmen ist.
Abgedeckt ist damit UseCase 1 als auch 2:
-
Ein Alarmserver fällt aus: Für jeden Client wurde ein Server-Callback-Objekt erzeugt. Fällt nun ein CLient aus, wird bei diesem speziellen Server-Callback-Objekt die unreferenced() Method ausgeführt, mit welcher man die in UC1 erwähnten Aktionen ausführen kann.
-
Geht der WatchdogServer flöten, wird bei den AlarmServern die unreferenced-Methode im Client-Callback-Objekt ausgelöst. Darüber lässt sich ein reconnect-Versuch triggern.
Dein letzter Sample-Code sieht soweit korrekt aus:
Startet man den WatchdogServer und darauf den AlarmServer läuft alles prima. Geht der Alarmserver nun flöten, wird es etwas „seltsam“:
Der Ping, der vom Watchdogserver ausgeht, wird über eine hin zum Alarmserver frisch weitere Verbindung gehandhabt. Wieso eine neue Verbindung? Wenn der Alarmserver dem Server ein Callback-Objekt gibt, kann der WatchdogServer damit eine Methode am Alarmserver aufrufen. Ein neues Lookup ist leider totaler quatsch, zumal die Verbindung auch nicht wieder aufgeräumt wird (Stichwort: „Simon.release()“).
Hast du dir schonmal das oben genannte Beispielprojekt angesehen und versuchtzu verstehen wie das mit den Callbacks und dem unreferenced() funktioniert? Wenn nein wirds höchste Zeit
Nebenbei: Der Code von dir funktioniert so wie’s von SIMON gedacht ist:
Watchdogserver startet, Alarmserver verbindet sich, Watchdogserver holt sich alle 10sek ein Objekt vom Alarmserver und ruft damit ping auf.
Geht der Alarmserver nun verloren, kommt im 10sek. Rhythmus eine Exception von wegen: Kann die Verbindung zum Alarmserver nicht aufbauen (völlig logisch, der ist ja gerade offline). Geht der Alarmserver nun wieder online, hören die Exceptions am WatchdogServer wie erwartet wieder auf.
Aber wie gesagt, das ist „tonnenweise“ Code, der nicht eingfach zu durschauen ist (bezogen auf die Nicht-Verwendung von Callbacks) und der nicht mehr Features bietet, als Simon von Haus aus schon mitbringt.
Mal sehen ob ich dir schnell einen Watchdog-Alarmserver-Konstrukt basteln kann…
- Alex
Wie ich schon geschrieben hab, so war es vorher bevor ich die Callback Sachen „entdeckt“ hab
Mittlerweile hab ich überall Callback drin und auf den ersten Blick (kaum Tests bisher) läufts auch gut.
Der Alarmserver heißt Alarmserver weiß er Alarme verschickt (was für eine Überraschung :D) aber diese Alarme haben nichts mit dem Watchdog zu tun sondern gehören zu einem anderen System hier. Neben dem Alarmserver gibt es noch einige andere Server. Wie anfangs schonmal gesagt ist der Watchdog zur Überwachung der Systeme da und mach auch noch paar weitere Sachen.
Die unreferenced-Methode verwende ich bisher nicht (wird sich wohl auch nicht ändern) weil ich denen nicht traue. Der Alarmserver wurde bis letzte Woche per RMI von einem anderen System angesprochen. Aber dann ist es mal aufgetreten das die RMI Verbindung tot war aber die RMI Umgebung hat das garnicht bemerkt und immer fleißig behauptet „Ja die Gegenstelle ist da, Daten sind angekommen“ bzw. „Ping? Ja klar geht hier hast du das true für die Quitung“ aber über mehrere Stunden. Ich hab das noch nie bei RMI erlebt aber deshalb versuche ich jetzt soviel wie möglich weit ab von RMI/SIMON und so zu lösen.
Das ist komisch, genau das passiert bei mir nicht. Da gehen die weiter bzw. er hatte sich aufgehängt.
Wie ich schon geschrieben hab, so war es vorher bevor ich die Callback Sachen „entdeckt“ hab
Mittlerweile hab ich überall Callback drin und auf den ersten Blick (kaum Tests bisher) läufts auch gut.
Na und warum hab ich mir dann deine „nicht callback“ Lösung angesehen?
Die unreferenced-Methode verwende ich bisher nicht (wird sich wohl auch nicht ändern) weil ich denen nicht traue.
Du weißt aber schon dass da etwas anderes als bei RMI dahinter steckt?
Die Methodik bei Simon macht absolut das gleiche was du fabrizierst: Es wird in regelmäßigen abständen mittels eines (bzw. beim Server megrerer Threads)(->einstellbar) ein Paket hingeschickt und auf eine Antwort gewartet. Trifft das Paket auf eine unterbrochene Leitung, wird die unreferenced() Methode aufgerufen. Mehr ist es nicht. Wenn du dem nicht traust, ganz ehrlich, dann solltest du SIMON auch nicht trauen.
Simon ist gänzlich was anderes als RMI. Allein schon deswegen, weil keine Streamverbindung genutzt wird und alles auf NIO (non-blocking multiplexed IO) statt IO (standard, non-multiplexed blocking IO) basiert.
Wenn du mit „JConsole“ (im bin-Ordner eines jeden JDKs) mal auf den Client oder Server drauf schaust und bei den Threads nachsiehst, wirst du den DGC und Ping-Worker entdecken. Genau die sind für unreferenced zuständig. Ohne die hättest du auch schnell ein Speicherleck weil „alte“ Callbackobjekte etc gar nicht abgeräumt würden und der Server, sowie der Client, irgendwann in eine „OutOfMemory“ Exception geraten würden.
Ergo kann man schlussfolgern: Traut man Simon „unreferenced()“ nicht, so scheint es einem wurscht zu sein ob die Anwendung irgend wann an einer OutOfMemory stirbt.
- Alex
Ich hab dir meine mit Callback nicht gegeben weil die bei mir läuft im Gegensatz zu der Lösung da oben
Ja aber in wie weit bekommt der Watchdog mit das einer seiner Clients (zb der Alarmserver) nicht mehr da ist und vor allem welcher?
Wenn du in das Beispielprojekt geschaut hättest, wüttest du das. Das Zauberwort heisst “Sessionpattern”. Macht man bei RMI genau so. Hat aber wieder nix mit Simon direkt zu tun. Ist ja ein “Pattern”.
- Alex
Ja ich hab mir das angesehen, hat ne weile gedauert bis ich das Session Objekt im Code gesehen hab
Ich werd mal sehen ob ich das später einbaue, erstmal bleibt es so wie es ist.
So, ich war mal so frei und hab das mal eben schnell zusammengecodet, mit unreferenced, und mit callbacks und mit session-objekt.
Einfach entpacken und als Projekt in deinen Eclipse-Workspace laden.
- Alex
Oh cool danke, werd ich mir morgen ansehen. Aber ich steh schon vor dem nächsten Problem, bei einer bestimmten Methode hängt er sobald er diese aufruft. Jede andere geht nur die nicht.
Aber das werd ich mir morgen wieder ansehen jetzt ist Feierabend
Hab gerade gesehen dass es zu “händern” kommen kann, wenn man vergessen hat das Remoteinterface von “SimonRemote” abzuleiten. Im Logging sieht man’s dann dass man da was falsch gemacht hat. Musst du ggf. mal mit dem neuen build heute nach ausprobieren.
- Alex