docs: def retry(fn, max_retries=10, warning_msg=None, fallback_result=None):
      """
      Minimalistic retry strategy to compensate for failures probably caused by a thread-safety bug in scikit-learn:
      * https://github.com/scikit-learn/scikit-learn/issues/2755
      * https://github.com/scikit-learn/scikit-learn/issues/7346
  
      :param fn: the function to retry.
      :param max_retries: the maximum number of retries to attempt.
      :param warning_msg: a warning message to display when an attempt fails.
      :param fallback_result: result to return when all attempts fail.
      :return: Returns the result of fn if one attempt succeeds, else return fallback_result.
      """
      nr_retries = 0
  
      result = fallback_result
  
      for attempt in range(max_retries):
          try:
              result = fn()
          except Exception as cause:
              nr_retries += 1
  
              msg_head = '' if warning_msg is None else repr(warning_msg) + ' '
              msg_tail = "Retry ({1}/{2}). Failure caused by {0}.".format(repr(cause), nr_retries, max_retries)
  
              logger.warning(msg_head + msg_tail)
          else:
              break
  
      return result