Skip to content

Commit 9321ed6

Browse files
Merge pull request #363 from dafyddcrosby/EnvironmentCookbookVersionsEndpoint_cookbook_obj_cache
[EnvironmentCookbookVersionsEndpoint] Use cookbook_obj_cache in depsolve before calling get_data
2 parents dc44538 + cb51bd7 commit 9321ed6

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

lib/chef_zero/endpoints/environment_cookbook_versions_endpoint.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ def depsolve(request, unsolved, desired_versions, environment_constraints, cookb
8484
new_unsolved = unsolved[1..-1]
8585

8686
# Pick this cookbook, and add dependencies
87-
cookbook_obj = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ["cookbooks", solve_for, desired_version]))
87+
cookbook_obj = cookbook_obj_cache.dig(solve_for, desired_version) ||
88+
FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ["cookbooks", solve_for, desired_version]))
8889
cookbook_obj_cache[solve_for] ||= {}
8990
cookbook_obj_cache[solve_for][desired_version] = cookbook_obj
9091
cookbook_metadata = cookbook_obj["metadata"] || {}
@@ -110,7 +111,8 @@ def depsolve(request, unsolved, desired_versions, environment_constraints, cookb
110111
next if dep_not_found
111112

112113
# Depsolve children with this desired version! First solution wins.
113-
result, cookbook_obj_cache = depsolve(request, new_unsolved, new_desired_versions, environment_constraints, cookbook_obj_cache)
114+
result, returned_cache = depsolve(request, new_unsolved, new_desired_versions, environment_constraints, cookbook_obj_cache)
115+
cookbook_obj_cache = returned_cache || cookbook_obj_cache
114116
return [result, cookbook_obj_cache] if result
115117
end
116118
[nil, nil]

spec/endpoints/environment_cookbook_versions_endpoint_spec.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,42 @@ def cookbook_json(name, version, dependencies = {})
362362
expect(result).to be_nil
363363
end
364364

365+
it "uses cached cookbook data instead of re-fetching during backtracking" do
366+
desired = {
367+
"web" => ["1.0.0", "2.0.0"],
368+
"db" => ["1.0.0"],
369+
}
370+
# web 2.0.0 depends on lib, which depends on missing (doesn't exist) → branch fails
371+
# web 1.0.0 has no deps → backtracks here, db must be re-solved
372+
# db 1.0.0 should be fetched only once (cached from the first branch)
373+
allow(data_store).to receive(:get)
374+
.with(org_prefix + ["cookbooks", "web", "2.0.0"], request)
375+
.and_return(cookbook_json("web", "2.0.0", { "lib" => ">= 1.0.0" }))
376+
allow(data_store).to receive(:get)
377+
.with(org_prefix + ["cookbooks", "web", "1.0.0"], request)
378+
.and_return(cookbook_json("web", "1.0.0"))
379+
expect(data_store).to receive(:get)
380+
.with(org_prefix + ["cookbooks", "db", "1.0.0"], request)
381+
.once
382+
.and_return(cookbook_json("db", "1.0.0"))
383+
allow(data_store).to receive(:exists_dir?)
384+
.with(org_prefix + %w{cookbooks lib})
385+
.and_return(true)
386+
allow(data_store).to receive(:list)
387+
.with(org_prefix + %w{cookbooks lib})
388+
.and_return(["1.0.0"])
389+
allow(data_store).to receive(:get)
390+
.with(org_prefix + ["cookbooks", "lib", "1.0.0"], request)
391+
.and_return(cookbook_json("lib", "1.0.0", { "missing" => ">= 1.0.0" }))
392+
allow(data_store).to receive(:exists_dir?)
393+
.with(org_prefix + %w{cookbooks missing})
394+
.and_return(false)
395+
396+
result, _cache = endpoint.depsolve(request, %w{web db}, desired, {})
397+
expect(result["web"]).to eq(["1.0.0"])
398+
expect(result["db"]).to eq(["1.0.0"])
399+
end
400+
365401
it "resolves a deep dependency chain" do
366402
desired = { "app" => ["1.0.0"] }
367403
allow(data_store).to receive(:get)

0 commit comments

Comments
 (0)