Re: Distributed Objects pitfalls and strategies
Re: Distributed Objects pitfalls and strategies
- Subject: Re: Distributed Objects pitfalls and strategies
- From: John Scalo <email@hidden>
- Date: Tue, 30 Mar 2004 11:47:13 -0800
Thanks for the pointers, Wade. Some follow-ups below.
You can set the message reply timeout on the NSConnection. By default
it is either 10, 60 or never, depending on what mood NSConnection is
in when you init it. Depending on your intended use you may want
timeouts anywhere between a few seconds and a few minutes. From the
fact that this is a problem for you I imagine a few seconds is more
likely what you want.
I am indeed setting reply timeouts before and after messaging the
connection (depending on the job - some messages wait for quite a bit
of data and I have to accommodate that), and I do use oneway void
wherever possible. But this problem is really secondary to the fact
that if a server quits with an active connection, a new port can't be
created for <=10 minutes.
But that won't solve all your problems. You should try to write your
DO stuff to be as asynchronous as possible (using oneway void and
bycopy as much as you can). This will help stop either side locking
up if the other takes a while and/or dies. You should also try to
separate your networking into a separate thread to your UI, as with
any network app, to ensure the lock ups don't translate to your app
freezing.
As for the port not being reusable immediately, that's one I've never
actually seen myself. It's been brought up ad infinum on many lists.
The solution is probably to create the sockets manually and set the
appropriate port option, as you do... you could try setting it after
creating the ports automatically, although from memory setsockopt
doesn't do much to ports already in use.
That's strange that you've never run into it. It's 100% reproducible:
1. On the server, create a socket (via NSSocketPort or whatever) using
a static port #
2. Make an NSConnection around this port.
3. Connect to this connection from a client computer.
4. Quit the server.
5. Start the server process again and try create the port.
Result: You get a NULL port because the system thinks it's still in
use. I believe the system's timeout is 10 minutes, so in at most 10
minutes, you can make the port again.
-- Server set to reuse ports --
i.e. the server uses initWithProtocolFamily and the client uses
initRemoteWithProtocolFamily, setting up their own BSD socket
bind()ing, and listen()ing. Each calls setsockopt(newSocket,
SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) before binding.
Problems:
* Client hangs and gets timeout exceptions trying to resolve
connections after the server process has been stopped and started
again. e.g., a user logs out and another logs in.
I'm not familiar with the behaviour for users switching, but I'm
pretty sure no processes ever get paused or otherwise put on old. Why
exactly is your server process starting and stopping when users log in
and out?
Well when a user logs out, all of their processes are quit. Then
there's the case of fast user switching, which requires extra care
since only one NSConnection can exist per port per computer (afaik).
The client hanging can be treated using the suggestions I spoke of
above.
-- Both set to reuse ports --
Problems:
* If there are multiple servers running on the network, then messages
sent to a connection's proxy go to a random server, not necessarily
the one the NSSocketPort was created for.
*boggle* That's a big of a disaster, innit? I've never heard that
one before... I've had multiple servers [of the same type, using the
same port] running concurrently without any such trouble. Of course,
in that particular scenario I've never created the sockets myself...
perhaps you're not configuring something correctly, or somesuch? I'm
not big on raw sockets, so I can't really suggest anything.
Right, this is only a problem when you set the socket on the client
side to allow port reuse.
I'm not sure how TCP connections could cross over as you describe; I'm
pretty sure they can't. Which implies the connection is being
frequently remade, and to the wrong address... or something. Do you
have any more details on this problem?
The issue is entirely on the client side. When the client tries to make
the remote NSConnection using a new NSSocketPort (with SO_REUSEPORT)
with the same port # as a previously made NSSocketPort (with
SO_REUSEPORT), the NSConnection is "pointing" to the wrong server. I
guess this is because the NSSocketPort was set to be reused, and it's
reusing the address as well (even though the SO_REUSEADDR option is NOT
set).
Well.. the thought arises as to why you need to reuse the port all the
time... you're not creating a new server instance after each
connection are you?
Simple - if one user is using the program, logs out, and another logs
in and wants to use the same program, then the port needs to be reused.
If you need to serve different objects to different clients (i.e. one
'server' task per client connection)
No, that's not a requirement.
then you should setup a gateway object to server, which all clients
connect to initially, and then that can return a unique instance of
your tailor-made server object on the client's request.
That of course still won't help if you do have a valid reason to be
regularly tearing down your server, but I suspect this probably isn't
the case. Can you provide any more details as to what and how you're
trying to do things? Perhaps you can avoid the problems you're
experiencing by taking a slightly different approach.
Again, nothing unusual. It's just that the program is a user-level
thing and many of my customers use Mac OS X multiple users (not
necessarily Panther fast user switching, but that too). So when one
logs out while there's an active connection to a client, the server
quits normally but the OS doesn't have a way to know that the
connection is no longer valid, and so just waits 10 minutes before
terminating it. If another user logs in before this 10 minute period
and opens the program, trouble ensues.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.