def METHOD_NAME(self, timeout=-1):
    """
    joins the worker agents.
    The caller will be blocked until exceeding the timeout or all worker agents finish their jobs.
    """
    # check the number of alive threads
    try:
        t1 = time.time()
        while self.__cnt_alive_threads__() > 0:
            t2 = time.time()
            # break the loop if exceeding the timeout
            if timeout >= 0 and t2 - t1 > timeout:
                break
            else:
                # sleep for another 0.5 second
                time.sleep(0.5)
    except KeyboardInterrupt:
        self.logger.error(
            'Keyboard interruption on MTRunner: %s' % self.name)