From c11e8c4d3c9bc013ad29e0777f9307e5dc32fb67 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Thu, 27 Jan 2005 01:55:48 +0000 Subject: [PATCH] The beginnings of documentation for the Presents distributed object system. Oh the complexity. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3313 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- build.xml | 3 +- docs/stylesheet.css | 48 +++ .../threerings/presents/images/dobject.dia | Bin 0 -> 1545 bytes .../threerings/presents/images/dobject.png | Bin 0 -> 24897 bytes src/java/com/threerings/presents/package.html | 321 ++++++++++++++++++ 5 files changed, 371 insertions(+), 1 deletion(-) create mode 100644 docs/stylesheet.css create mode 100644 src/java/com/threerings/presents/images/dobject.dia create mode 100644 src/java/com/threerings/presents/images/dobject.png create mode 100644 src/java/com/threerings/presents/package.html diff --git a/build.xml b/build.xml index 73322b3fd..e7da8186c 100644 --- a/build.xml +++ b/build.xml @@ -120,7 +120,8 @@ + link="http://www.threerings.net/code/narya/narya/docs/api" + stylesheetfile="docs/stylesheet.css"> diff --git a/docs/stylesheet.css b/docs/stylesheet.css new file mode 100644 index 000000000..47ae720bd --- /dev/null +++ b/docs/stylesheet.css @@ -0,0 +1,48 @@ +/* Javadoc style sheet */ + +/* Page background color */ +body { + background-color: #FFFFFF; + font-family: Arial, Helvetica, sans-serif; +} + +pre { + font-family: Courier New, monospace +} + +/* Headings */ +h1 { font-size: 145% } + +/* Table colors */ +.TableHeadingColor { background: #CCCCFF } /* Dark mauve */ +.TableSubHeadingColor { background: #EEEEFF } /* Light mauve */ +.TableRowColor { background: #FFFFFF } /* White */ + +/* Font used in left-hand frame lists */ +.FrameTitleFont { font-size: 100%; font-family: Helvetica, Arial, sans-serif } +.FrameHeadingFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif } +.FrameItemFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif } + +/* Navigation bar fonts and colors */ +.NavBarCell1 { background-color:#EEEEFF;} /* Light mauve */ +.NavBarCell1Rev { background-color:#00008B;} /* Dark Blue */ +.NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;} +.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;} + +.NavBarCell2 { + font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF; +} +.NavBarCell3 { + font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF; +} + +.example { + padding-top: 5px; + padding-bottom: 5px; + padding-left: 10px; + padding-right: 10px; + margin-left: 20px; + margin-right: 20px; + border: 1px solid black; + background-color: #FFFF99 +} diff --git a/src/java/com/threerings/presents/images/dobject.dia b/src/java/com/threerings/presents/images/dobject.dia new file mode 100644 index 0000000000000000000000000000000000000000..0c173535466d13b5b8d89e1e20cecbf9e4a056c5 GIT binary patch literal 1545 zcmV+k2KMm8z~A{4QTlQxr6zX%FJ-Itq|-fg)#}vPVttKsnB;Q=J89COM*5-&kchX3It z!9&q#s9z5>?YV#mb6gx-AH|%rc)H|7OYwq?^(hYTW{fV=NUvJ0+l4ftOuNU)SbuX{ zzVzW*%y3K20ofUzktrkiZog<#yn^5y(HUWNv5So6v1r0q*-n!^a*Fq7ZPu-F(I}l= zzxiOlsV-@KU?Z#PLiZ}+3(RJ5x~oU@O;U9P0zN`WbcPf7f$7;E{Lv?;tDE+#F6mbt z>sMWzPcq6l!!h4gIi)lqIIXmDwj}54$wQn77dvED3oCA8&gqfszr{)Z5(BEkPtkU2 zB7JH;T#1WrQ9wl{GC4D7H`hA?o(}Xl#eVp>n#IL#$Umu;4-kZ}~dP5~` z@AMG)#39b<)5B~TMSYraDxctVAF36!?x|6`pB1z%@$u zlFRiwI=@~NJQb->`+wg%a(-qIQ;U%8vNpwU6TyyJnrq^@wxTB?>1J~N@^YL=^ zW2;?lq2vprk1OqS>7|2gIZfhFD@I~L(>t=tM|+l04%8m|3R#-+rVA;KYqxk2Co6Hi zIL&n}=c^(~7C}*+`WH#=36DekJeNQH3U-FCVF*p&Zx5kqw^O`b$rBAmptbU~U2lcdWx|#aF6(O?ASi3D_U8zZ`D-u+DB<6nG zZ~$~(KS3bS{wDt}NzQX^b9OivHj%4=uo>ip-&8pH4Vu3zq)11~mWTcdG%?!5nTb|N({w`8s5Il{#x)ek_PM#9 zaE&mlYi?R4Jt@meqX}k=KGX$oJQ1Omq9+MSXNNLWkq)#~aU=&muA!UQa9ghk6-BVz z;P5Qy83AxC)3!#)0jBH0qVg_2B?m{%y2j{%rV5W=H9Wiv2oKjomQl!EUkrYha~SqKWcn17|-uPpDK+an7BSl$l0gykR` zXdfBHQHYBLA#yJqMB{XjFQ<7ZM2SIA6p>Alnqw-A$ixUVJK%^f7b9Ll5ep!ZvRnc~ zETDbQBFsgevJe;{>?tX!zN)OGcb@nPCq3Z=wy%2-l3Mp5_*D25PdKTi02lxTqG2gY^hAjc9<_s>R7^nk2PdF+ zNuWRq6g}LE@f0a~B8AgIMdHYz vwWqW8rn=d$VEYpj+5nV~vntr04BP5^`P)C&gRLJ2x*q%wB)fXrKu`bxl4R?y literal 0 HcmV?d00001 diff --git a/src/java/com/threerings/presents/images/dobject.png b/src/java/com/threerings/presents/images/dobject.png new file mode 100644 index 0000000000000000000000000000000000000000..5890da6e807f98cdecbed1bf04c1b13329e93d00 GIT binary patch literal 24897 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 + + + + + + + + Defines a framework for distributing information between multiple + separate applications (over a network) and for coordinating control + flow between those applications in the form of remote procedure call + services. The normal configuration of the Presents system is + client/server; generally with many clients connecting to a single + server. All information transfer takes place through the server using + the distributed object system documented below. + +

A note to the reader: the Presents system is a complex + one and though a great deal of code is provided in explaining the + services it provides, it is not the intent that one should start from + only these examples and build a working system. A better approach is + to read through this documentation to come to an understanding of the + concepts and mechanisms that define the system and then take a look at + some working sample code which is provided in the tests + directory of this distribution. + +

Distributed Objects

+ + The Presents services allow applications to access and update shared + information through a mechanism known as distributed objects. + Distributed objects are maintainedon the server and clients + "subscribe" to the objects and are provided with proxy copies which + are updated by a stream of events sent by the server when any state + changes in the objects. + +

Clients cannot modify their proxy distributed objects directly, + instead they make use of setter methods which package up the requested + change into an event and send that event to the server for processing. + After performing access control checks, the server will apply the + event to the primary distributed object instance and then dispatch + that event to all subscribed clients. Those clients (including the + original change requesting client) then apply the event to their proxy + copy of the object and in this way all clients maintain an up to date + copy of the object's data. + +

+ +

Defining an object

+ + A distributed object is defined just like a regular Java object and is + then run through a post-processor which inserts methods and constants + into the object definition which are needed by the distributed object + system. Here is a distributed object as originally defined: + +
+    public class CageObject extends DObject
+    {
+        /** The number of monkeys in the cage. */
+        public int monkeys;
+
+        /** The name of the owner of this cage. */
+        public String owner;
+    }
+ + This class definition is then run through a post-processor which turns + it into the following: + +
+    public class CageObject extends DObject
+    {
+        // AUTO-GENERATED: FIELDS START
+        /** The field name of the monkeys field. */
+        public static final String MONKEYS = "monkeys";
+
+        /** The field name of the owner field. */
+        public static final String OWNER = "owner";
+        // AUTO-GENERATED: FIELDS END
+
+        /** The number of monkeys in the cage. */
+        public int monkeys;
+
+        /** The name of the owner of this cage. */
+        public String owner;
+
+        // AUTO-GENERATED: METHODS START
+        /**
+         * Requests that the monkeys field be set to the
+         * specified value. The local value will be updated immediately and an
+         * event will be propagated through the system to notify all listeners
+         * that the attribute did change. Proxied copies of this object (on
+         * clients) will apply the value change when they received the
+         * attribute changed notification.
+         */
+        public void setMonkeys (int value)
+        {
+            int ovalue = this.monkeys;
+            requestAttributeChange(
+                EVEN_BASE, new Integer(value), new Integer(ovalue));
+            this.monkeys = value;
+        }
+
+        /**
+         * Requests that the owner field be set to the
+         * specified value. The local value will be updated immediately and an
+         * event will be propagated through the system to notify all listeners
+         * that the attribute did change. Proxied copies of this object (on
+         * clients) will apply the value change when they received the
+         * attribute changed notification.
+         */
+        public void setOwner (String value)
+        {
+            String ovalue = this.owner;
+            requestAttributeChange(
+                ODD_BASE, value, ovalue);
+            this.owner = value;
+        }
+        // AUTO-GENERATED: METHODS END
+    }
+ + The contents of the methods are not too important, the main things to + note are that setter methods for the two attributes (fields in a + distributed object are referred to as attributes in this + documentation and elsewhere in the system) were generated and + constants were defined that will be used to identify which attribute + changed if we choose to inspect an event notifying us of such a + change. + +

Creating an object

+ + Generally, some entity on the server will choose to create a new + instance of a distributed object. Rather than simply instantiate the + object directly, one must create the object through the {@link + com.threerings.presents.dobj.DObjectManager}: + +
+    public class ServerEntity implements Subscriber {
+        public void init (DObjectManager omgr) {
+            omgr.createObject(CageObject.class, this);
+        }
+
+        // inherited from interface Subscriber
+        public void objectAvailable (DObject object) {
+            // yay! we created our object
+            _object = (CageObject)object;
+        }
+
+        // inherited from interface Subscriber
+        public void requestFailed (int oid, ObjectAccessException cause) {
+            // oh the humanity, we failed to create our object; in
+            // general this would only happen if we did something silly like
+            // passed in a DObject class that didn't extend DObject
+        }
+
+        protected CageObject _object;
+    }
+ + You'll notice that we provide an instance of a Subscriber + when creating our object. This subscriber instance is in fact + subscribed to the newly created object in the same manner as is + described below for all additional subscribers to the object. It is + possible to instruct an object to automatically destroy itself when + all subscribers have unsubscribed. (See {@link + com.threerings.presents.dobj.DObject}.setDestroyOnLastSubscriberRemoved()). + +

Subscribing to an object

+ +

The client obtains a proxy of the object by a process called + subscription, which is accomplished via {@link + com.threerings.presents.dobj.DObjectManager}.subscribeToObject(): + +

+    public class ObjectUser implements Subscriber {
+        public void init (Client client, int objectId) {
+            client.getDObjectManager().subscribeToObject(objectId, this);
+        }
+
+        // inherited from interface Subscriber
+        public void objectAvailable (DObject object) {
+            // yay! we got our object
+            _object = (CageObject)object;
+        }
+
+        // inherited from interface Subscriber
+        public void requestFailed (int oid, ObjectAccessException cause) {
+            // oh the humanity, we failed to subscribe
+        }
+
+        protected CageObject _object;
+    }
+ +

Later a client would relinquish its subscription to the object + using a similar mechanism: + +

+    public class ObjectUser implements Subscriber {
+        // ...
+        public void shutdown (Client client) {
+            client.getDObjectManager().unsubscribeFromObject(
+                _object.getOid(), this);
+            _object = null;
+        }
+        // ...
+    }
+ + However, this is a fine time to point out the dangers of working in an + asynchronous distributed environment. There is no guarantee that your + object subscription request will be completed before the client + decides to call shutdown() on its ObjectUser. Thus, in + the previous code, we would get a null pointer exception, and even + worse, we would remain subscribed to the object even though we didn't + want to be. To avoid these sorts of problems, the {@link + com.threerings.presents.util.SafeSubscriber} class is provided: + +
+    public class ObjectUser implements Subscriber {
+        public void init (Client client, int objectId) {
+            _safesub = new SafeSubscriber(objectId, this);
+            _safesub.subcribe(client.getDObjectManager());
+        }
+
+        // inherited from interface Subscriber
+        public void objectAvailable (DObject object) {
+            // yay! we got our object
+            _object = object;
+        }
+
+        // inherited from interface Subscriber
+        public void requestFailed (int oid, ObjectAccessException cause) {
+            // oh the humanity, we failed to subscribe
+        }
+
+        public void shutdown (Client client) {
+            _safesub.unsubscribe(client.getDObjectManager());
+            _object = null;
+        }
+
+        protected SafeSubscriber _safesub;
+        protected DObject _object;
+    }
+ + The safe subscriber will pass the object availability on to your + subscriber and when the time comes to unsubscribe, it will cope with + the case where the original subscription was not fully processed and + stick around long enough to ensure that once it is, the request to + unsubscribe is also dispatched. It will also cope with a request to + unsubscribe() even if the original subscription request + failed. + +

Listeners

+ + Once a client has subscribed to a distributed object, all events + pertaining to that object will be delivered to the client. Frequently, + it is useful to respond dynamically to changes in distributed object + values and this is accomplished using listeners. A client can register + any number of listeners on an object and when the object is finally + unsubscribed from and garbage collected, the listener registrations + all go away as well. + +

The basic listener is the {@link + com.threerings.presents.dobj.AttributeChangeListener} which is + informed of all simple attribute changes (setting a primitive field to + a new value is called an attribute change in this distributed object + system). We return to our trusty example: + +

+    public class ObjectUser
+        implements Subscriber, AttributeChangeListener {
+        // ...
+        public void init (Client client, int objectId) {
+            _safesub = new SafeSubscriber(_subscriber, objectId);
+            _safesub.subcribe(client.getDObjectManager());
+        }
+
+        // inherited from interface Subscriber
+        public void objectAvailable (DObject object) {
+            // yay! we got our object
+            _object = object;
+            _object.addListener(this);
+        }
+
+        // inherited from interface Subscriber
+        public void requestFailed (int oid, ObjectAccessException cause) {
+            // oh the humanity, we failed to subscribe
+        }
+
+        // inherited from interface AttributeChangeListener
+        public void attributeChanged (AttributeChangedEvent event)
+        {
+            System.out.println("Wow! The " + event.getName() +
+                               " field changed to " + event.getValue() + ".");
+        }
+
+        public void shutdown (Client client) {
+            _safesub.unsubscribe(client.getDObjectManager());
+            if (_object != null) {
+                 // removing our listener not necessary as we are
+                 // unsubscribing, but it's a good habit to develop as
+                 // frequently listeners will come and go during the
+                 // lifetime of an object subscription
+                _object.removeListener(this);
+                _object = null;
+            }
+        }
+
+        protected SafeSubscriber _safesub;
+        protected DObject _object;
+    }
+ + It is useful to note that listeners are notified of a changed + attribute after the change has been applied to the object. The + previous value of the attribute is available through the {@link + com.threerings.presents.dobj.AttributeChangedEvent#getOldValue} + method, though in spite of many years of experience using this system + in a variety of circumstances, we have rarely found that we cared to + know the previous value. + +

Distributed collections

+ +

Invocation Services

+ + +