title: twisted client call from a library function
body: <p>I'm trying to implement a function that will act as a Twisted client. It's called from code I don't have control over. I tried something like (this taken from the pbsimpleclient.py example code):</p>
  
  <pre><code># Copyright (c) Twisted Matrix Laboratories.
  # See LICENSE for details.
  
  
  from twisted.spread import pb
  from twisted.internet import reactor
  from twisted.python import util
  
  def remcall(**kw):
      factory = pb.PBClientFactory()
      reactor.connectTCP("localhost", 8789, factory)
      d = factory.getRootObject()
      # kw here is what's passed in via remcall
      d.addCallback(lambda object: object.callRemote("echo", kw))
      d.addCallback(lambda echo: 'server echoed: '+repr(echo))
      d.addErrback(lambda reason: 'error: '+str(reason.value))
      d.addCallback(util.println)
      d.addCallback(lambda _: reactor.stop())
      reactor.run()
  </code></pre>
  
  <p>And the caller would make a call like:</p>
  
  <pre><code>remcall(hello=1, world=2)
  remcall(hi=3, there=4)
  </code></pre>
  
  <p>But as you may have guessed, it gives a "twisted.internet.error.ReactorNotRestartable" error.</p>
  
  <p>What's the best way to do this? I'm not so worried about getting a response from the remote end, but I should know if it's failing and why.</p>