Creates a new thread pool with the given name.

    If the thread pool of this name already exist, we just return the existing
    one. This allows us to have different pools with different characteristics
    used by different parts of the code, at the same time.

    Args:
      name: The name of the required pool.
      min_threads: The number of threads in the pool.
      max_threads: The maximum number of threads to grow the pool to. If not set
        we do not grow the pool.

    Returns:
      A threadpool instance.

def Factory(cls, name, min_threads, max_threads=None):
    """Creates a new thread pool with the given name.

    If the thread pool of this name already exist, we just return the existing
    one. This allows us to have different pools with different characteristics
    used by different parts of the code, at the same time.

    Args:
      name: The name of the required pool.
      min_threads: The number of threads in the pool.
      max_threads: The maximum number of threads to grow the pool to. If not set
        we do not grow the pool.

    Returns:
      A threadpool instance.
    """
    with cls.factory_lock:
      result = cls.POOLS.get(name)
      if result is None:
        cls.POOLS[name] = result = cls(
            name, min_threads, max_threads=max_threads)

      return result