'Wait for the given service to be available on the specified port.
Args:
service_name: [string] The service name we we are waiting on.
port: [int] The remote port the service is at.
timeout: [int] How much time to wait before giving up.
Returns:
The ForwardedPort entry for this service.'

def wait_on_service(self, service_name, port=None, timeout=240):

    try:
        with self.__lock:
            forwarding = self.__forwarded_ports.get(service_name)
            if (forwarding is None):
                forwarding = self.__forward_port_to_service(service_name)
            self.__forwarded_ports[service_name] = forwarding
    except Exception as ex:
        logging.exception('Exception    while    attempting    to    forward    ports    to    "%s"', service_name)
        raise
    end_time = (time.time() + timeout)
    logging.info('Waiting    on    "%s..."', service_name)
    if (port is None):
        port = self.__service_port_map[service_name]
    time.sleep(1)
    threadid = hex(threading.current_thread().ident)
    count = 0
    while (forwarding.child.poll() is None):
        try:
            logging.info('WaitOn    polling    %s    |    %s', service_name, threadid)
            urllib2.urlopen('http://localhost:{port}/health'.format(port=forwarding.port), timeout=20)
            logging.info('"%s"    is    ready    on    port    %d    |    %s', service_name, forwarding.port, threadid)
            return forwarding
        except urllib2.HTTPError as error:
            logging.warning('%s    got    %s.    Ignoring    that    for    now.', service_name, error)
            return forwarding
        except (urllib2.URLError, Exception) as error:
            if ((count % 5) == 0):
                logging.info('WaitOn    got    %s    |    %s', error, threadid)
            count += 1
            if (time.time() >= end_time):
                logging.error('Timing    out    waiting    for    %s    |    %s', service_name, threadid)
                raise error
            time.sleep(2.0)
    logging.error('It    appears    %s    is    no    longer    available.    Perhaps    the    tunnel    closed.', service_name)
    raise RuntimeError('It    appears    that    {0}    failed'.format(service_name))
