class Client(object):
    '''An agent that connects to an external host and provides an API to
    return data based on a protocol across that host.
    '''
    def __init__(self, connection_handler=None):
        self.connection_handler = connection_handler or self.client_conn_handler
        self.jobs = deque()
        self.conn = None
     
    def connect(self, addr, port):  
        '''Connect to a remote host.
        '''
        remote_addr = (addr, port)
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect(remote_addr)
        from diesel.core import Connection
        self.conn = Connection(sock, (addr, port), self.client_conn_handler)
        self.conn.iterate()

    def close(self):
        '''Close the socket to the remote host.
        '''
        self.conn = None

    @property
    def is_closed(self):
        return self.conn is None

    def client_conn_handler(self, addr):
        '''The default connection handler.  Handles @call-ing
        behavior to client API methods.
        '''
        from diesel.core import sleep, ConnectionClosed
        yield self.on_connect()

        while True:
            try:
                if not self.jobs:
                    yield sleep()
                if not self.jobs:
                    continue
                mygen = self.jobs.popleft()
                yield mygen
            except ConnectionClosed:
                self.close()
                self.on_close()
                break

    def on_connect(self):
        '''Hook to implement a handler to do any setup after the
        connection has been established.
        '''
        if 0: yield 0

    def on_close(self):
        '''Hook called when the remote side closes the connection,
 def connect(self, addr, port):  
     '''Connect to a remote host.
     '''
     remote_addr = (addr, port)
     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     sock.connect(remote_addr)
     from diesel.core import Connection
     self.conn = Connection(sock, (addr, port), self.client_conn_handler)
     self.conn.iterate()