From: samurai@cs.mcgill.ca (Darcy BROCKBANK)
Subject: Re:  distributed objects? (Plusses & minuses of NeXT's design)
Organization: SOCS - Mcgill University, Montreal, Canada
Date: Sun, 27 Sep 1992 17:30:00 GMT


In article <dillon.0ocn@overload.Berkeley.CA.US> dillon@overload.Berkeley.CA.U!
>>In article <1992Sep24.013242.21299@news2.cis.umn.edu> burchard@horizon.math.!
>>>In article <5123@rosie.NeXT.COM> sam_s@NeXT.com (Sam Streeper) writes:
>>>...
>>
>>I think Distributed Objects is one of the greatest features of 3.0.  It opens
>>..
>>
>>However, I feel that there is one glaring flaw in the design of 3.0 D.O.'s.
>>The set of message parameter types supported is just not broad enough to make
>
>    There is another glaring flaw and that is their handling of dead
>    connections.  I have yet to be able to get reliable notification of a
>    dead distributed object being accessed remotely.  Without this,
>    distributed objects are useless!

I had trouble with this too... however the mechanism is there, you
just have to become familiar with it.

1) Your object should comform to the NXSenderIsInvalid protocol,
if you plan on sending remote messages. If you do this, you can
ask for invalidation notification when the connection goes down:

        id server = [NXConnection connectToName:"RemoteServer"];
        id connection = [server connectionForProxy];
        [ connection registerForInvalidationNotification:self];

Now when the connection goes down, you get a message - senderIsInvalid:
telling you that the connection is dead.


2) Bracket EVERY remote message with NX_DURING..NX_HANDLER..NX_ENDHANDLER
if you think there may be problems with your connections. If you try
to send a message to a proxy whose connection has died, you'll likely
raise an exception. If you don't catch the exception with a NX_HANDLER
then the exception will be caught in the main event loop, and you'll
not be able to finish any methods you have on the stack.

3) I think that DO's are very nicely done, and totally intuitive. You
just get a proxy and away you go! I even mistakenly sent the 
proxy a -free; message, and it blew away an object in another 
application! To prevent this, you should use an NXProtocolChecker,
so that you protect against bad messages...

4) I'm pretty certain that there's a bug in the "RemoteSpot" 
example (Sam?). When a remote spot connects to the server, the
server adds it's id (really a proxy) to a client list. When
the remote spot dies, then the server gets a -senderIsInvalid:
message, and tries to take the "sender" argument out of the
client list. This would be OK if the "sender" was a proxy that
was added to the list, but it ain't.

From the docs on NXSenderIsInvalid:

This message is sent by an invalidation notifier (such as an 

NXConnection) whenever it becomes unusable (for example, 
because its connection has been broken, or because the invalidation 
notifier is about to be freed).  This gives the receiver a 
chance to take proper action regarding the new status of 
the invalidation notifier.

The result is that the server tries to delete "sender" which
isn't in it's client list anyway. The server never checks
the return value of [List removeObject:] so the bug was never
found. Anyway, the proxy of the dead connection remains
in the list to have messages sent to it.

What I do, is:

NX_DURING
        [remoteObject doThis:xyz];
NX_HANDLER
        fprintf(stderr,"%s: Remote exception, removing proxy.",
                [NXApp appName]);
        [clientList removeObject:remoteObject];
NX_ENDHANDLER

Now theres still a couple of problems. When the proxy's
connection dies, then it's supposed to free all it's
proxies. If so, then I've just sent a message to a 
free'd object, which should CRASH not RAISE. However,
it does raise, so maybe the connection isn't freed? It
should have been though, because you do get those
- senderIsInvalid: messages... The other problem, is
that the proxy "remoteObject" should be freed via:
[remoteObject freeProxy] which the docs say you 
shouldn't do (because the connection should, but it hasn't).

Leavingg the proxy around is a memory leak, so I'm not
sure which way to go on that...

Anyway, it's likely that I'm still one step away from
handling this correctly, but the above methods do work,
and handle connection deaths gracefully (that is, the
server doesn't crash, and knows the client is dead).

>
>    Yet another flaw is the totally non-intuitive methods relating to
>    connecting to distributed objects -- it doesn't 'just work', it's a
>    mess, and you have to be careful.
>
>    Orginally I had planned to use DO's for IPC but until I figure out how
>    to get reliable notification of death its unusable for that purpose.

Once you get a feel for what's going on, you'll see
how easy it is. You can do complete interprocess communication
and even send objects across the wire, with 4 lines
of code.

You just cannot beat that for productivity.

I've never done IPC before, but with DO's I made a
client-client/server-server setup of three applications,
and did a client-server setup of two other applications
in three days. That's 5 apps doing IPC with each other,
from scratch, and not knowing anything about DOs before
hand, in 3 days.

I love DO's
I love IXKit
I love 3DKit

Nuff said.

- db
Newsgroups: comp.sys.next.software