Skip to content

Commit

Permalink
Feature/remote caching (#17449)
Browse files Browse the repository at this point in the history
Co-authored-by: Abril Rincón Blanco <[email protected]>
  • Loading branch information
memsharded and AbrilRBS authored Dec 23, 2024
1 parent d7ff114 commit ef5d9d5
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 2 deletions.
4 changes: 4 additions & 0 deletions conan/api/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def __init__(self, name, url, verify_ssl=True, disabled=False, allowed_packages=
self.disabled = disabled
self.allowed_packages = allowed_packages
self.remote_type = remote_type
self.caching = {}

def __eq__(self, other):
if other is None:
Expand All @@ -45,6 +46,9 @@ def __str__(self):
def __repr__(self):
return str(self)

def invalidate_cache(self):
self.caching = {}


class MultiPackagesList:
def __init__(self):
Expand Down
17 changes: 15 additions & 2 deletions conans/client/remote_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,13 @@ def _get_package(self, layout, pref, remote, scoped_output, metadata):
raise

def search_recipes(self, remote, pattern):
return self._call_remote(remote, "search", pattern)
cached_method = remote.caching.setdefault("search_recipes", {})
try:
return cached_method[pattern]
except KeyError:
result = self._call_remote(remote, "search", pattern)
cached_method[pattern] = result
return result

def search_packages(self, remote, ref):
packages = self._call_remote(remote, "search_packages", ref)
Expand Down Expand Up @@ -234,7 +240,14 @@ def get_latest_package_reference(self, pref, remote, info=None) -> PkgReference:
if k in ("shared", "fPIC", "header_only")]
if options:
headers['Conan-PkgID-Options'] = ';'.join(options)
return self._call_remote(remote, "get_latest_package_reference", pref, headers=headers)

cached_method = remote.caching.setdefault("get_latest_package_reference", {})
try:
return cached_method[pref]
except KeyError:
result = self._call_remote(remote, "get_latest_package_reference", pref, headers=headers)
cached_method[pref] = result
return result

def get_recipe_revision_reference(self, ref, remote) -> bool:
assert ref.revision is not None, "recipe_exists needs a revision"
Expand Down
50 changes: 50 additions & 0 deletions test/integration/command_v2/custom_commands_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,3 +419,53 @@ def mycommand(conan_api, parser, *args, **kwargs):
c.run("export .")
c.run("mycommand myremote myurl")
assert json.loads(c.stdout) == {"myremote": "myurl"}


class TestCommandsRemoteCaching:
def test_remotes_cache(self):
complex_command = textwrap.dedent("""
import json
from conan.cli.command import conan_command
from conan.api.output import ConanOutput
@conan_command()
def mycache(conan_api, parser, *args, **kwargs):
\""" this is a command with subcommands \"""
remotes = conan_api.remotes.list()
host = conan_api.profiles.get_profile(["default"])
build = conan_api.profiles.get_profile(["default"])
deps_graph = conan_api.graph.load_graph_requires(["pkg/0.1"], None, host, build,
None, remotes, None, None)
conan_api.graph.analyze_binaries(deps_graph, None, remotes=remotes)
# SECOND RUN!!!
# This will break if the caching is not working
remotes[0].url = "broken"
deps_graph = conan_api.graph.load_graph_requires(["pkg/0.1"], None, host, build,
None, remotes, None, None)
conan_api.graph.analyze_binaries(deps_graph, None, remotes=remotes)
# Now invalidate the cache and see how it breaks
try:
remotes[0].invalidate_cache()
deps_graph = conan_api.graph.load_graph_requires(["pkg/0.1"], None, host, build,
None, remotes, None, None)
conan_api.graph.analyze_binaries(deps_graph, None, remotes=remotes)
except Exception as e:
ConanOutput().warning(f"Cache invalidated, as expected: {e}")
""")

c = TestClient(default_server_user=True)
c.save_home({"extensions/commands/cmd_mycache.py": complex_command})

c.save({"dep/conanfile.py": GenConanfile("dep", "0.1"),
"pkg/conanfile.py": GenConanfile("pkg", "0.1").with_require("dep/0.1")})
c.run("create dep")
c.run("create pkg")
c.run("upload * -r=default -c")
c.run("remove * -c")
c.run("mycache")
# Does not break unexpectedly, caching is working
assert "WARN: Cache invalidated, as expected: Invalid URL 'broken" in c.out

0 comments on commit ef5d9d5

Please sign in to comment.