Workaround gesucht für OncRpcClient.close()

oncrpc
remotetea

#1

Hallo zusammen,

ich “darf” Remote Tea nutzen um RPC Funktionen auf einem anderen Server auszuführen. Die Stubs die ich dazu nutze sind nicht von mir generiert worden, ich darf nur damit arbeiten.

Jetzt ist das Problem dass die Sockets auf dem Server nicht beendet werden bis meine JVM terminiert. Um den Socket zu schließen soll man die Methode OncRpcClient.close() aufrufen, nun steht dort aber in den Javadocs:

close

public void close() throws OncRpcException

Close the connection to an ONC/RPC server and free all network-related resources. Well – at least hope, that the Java VM will sometimes free some resources. Sigh.

Throws:
OncRpcException - if an ONC/RPC error occurs.

Hat jemand vielleicht ne Idee, wie ich die JVM dazu bringen kann, diese Ressourcen garantiert und zeitnah frei zugeben?

Am Liebsten wäre mir ein Einzeiler den ich direkt nach dem close() aufrufe. Ich setze den Client auch nach dem close() auf “null” wie es in der Javadoc drinnen steht.

Hier ein kurzes Snippet von meiner disconnect-Methode:

public boolean disconnectRpc(){
    MyResult result = rpcClient.disconnect_session(sessionID);
	if(result.getErrorCode()==0){
		rpcClient.close();
		rpcClient = null;
		return true;
	}else{
		return false;
	}
}

#2

Ist das Framework so etwas wie RMI? In RMI gibt es ein ähnliches Problem, aber mit dem Server. Der kann nicht sauber beendet werden. Man muss ihn durch abwürgen der VM ausknipsen.

In deinem Code fällt mir nur die Formulierung deiner Bedingung auf. Ich hätte das so geschrieben:

   public boolean disconnectRpc(){
      MyResult result = rpcClient.disconnect_session(sessionID);
      if(result.getErrorCode()==0){
         rpcClient.close();
         rpcClient = null;
         return true;
      }
      return false;
   }

Gibt es für den Errorcode Konstanten, die man einsetzen kann?


#3

Konstanten hab ich für die Errorcodes tatsächlich noch nicht, danke für den Hinweis.

Die Methode war zusammen gekürzt, nebenher findet da bspw. noch detailliertes Logging statt.


Meine Beobachtungen haben aber gezeigt, das mit den auf “null” setzen nachdem close() scheinbar ausreichend ist um den Socket zu schließen.

Ich mach jetzt noch ein paar längere Testläufe um sicher zu sein, denn im Produktivsystem wäre es durchaus kritisch wenn sich über die Zeit Sockets ansammeln die nicht mehr genutzt werden und eigentlich nur Speicher fressen.


Edit sagt: Ja das scheint sowas wie RMI zu sein, nur das im meinem Fall der angesprochene Server mit C# und Python realisiert worden ist.


#4

Dein Problem hat mich dazu gebracht, mich noch mal eingehender mit meinem Problem mit dem RMI-Server zu beschäftigen. Es gibt da zwei Sachen, die man machen kann:
Zunächst muss man das exportierte Remote-Objekt aus der RMI-Registry entfernen, danach den Namen der Bindung des Remote-Objektes, unter der es in der RMI-Registry angemeldet wurde, lösen.

    public void shutDown() throws NoSuchObjectException, RemoteException, NotBoundException {
        UnicastRemoteObject.unexportObject(this.task, true);
        Registry registry = LocateRegistry.getRegistry();
        registry.unbind(this.bindName);
    }

Nach deiner Anregung habe ich abschließend das RMI-Server-Objekt auf null gesetzt. Danach ließ sich das Programm auch ohne Abschießen der VM sauber beenden. Nötig ist das dazu nicht, schadet aber auch nicht.
Vielleicht kannst du von diesen Erkenntnissen profitieren.


#5

Ein Binding findet bei dem oncrpc-Zeugs nicht statt, zumindest nicht für mich ersichtlich. Aber das auf “null”-setzen scheint zu klappen.

Problem ist nur das ich gerade bei meinen Tests zu viele Sockets auf- und abbaue dass ich damit den Zielserver abschieße :smiley: Das Ding ist nur für die Entwicklung gedacht und verkraftet einfach nicht so viele Anfragen. Ich darf aber erst gegen eine QS-Instanz laufen wenn wir sicher sind, dass alles korrekt aufgeräumt wird.

Aber danke dir für deine Denkanstöße :slight_smile: