Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def post(request)
end

# Depsolve!
solved = depsolve(request, desired_versions.keys, desired_versions, environment_constraints)
solved, cookbook_obj_cache = depsolve(request, desired_versions.keys, desired_versions, environment_constraints)
unless solved
if @last_missing_dep && !cookbook_names.include?(@last_missing_dep)
return raise RestErrorResponse.new(412, "No such cookbook: #{@last_missing_dep}")
Expand All @@ -50,23 +50,31 @@ def post(request)

result = {}
solved.each_pair do |name, versions|
cookbook = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ["cookbooks", name, versions[0]]))
if cookbook_obj_cache.dig(name, versions[0])
cookbook = cookbook_obj_cache[name][versions[0]]
else
cookbook = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ["cookbooks", name, versions[0]]))
end
result[name] = ChefData::DataNormalizer.normalize_cookbook(self, request.rest_path[0..1], cookbook, name, versions[0], request.base_uri, "MIN", false, api_version: request.api_version)
end
json_response(200, result)
end

def depsolve(request, unsolved, desired_versions, environment_constraints)
def depsolve(request, unsolved, desired_versions, environment_constraints, cookbook_obj_cache = nil)
desired_versions.each do |cb, ver|
if ver.empty?
@last_constraint_failure = cb
return nil
return [nil, nil]
end
end

# If everything is already
solve_for = unsolved[0]
return desired_versions unless solve_for
return [desired_versions, cookbook_obj_cache] unless solve_for

# Cache the get_data calls - this saves the need to run the get_data call a second time in #post
# Conceptually: cache[cookbook][version] = cookbook_object
cookbook_obj_cache ||= {}

# Go through each desired version of this cookbook, starting with the latest,
# until we find one we can solve successfully with
Expand All @@ -77,6 +85,8 @@ def depsolve(request, unsolved, desired_versions, environment_constraints)

# Pick this cookbook, and add dependencies
cookbook_obj = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ["cookbooks", solve_for, desired_version]))
cookbook_obj_cache[solve_for] ||= {}
cookbook_obj_cache[solve_for][desired_version] = cookbook_obj
cookbook_metadata = cookbook_obj["metadata"] || {}
cookbook_dependencies = cookbook_metadata["dependencies"] || {}
dep_not_found = false
Expand All @@ -100,10 +110,10 @@ def depsolve(request, unsolved, desired_versions, environment_constraints)
next if dep_not_found

# Depsolve children with this desired version! First solution wins.
result = depsolve(request, new_unsolved, new_desired_versions, environment_constraints)
return result if result
result, cookbook_obj_cache = depsolve(request, new_unsolved, new_desired_versions, environment_constraints, cookbook_obj_cache)
return [result, cookbook_obj_cache] if result
end
nil
[nil, nil]
end

def sort_versions(versions)
Expand Down
Loading