':param url:
:type url:
:return:
:rtype:'

@gen.coroutine
def _fetch(self, url):

    fetch_result = FetchResult()
    storage = self.context.modules.storage
    (yield self.acquire_url_lock(url))
    try:
        fetch_result.buffer = (yield gen.maybe_future(storage.get(url)))
        mime = None
        if (fetch_result.buffer is not None):
            self.release_url_lock(url)
            fetch_result.successful = True
            self.context.metrics.incr('storage.hit')
            mime = BaseEngine.get_mimetype(fetch_result.buffer)
            self.context.request.extension = EXTENSION.get(mime, '.jpg')
            if ((mime == 'image/gif') and self.context.config.USE_GIFSICLE_ENGINE):
                self.context.request.engine = self.context.modules.gif_engine
            else:
                self.context.request.engine = self.context.modules.engine
            raise gen.Return(fetch_result)
        else:
            self.context.metrics.incr('storage.miss')
        loader_result = (yield self.context.modules.loader.load(self.context, url))
    finally:
        self.release_url_lock(url)
    if isinstance(loader_result, LoaderResult):
        if (not loader_result.successful):
            fetch_result.buffer = None
            fetch_result.loader_error = loader_result.error
            raise gen.Return(fetch_result)
        fetch_result.buffer = loader_result.buffer
    else:
        fetch_result.buffer = loader_result
    if (fetch_result.buffer is None):
        raise gen.Return(fetch_result)
    fetch_result.successful = True
    if (mime is None):
        mime = BaseEngine.get_mimetype(fetch_result.buffer)
    self.context.request.extension = extension = EXTENSION.get(mime, '.jpg')
    original_preserve = self.context.config.PRESERVE_EXIF_INFO
    try:
        if ((mime == 'image/gif') and self.context.config.USE_GIFSICLE_ENGINE):
            self.context.request.engine = self.context.modules.gif_engine
        else:
            self.context.request.engine = self.context.modules.engine
        self.context.request.engine.load(fetch_result.buffer, extension)
        if (self.context.request.engine.image is None):
            fetch_result.successful = False
            fetch_result.buffer = None
            fetch_result.engine = self.context.request.engine
            fetch_result.engine_error = EngineResult.COULD_NOT_LOAD_IMAGE
            raise gen.Return(fetch_result)
        fetch_result.normalized = self.context.request.engine.normalize()
        storage = self.context.modules.storage
        is_no_storage = isinstance(storage, NoStorage)
        is_mixed_storage = isinstance(storage, MixedStorage)
        is_mixed_no_file_storage = (is_mixed_storage and isinstance(storage.file_storage, NoStorage))
        if (not (is_no_storage or is_mixed_no_file_storage)):
            self.context.config = copy.deepcopy(self.context.config)
            self.context.config.PRESERVE_EXIF_INFO = True
            fetch_result.buffer = self.context.request.engine.read(extension)
            storage.put(url, fetch_result.buffer)
        storage.put_crypto(url)
    except Exception:
        fetch_result.successful = False
    finally:
        self.context.config.PRESERVE_EXIF_INFO = original_preserve
        if (not fetch_result.successful):
            raise
        fetch_result.buffer = None
        fetch_result.engine = self.context.request.engine
        raise gen.Return(fetch_result)
