{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 ArialMT;} {\colortbl;\red255\green255\blue255;} \paperw11900\paperh16840\margl1440\margr1440\vieww17580\viewh12700\viewkind0 \deftab720 \pard\pardeftab720\ql\qnatural \f0\fs26 \cf0 \ DistributedObjectsText.xcodeproj is a minimal test case for recreating a problem with "connection went invalid while waiting for a reply" appearing on the console during a delayed callback from server to client when using distributed objects (see http://www.cocoabuilder.com/archive/message/cocoa/2008/7/9/212363)\ \ The full application presents a master-detail interface for a collection of hosts. Part of the detail interface is the status of an SSH connection which is automatically attempted for each host. The app uses NSTask to spawn instances of OpenSSH; in case a password is required, it passes the location of a helper tool 'async_askpass' for the environment variable SSH_ASKPASS, along with a unique token to identify the object responsible for handling that host.\ \ async_askpass uses Distributed Objects to get in touch with the application proper so that the password input (or key verification) UI can be shown in the appropriate detail interface. This UI is not modal, so async_askpass sits in its run loop waiting for a response.\ \ In this test project, the classes AsyncAskPassServer and AsyncAskPassClient are identical to those in the real project (except for the code within #ifdef DISTRIBUTED_OBJECTS_TEST_CODEPATH blocks -- see below), and the class WaitingForPasswordController has been changed only to have an outlet directly to its member variable "proxy", rather than obtaining it indirectly through file's owner (in the real app it is instantiated in a nib handled by an NSViewController). FakeAppDelegate exists purely to instantiate the AsyncAskPassServer, which happens in the real app's delegate; FakeProxy is the stand-in model object for the question text and answer target (in the real app, the proxy handles a bit more). And obviously, the UI in the test app is a lot more basic!\ \ When you run the app, it NSLogs a token for async_askpass, e.g.:\ \ 2008-07-09 23:11:12.111 DistributedObjectsTest[17340:10b] AsyncAskPassToken=7E591D24-C816-44E7-8513-15081E394E18\ \ You pass this as an environment variable to async_askpass, like so:\ \ $ AsyncAskPassToken=7E591D24-C816-44E7-8513-15081E394E18 DistributedObjectsTest/build/Debug/async_askpass "some question or other"\ \ You should see "some question or other" appear in the UI. If you type something into the password field and press "OK", it appears as the output to async_askpass -- i.e., the whole thing works -- but the message about the connection going invalid appears in the app's console. On my machine, the reconnection happens pretty quickly in this test project, but takes a second or more (blocking) in my real app.\ \ (By the way, I am aware that my code is leaking tokens. I plan to implement some robust spring cleaning code later -- it currently leaks processes sometimes, too!)\ \ The answerTarget is retained in just the same way (using a synthesized property) by the real proxy.\ \ For testing purposes, there is a switch statement in AsyncAskPassClient which automates the callback in various ways. On my development machine, of the 6 methods the first 4 work without the "connection went invalid" message, and the last two always generate it.\ \ Any insights gratefully appreciated!\ \ Thanks,\ Hamish\ }