[Twisted-Python] How to stop reactor when execution finishes on more than one ssh server?
Hi, in the sample sshsimpleclient.py, it demostrated how to connect to a ssh server and issue a command. my question is what should I do if I want to connect to more than one ssh server. I did try to create more than one SimpleTransport by using the following code HOSTS=[host1, host2, host3] protocol.ClientCreator(reactor, SimpleTransport).connectTCP(host1, 22) protocol.ClientCreator(reactor, SimpleTransport).connectTCP(host2, 22) protocol.ClientCreator(reactor, SimpleTransport).connectTCP(host3, 22) reactor.run() this really behaves as what i expected, and executed the command on all remote hosts, but after it finishes, i just hangs there, I know I need a place to call something like reactor.stop() when all transport finishes the execution. but i do not know where to call it, need some deffereds? and how? thanks very much! James
On Sun, 30 Sep 2007 01:08:52 +0800, James Deng <jtdeng@gmail.com> wrote:
Hi, in the sample sshsimpleclient.py, it demostrated how to connect to a ssh server and issue a command. my question is what should I do if I want to connect to more than one ssh server.
I did try to create more than one SimpleTransport by using the following code
HOSTS=[host1, host2, host3] protocol.ClientCreator(reactor, SimpleTransport).connectTCP(host1, 22) protocol.ClientCreator(reactor, SimpleTransport).connectTCP(host2, 22) protocol.ClientCreator(reactor, SimpleTransport).connectTCP(host3, 22) reactor.run()
this really behaves as what i expected, and executed the command on all remote hosts, but after it finishes, i just hangs there, I know I need a place to call something like reactor.stop() when all transport finishes the execution. but i do not know where to call it, need some deffereds? and how?
First, you need to know when a single connection is finished. If what you are interested in is a channel being closed, then the appropriate callback is SSHChannel.closed, as sshsimpleclient.py demonstrates. Then you need for that information to be relayed to the code which is responsible for knowing that at some point the reactor should be stopped. sshsimpleclient.py is not a good example of this, since with its approach to this, when a CatChannel is disconnected, the reactor will always be stopped. This makes CatChannel inappropriate for use in any real program. Instead, you may want to callback a Deferred in your closed implementation. The Deferred might be one which was supplied to your channel's constructor and was ultimately created by the same code which knows that the reactor needs to be stopped. Finally, you need to aggregate multiple Deferreds into one. You can do this using twisted.internet.defer.gatherResults, which takes a list of Deferreds and returns a Deferred which will be called back when all of the inputs have been called back. You can pass the Deferred for each of your channels to gatherResults and add a callback to the returned Deferred which stops the reactor. So, for example (not runnable): hosts = [host1, host2, host3] closedDeferreds = [] for host in hosts: d = Deferred() closedDeferreds.append(d) ClientCreator(reactor, SimpleTransport, d).connectTCP(host, 22) gatherResults(closedDeferreds).addCallback(lambda ignored: reactor.stop()) reactor.run() Jean-Paul
participants (2)
-
James Deng
-
Jean-Paul Calderone