# RMI Server Factory



## Tallan (28. Okt 2009)

Hallo zusammen,

ist es möglich das jeder Client vom Server ein eigenes Objekt bzw einen eigenen Thread der Server-RMI-Methoden bekommt?

Die Idee wäre das Client x auf einem bestimmten Thread des Servers der alle RMI Funktionen realisiert Arbeitet und Client y wiederrum seinen eigenen Thread auf dem Server hat. Wichtig wäre dabei das der Server selbst nur einen Port hat und nicht für jeden Thread einen neuen belegt.


Quasi eine Art RMI-Methoden-Factory die Threads der Serverfunktionen realisiert.

Hat jemand da eine Idee ob das umsetzbar ist?


----------



## tuxedo (28. Okt 2009)

Wo ist das Problem ... Du kannst doch hinter jede Servermethode einen Thread schnallen und mit der Servermethode nur den Thread entsprechend triggern?!

- Alex


----------



## Tallan (28. Okt 2009)

so hab ich es z.z die rmi methode auf dem server startet nur einen thread der entsprechendes bearbeitet.
Da es aber auch Methoden gibt die Daten aufbereiten und diese dann an den client zurückgeben wird das schon etwas schwieriger da der thread ja keinen return haben kann( oder irre ich mich da ).
Daher die idee jedem client einen eigenen "ServerInterfaceThread" zu übergeben den er dann anspricht


----------



## tuxedo (28. Okt 2009)

?? Du verkomplizierst da was...

Wenn der Client dem Server etwas zum rechnen gibt (oder eine Methode aufruft die asynchron im Server weiter laufen soll), dann kann und darf die Methode sofort terminieren. Die "Aufgabe" wird dann einem Thread (oder besser einem Pool) übergeben. Sobald der das Ergebnis hat meldet der sich via Callback beim Client. So einfach ist das.

Aber vielleicht wird's deutlicher wenn du ein passendes Szenario schilderst. Dann weiß man wenigstens was du vorhast und kann entsprechdn Ratschläge geben.

- Alex


----------



## Tallan (28. Okt 2009)

tuxedo hat gesagt.:


> ?? Du verkomplizierst da was...
> 
> Wenn der Client dem Server etwas zum rechnen gibt (oder eine Methode aufruft die asynchron im Server weiter laufen soll), dann kann und darf die Methode sofort terminieren. Die "Aufgabe" wird dann einem Thread (oder besser einem Pool) übergeben. Sobald der das Ergebnis hat meldet der sich via Callback beim Client. So einfach ist das.
> 
> ...



hm.. vielleicht drück ich mich falsch aus, so wie von dir beschrieben mache ich das z.Z.
Mein Client schickt eine Anfrage um Daten zu erhalten die erst vom Server aufbereitet werden müssen, hierfür startet der Server einen Thread bereitet die Daten auf und ruft dann per CallBack eine Methode auf dem Client auf und übergibt die Daten. Also genau das was du oben beschrieben hast.

Ich brauche für mein Programm allerdings auch mehrer Connections vom Server zu einer Datenbank um zu gewährleisten das einige Transaktionen in sich abgeschloßen sind und nicht thread a einen commit für halbfertige Daten von thread b macht ( selbe connection ).

Da ich also sowieso die Connections aufteilen muß, dachte ich es ist sauberer vielleicht die ganze Serverfunktionalität ( RMI Methoden, DBCon., .. ) als eigenen Thread für einen Client zu starten.


----------



## tuxedo (28. Okt 2009)

Tallan hat gesagt.:


> Ich brauche für mein Programm allerdings auch mehrer Connections vom Server zu einer Datenbank um zu gewährleisten das einige Transaktionen in sich abgeschloßen sind und nicht thread a einen commit für halbfertige Daten von thread b macht ( selbe connection ).
> 
> Da ich also sowieso die Connections aufteilen muß, dachte ich es ist sauberer vielleicht die ganze Serverfunktionalität ( RMI Methoden, DBCon., .. ) als eigenen Thread für einen Client zu starten.



Das ist ein schlechtes Design. Wenn du für jeden Client einen Thread bereit stellst dann geht dein Server recht schnell in die Knie. Du kannst das aber recht geschickt mit Threadpools lösen:


Client -----Rmi---> Server [ --Runnable--> TaskPool --Abfrage als Runnable--> DBPool]

Der Client stellt via RMI eine Anfrage an den Server. Die Anfrage wird in ein Runnable verpackt (nennen wir das ganze nun Task) und in einen ThreadPool (der Task-Pool) geworfen. Im ThreadPool arbeiten X Threads diese Runnables ab. Benötigt so ein Task Zugriff auf die DB, so wirft er die DB-Anfrage/Transaktion in einen weiteren ThreadPool wo wieder Y Threads gleichzeitig mit der DB sprechen können.

Ist der Task fertig, liefert er via Callback das Ergebnis an den Client zurück. 


```
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        
        
        cachedThreadPool.execute(new Runnable(){

            @Override
            public void run ()
            {
                // do whatever is needed to to
                // ....
                // returbn result via callback to client
            }
            
        });
```

Statt einem CachedThreadPool kannst du auch einen mit einer fixen Größe nehmen. Schau dazu einfach was Executors für Methoden anbietet. Der Cached Pool ist aber schon ziemlich geschickt und für die allermeisten Dinge ausreichend und sehr performant. 

Ach ja: Der Hauptvorteil eines Pools ist: Die Threads werden recycled und nicht ständig erzeugt und nach der benutzung wieder durch den GC abgeräumt. Sprich: Das ganze ist besser zu benutzen und ist auch noch performanter.


----------



## Tallan (28. Okt 2009)

tuxedo hat gesagt.:


> Das ist ein schlechtes Design. Wenn du für jeden Client einen Thread bereit stellst dann geht dein Server recht schnell in die Knie. Du kannst das aber recht geschickt mit Threadpools lösen:
> 
> 
> Client -----Rmi---> Server [ --Runnable--> TaskPool --Abfrage als Runnable--> DBPool]
> ...





danke ich werd mir das morgen mal in ruhe anschauen.


----------



## tuxedo (29. Okt 2009)

Tallan hat gesagt.:
			
		

> Hallo Alex,
> 
> erstmal wie schon des öfteren danke für dein Engagement.
> 
> ...



Nein, du lengst nicht direkt Threads an. Du erstellst z.B. einen cached Threadpool.

Das was du dann anlagst sind "Runnables". Also Objekte von Klassen die das Interface "Runnable" implementieren (sprich die run() methode ...).

Da du selbst in der Hand hast wie die Klassen aussehen, kannst du da Parameter dem Konstruktur übergeben und mit Methoden auf alles mögliche zugreifen. 

Wirst du nun dieses Objekt in den Pool, so greift sich irgendwann (dann wenn der Pool es für richtig hält) das Objekt und führt dessen run() Methode aus.

Dein 
	
	
	
	





```
cachedThreadPool.execute(new mythread(parameter))
```
 wäre recht fatal. Der Thread den du da reinsteckst hat zwar auch das Runnable-Interface implementiert und die run() Methode würde auch ausgeführt. Aber der ganze Overhead der mit dem Thread-Objekt mitkommt wäre total unnötig.

Wirf einfach nur anonyme Runnables rein wie ich dir schon beschrieben habe, oder, bau dir eine Klasse mit Konstruktur und allem drum und dran und implementiere "Runnable" und formuleire den Body der run() Methode. Fertig.

Im übrigen: Lern endlich solche allgemeine Fragen übers Forum zu handhaben. PMs bringen dich da nicht weiter. Ich habs dir schonmal gesagt: Ich bin nicht der allwissende mit unendlicher Zeit. Wenn du allgemeine Fragen hast: Ab damit ins Forum. Ganz sonderspezielle Fragen (meinetwegen über die interna von SIMON oder sowas) kannst du gerne via PM schicken (da bin ich ja eh der einzige der das beantworten kann).

In diesem Sinne,

gruß
Alex


----------

