Lundy
Lundy

Reputation: 673

Twisted Conch Shell: blocking executable

I have a working SSH Shell server, and I am trying to create a command (class of commands) that acts like 'ping', printing out some data every few seconds.

The shell looks up executables for received commands, instantiates them with the given args and runs them:

def lineReceived(self, lines):
    ...
    self.resume(None)

def run_cmd_stack(self):
    cmd = self.cmd_stack.pop()
    exe = self.get_executable(cmd)
    exe.run()

def resume(self, ret):
    """Used by Executables to signal their completion
    """
    self.RET = ret
    if len(self.cmd_stack) > 0:
        self.run_cmd_stack()
    else:
        self.showPrompt()

This code works, but it feels wrong:

class Executable(object):
    def __init__(self, shell_protocol, cmd, reactor):
        self.shell = shell_protocol
        self.reactor = reactor

    def end(self, ret):
        self.shell.resume(ret)


class exe_wait(Executable):
    name = 'wait'

    def run(self):
        i = int(self.args[0])
        self.loopy(i)
        return 0

    def loopy(self, i):
        d = defer.Deferred()
        if i > 0:
            self.shell.writeln("waiting...")
            d.addCallback(self.loopy)
            self.reactor.callLater(1, d.callback, i-1)
        else:
            d.addCallback(self.end)
            d.callback(0)
  1. I dont particularly like having to pass the reactor in as an argument, just so that I can test it with trial, but I couldn't figure out how to inject it just for testing.
  2. I feel like having the executable call the shell's "resume()" method is ugly, and I should be able to have the exe just 'return 0' when its done. The problem i've run into is that the shell just runs off and prints its prompt instead of waiting for the deferred.

Of all the methods i've tried, this is the only one i can get to work properly, so I'd really appreciate any advice I can get.

Upvotes: 1

Views: 92

Answers (0)

Related Questions