On 11 Mar 2006, at 15:44, Brian Granger wrote:
Here is a typical (madeup) usage case:
a = TwistedEnabledObject() a.connect(addr) # This uses reactor.connectTCP to connect to a server myresult = a.computeSomethingUsingTwisted(args) # This should block!!! ...and maybe... y = f(myresult) plot(y)
The key point is that the user will want to direclty use myresult interactively. Also they won't know ahead of time what actions they will want to do. Anyone who has used Matlab or Mathematica (scientists) will find this way of working extremely familiar. There is simply no way that users will want to get a Deferred() and add callbacks to trigger actions. Thus I would argue that I DO want to make my properly written asynchronous code blocking.
It sounds like this is a user-interface problem rather than a software-design problem. A common tool for solving such problems is to ask, "What does other, similar software do?". It occurs to me that the problem you're facing is not unlike, oh, job- control in bash or zsh. I'd imagine a usage case that looks something like this:
a = TwistedEnabledObject() a.connect(addr) [1] TwistedEnabledObject.connect(self, addr) [1] done TwistedEnabledObject.connect(self, addr) result1 = a.computeSomethingUsingTwisted(args) [1] TwistedEnabledObject.computeSomethingUsingTwisted(args) result2 = a.computeSomeOtherThingUsingTwisted(args) [2] TwistedEnabledObject.computeSomeOtherThingUsingTwisted(args) print 1+3 4 jobs() [1] running TwistedEnabledObject.computeSomethingUsingTwisted(args) [2] running TwistedEnabledObject.computeSomeOtherThingUsingTwisted(args) print repr(result1) <deferredResult (waiting for result)> [1] done TwistedEnabledObject.computeSomethingUsingTwisted(args) print repr(result1) <deferredResult with value: 42> print result.value 42
I think I'd appreciate an environment like that more than an environment that made me wait for things all the time. I don't know if it's possible to achieve with your PyCrust/Twisted hybrid, of course.