def __init__(self, options, log, stable_name, pinger=None, resolver=None): """Create a cache factory from settings. :param options: Task's scoped options. :param log: Task's context log. :param stable_name: Task's stable name. :param pinger: Pinger to choose the best remote artifact cache URL. :param resolver: Resolver to look up remote artifact cache URLs. :return: cache factory. """ self._options = options self._log = log self._stable_name = stable_name # Created on-demand. self._read_cache = None self._write_cache = None # Protects local filesystem setup, and assignment to the references above. self._cache_setup_lock = threading.Lock() # Caches are supposed to be close, and we don't want to waste time pinging on no-op builds. # So we ping twice with a short timeout. # TODO: Make lazy. self._pinger = pinger or Pinger(timeout=self._options.pinger_timeout, tries=self._options.pinger_tries) # resolver is also close but failing to resolve might have broader impact than # single ping failure, therefore use a higher timeout with more retries. self._resolver = resolver or \ (RESTfulResolver(timeout=1.0, tries=3) if self._options.resolver == 'rest' else \ NoopResolver())