1 / 36

Remote Method Invocation (RMI) and Distributed Observers in Java

Remote Method Invocation (RMI) and Distributed Observers in Java. Theodore Norvell. The Proxy Pattern. The Client object uses its subject via an interface Thus it may be used with a real subject or with a proxy object which represents the subject. The Proxy Pattern.

adsila
Download Presentation

Remote Method Invocation (RMI) and Distributed Observers in Java

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Remote Method Invocation(RMI) and Distributed Observers in Java Theodore Norvell

  2. The Proxy Pattern • The Client object uses its subject via an interface • Thus it may be used with a real subject or with a proxy object which represents the subject. Engineering 5895 Memorial University

  3. The Proxy Pattern • The client calls the proxy, which • forwards the call (somehow) to the actual subject. Engineering 5895 Memorial University

  4. RMI and the Proxy pattern • RMI uses the Proxy pattern to distribute objects across a network. • Recall that in the Proxy pattern a proxy and a subject share a common interface. • In RMI, objects call methods in a proxy (aka stub) on its own machine • The proxy sends messages across the network to a “skeleton” object • The skeleton calls the subject object. Engineering 5895 Memorial University

  5. One Remote Method Call. (0) Client calls stub (1) Stub messages skeleton (2) Skeleton calls server (subject) (3) Call returns (4) Skeleton messages proxy (5) Call returns Engineering 5895 Memorial University

  6. Full disclosure • The term “skeleton object” is out of date. The point is that some code (that you don’t have to write) running on the server’s jvm will turn network traffic into method calls to the server object and method returns (or exceptions) into network traffic. • I’ll continue to use the term “skeleton object” to refer to the object(s) that perform these duties. Engineering 5895 Memorial University

  7. Issues • Concurrency • If there are multiple clients, the server may field multiple calls at the same time. • So use synchronization as appropriate. • Argument passing • Arguments are passed by value or “by proxy” not by reference. • Proxy generation • Proxy classes are automatically derived from the server class’s interface. • Lookup • Objects are usually found via a registry (program rmiregistry) Engineering 5895 Memorial University

  8. Nitty-Gritty • The proxy and the server share an interface. • This interface must extend java.rmi.Remote. • Every method in the interface should be declared to throw java.rmi.RemoteException • RemoteExceptions are thrown when network problems are encountered, • or when server objects no longer exist. • The server typically extends class java.rmi.server.UnicastRemoteObject • The constructor of this class throws a RemoteException • Therefore, so should the constructor of any specialization. Engineering 5895 Memorial University

  9. Argument Passing Revisited • Most arguments and results • are converted to a sequence of bytes; • the bytes are sent over the net • therefore the class should implement the java.io.Serializable interface • a clone of the argument/result is constructed on the other side. • The effect is pass by object value, rather than by object reference. • But • objects that extend java.rmi.server.RemoteObject • instead have a proxy constructed for them on the other side • I call this “pass by proxy”. Essentially pass by reference • So each argument, result, exception type should be • a primitive type, Serializable, or extend RemoteObject Engineering 5895 Memorial University

  10. An Example – Distributed Othello • Othello is a two person board game • My implementation uses the observer pattern so that, • when the (game state) model changes, • all observers are informed of the change. • I wanted to put the model on one machine and the observers on other machines. • Hence I implemented the observer pattern with RMI. • This is example othello-2 on the website. Engineering 5895 Memorial University

  11. The Observer Pattern Subject alerts Observers of changes of state. Engineering 5895 Memorial University

  12. Observer Pattern Engineering 5895 Memorial University

  13. Object diagram for Othello 2 Client Host 0 Client Host 1 :BoardView : BoardView Notifies Observes Notifies Observes :Animator :Animator Observes Observes :RemoteGameModel Notifies Notifies Server Host Engineering 5895 Memorial University

  14. … with proxies and skeletons : BoardView : BoardView Notifies Notifies Observes Observes :Animator Notifies :Animator Client Host Observes Notifies Skeleton Remote Game Model’s Proxy Skeleton Observes Communicates with Communicates with Communicates with Remote Game Model’s Proxy Another Client Host Communicates with Animator Proxy Skeleton Server Host :RemoteGameModel Animator Proxy Notifies Engineering 5895 Memorial University

  15. The Observer Pattern for Othello Engineering 5895 Memorial University

  16. Proxy for the Remote Game Model Engineering 5895 Memorial University

  17. Proxies for the Animators Engineering 5895 Memorial University

  18. Animator / RemoteGameModel Relationship Engineering 5895 Memorial University

  19. Typical sequence —slightly simplified • A remote client calls a synchronized mutator on the RemoteGameModel via its stub & skeleton • The RemoteGameModel updates its state and notifies each Animator via its stubs & skeletons. • The Observers (Animator objects) call the RemoteGameModel accessor “getPieceAt” via its stubs and skeleton. • (Therefore this accessor must not be synchronized!) • getPieceAt returns • The update routines return. • The original mutator call returns and the RemoteGameModel becomes unlocked. Engineering 5895 Memorial University

  20. someObj : RemoteGameModel : RemoteGameModel_Stub : Animator_Stub : Animator move(int, int, int) Across net notifyObservers(...) with help of skeleton update(...) update(...) Across net with help of skeleton getPieceAt(int, int) getPieceAt(int, int) Calls to other accessors are similar Typical sequence —slightly simplified Engineering 5895 Memorial University

  21. Concurrent Notification • The previous sequence is slightly simplified. • In fact the Animators return from update immediately (so that all can be informed essentially at the same time). • The Animation threads will inform the RemoteGameModel of when they have completed their animation. • The RemoteGameModel waits until it has been informed that all animations are complete. • The effect is that the animations can happen concurrently, yet the RemoteGameModel does not unlock until all animations are complete and all models agree on the board state. • See RemotelyConcurrentlyObservable for details. Engineering 5895 Memorial University

  22. someObj : RemoteGameModel : Animator : Animator : RemoteCountMonitor move(...) notifyObservers(...) update(...) update(...) waitForZero( ) decrement( ) decrement( ) Concurrent Notification During this time the animators animate (using new threads created in update). The last thing these threads do is call decrement (via RMI). Once all the animation threads have called decrement, the original server thread returns from waitForZero I simplifed this diagram a bit by omitting the callbacks from the animators to the game model and by omitting the stubs and skeletons. Engineering 5895 Memorial University

  23. Naming the Server • Normally an object’s address serves as a unique identifier • But this only makes sense in the context of a given JVM process. • We would like objects to have unique identifiers that are unique in the world. • The rmiregistry allows you to give a URI to an object • And to obtain a proxy for an object that has a URI. • URIs are: rmi://host/name • The host must be running a rmiregistry process and that process should have the appropriate class files on its CLASSPATH Engineering 5895 Memorial University

  24. Binding the server to a name. • The main routine for the server • The static method bind in Naming gives a URI to gameModel publicstaticvoid main( String[] args ) { try { RemoteGameModel gameModel = new RemoteGameModel(); String name = args[0] ; Naming.bind( name, gameModel ) ; System.err.println("Game model bound to "+name);} catch( java.net.MalformedURLException e) { … } catch( AlreadyBoundException e) { … } catch( RemoteException e ) { … } } Engineering 5895 Memorial University

  25. The uri specifies the host (and port) of the RMI registry process. Bind 1. A call Naming.bind(uri,gm) is made. i.jar only needs the class files for the server object’s interface. 1.1 A proxy object is created. Webserver 1.1.1 A serialization of the proxy is sent to the registry. read 1.1.1.1 A copy is created in the registry’s vm. Animator object i.jar get RMIRegistry GameModel object Proxy objects U is the URL of i.jar Skeleton object bind java -Djava.rmi.server.codebase=U -cp s.jar ServerMainClass JVMs gm Engineering 5895 Memorial University

  26. Looking up the server object • The clients obtain a proxy for the game model using Naming.lookup( URI ) • From ClientMain.java publicstaticvoid main( String[] args) { RemoteGameModelInterface proxy = null ; try { String name = args[0] ; proxy = (RemoteGameModelInterface) Naming.lookup( name ) ; } catch( java.net.MalformedURLException e) { … } catch( NotBoundException e) { … } catch( RemoteException e) { … } … continued on the slide after next … Engineering 5895 Memorial University

  27. Looking up the server object 2. Naming.lookup(uri) is called on the client vm. java -cp c.jar ClientMainClass 2.1 A lookup message is sent to the RMI registry. lookup(uri) 2.1.1. A serialized copy of the proxy is sent to the client. And a proxy is built in the client vm. Animator object RMIRegistry GameModel object Proxy objects Skeleton object java -Djava.rmi.server.codebase=U -cp s.jar ServerMainClass JVMs Engineering 5895 Memorial University

  28. Closing the loop • The client then can use the proxy. E.g. • Continuing the ClientMain main routine … Animator animator0 = null ; try { animator0 = new Animator( proxy ) ; } catch( RemoteException e ) { … } • The constructor for Animator public Animator( RemoteGameModelInterface gameModel ) throws RemoteException { super() ; … gameModel.addObserver(this); } Engineering 5895 Memorial University

  29. Adding a remote Observer. • Each Animator calls addObserver(this) on the RemoteGameModel’s proxy. • Since Animator implements RemoteObject, it is passed by proxy, meaning • a proxy for the Animator is constructed in the JVM of the RemoteGameModel. • (see next slide.) Engineering 5895 Memorial University

  30. Adding a remote observer ani Animator object addObserver(a) GameModel object addObserver( ) gmp Proxy objects 3 the animator (ani) calls addObserver(this) on the game model’s proxy (gmp) Skeleton objects JVMs 3.1 the client vm sends a serialized proxy for ani to the server vm. anip addObserver(anip) 3.1.1 The animator’s proxy (anip) is constructed in the server vm. gm 3.1.1.1 An addObserver(anip) message is sent to the game model, which saves anip’s address to its observer list. Engineering 5895 Memorial University

  31. The final hookup (again) Calls :Animator Skeleton Observes Communicates with Remote Game Model’s Proxy Communicates with Client Host 0 Skeleton Animator Proxy :RemoteGameModel Notifies Server Host Calls Engineering 5895 Memorial University

  32. Creating the stubs and skeletons • First we write a server class: E.g. publicclass RemoteGameModel extends RemotelyConcurrentlyObservable implements RemoteGameModelInterface { public RemoteGameModel() throwsRemoteException { super() ; } … } • We compile it with “javac” • The stub objects will be created automatically at run time. Engineering 5895 Memorial University

  33. Starting an RMI registry • In order to build a proxy object, the RMIRegistry process needs access to the .class file(s) for the interface. • Option 0. Run the RMIRegistry with the appropriate .class files on its classpath. • Option 1. Put the class files on a webserver and, when the server is run, use the following option -Djava.rmi.server.codebase=URL • (Option 1 was illustrated earlier in the animation of the bind process.) Engineering 5895 Memorial University

  34. A Few Words of Warning • RMI makes it seductively easy to treat remote objects as if they were local. • Keep in mind • Partial Failure • Part of the system of objects may fail • Partial failures may be intermittent • Network delays • On a large network, delays are indistinguishable from failures • In the Othello example, failure was not considered. The system is not designed to be resilient to partial failures. Engineering 5895 Memorial University

  35. A Few Words of Warning (cont.) • Keep in mind (cont.) • Performance • Remote calls are several orders of magnitude more expensive than local calls (100,000 or more to 1) • E.g. in the Othello example, this motivated splitting the model into local (Animator) and remote (RemoteGameModel) copies. • Concurrency • Remote calls introduce concurrency that may not be in a nondistributed system. • E.g. in Othello, I had to be careful not to use synchronized for accessors called by remote Observers and to consider the data integrity consequences of not doing so. (The reason was that the call to the mutator and the call to the accessor are in different threads each spun off the skeleton. Therefore the call to the mutator would lock out the call to the accessor, if both were synchronized.) Engineering 5895 Memorial University

  36. A Few Words of Warning (cont.) • Keep in mind (cont.) • Semantics changes • In Java, local calls pass objects by pointer value. • Remote calls pass objects either by copy or by copying a proxy. • E.g. in the Othello game as I converted from the nondistributed to a distributed version, the semantics of some calls changed, even though I did not change the source code for those calls. Engineering 5895 Memorial University

More Related