class_docstr: Interface for FiftyOne services.
  
  All services must define a ``command`` property.
  
  Services are run in an isolated Python subprocess (see ``service/main.py``)
  to ensure that they are shut down when the main Python process exits. The
  ``command`` and ``working_dir`` properties control the execution of the
  service in the subprocess.
class_docstr_tok: ["Interface","for","FiftyOne","services",".","All","services","must","define","a","``","command","``","property",".","Services","are","run","in","an","isolated","Python","subprocess","(","see","``","service\/main.py","``",")","to","ensure","that","they","are","shut","down","when","the","main","Python","process","exits",".","The","``","command","``","and","``","working_dir","``","properties","control","the","execution","of","the","service","in","the","subprocess","."]
docstr: Waits for any child process of this service to bind to a TCP port.
  
  Args:
      port (None): if specified, wait for a child to bind to this port
      timeout (60): the number of seconds to wait before failing
  
  Returns:
      the port the child has bound to (equal to the ``port`` argument
      if specified)
  
  Raises:
      ServiceListenTimeout: if the timeout was exceeded
code: def _wait_for_child_port(self, port=None, timeout=60):
      """Waits for any child process of this service to bind to a TCP port.
  
      Args:
          port (None): if specified, wait for a child to bind to this port
          timeout (60): the number of seconds to wait before failing
  
      Returns:
          the port the child has bound to (equal to the ``port`` argument
          if specified)
  
      Raises:
          ServiceListenTimeout: if the timeout was exceeded
      """
  
      @retry(
          wait_fixed=250,
          stop_max_delay=1000 * timeout,
          retry_on_exception=lambda e: isinstance(
              e, ServiceListenTimeout
          ),
      )
      def find_port():
          for child in fosu.normalize_wrapper_process(
              self.child
          ).children(recursive=True):
              try:
                  for local_port in fosu.get_listening_tcp_ports(child):
                      if port is None or port == local_port:
                          return local_port
  
              except psutil.Error:
                  pass
  
          raise ServiceListenTimeout(etau.get_class_name(self), port)
  
      return find_port()
  
imports: import logging
  import os
  import subprocess
  import sys
  import psutil
  import requests
  from retrying import retry
  import eta.core.utils
  import fiftyone.constants
  import fiftyone.core.config
  import fiftyone.core.context
  import fiftyone.service.util
label_desc: Use image node_id 9 for calling the Service obj's underlying member method code with example usage: obj._wait_for_child_port(port, timeout) and returns: find_port, local_port