Skip to content

Commit 329bd6e

Browse files
authored
Merge pull request #263 from IanButterworth/ib/cache_download_tweaks
Symbol caches: Larger download batching. Don't ask for non-General pkgs
2 parents 4c2d614 + d3f34d3 commit 329bd6e

File tree

3 files changed

+114
-13
lines changed

3 files changed

+114
-13
lines changed

src/SymbolServer.jl

Lines changed: 83 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,65 @@ mutable struct SymbolServerInstance
2727
end
2828
end
2929

30+
function get_general_pkgs()
31+
dp_before = copy(Base.DEPOT_PATH)
32+
try
33+
# because the env var JULIA_DEPOT_PATH is overritten this is probably the best
34+
# guess depot location
35+
push!(empty!(Base.DEPOT_PATH), joinpath(homedir(), ".julia"))
36+
@static if VERSION >= v"1.7-"
37+
regs = Pkg.Types.Context().registries
38+
i = findfirst(r -> r.name == "General" && r.uuid == UUID("23338594-aafe-5451-b93e-139f81909106"), regs)
39+
i === nothing && return Dict{UUID, PkgEntry}()
40+
return regs[i].pkgs
41+
else
42+
for r in Pkg.Types.collect_registries()
43+
(r.name == "General" && r.uuid == UUID("23338594-aafe-5451-b93e-139f81909106")) || continue
44+
reg = Pkg.Types.read_registry(joinpath(r.path, "Registry.toml"))
45+
return reg["packages"]
46+
end
47+
return Dict{UUID, PkgEntry}()
48+
end
49+
finally
50+
append!(empty!(Base.DEPOT_PATH), dp_before)
51+
end
52+
end
53+
54+
"""
55+
remove_non_general_pkgs!(pkgs)
56+
57+
Removes packages that aren't going to be on the symbol cache server because they aren't in the General registry.
58+
This avoids leaking private package name & uuid pairs via the url requests to the symbol server.
59+
60+
If the General registry cannot be found packages cannot be checked, so all packages will be removed.
61+
"""
62+
function remove_non_general_pkgs!(pkgs)
63+
general_pkgs = get_general_pkgs()
64+
if isempty(general_pkgs)
65+
@warn """
66+
Could not find the General registry when checking for whether packages are public.
67+
All package symbol caches will be generated locally"""
68+
return empty!(pkgs)
69+
end
70+
filter!(pkgs) do pkg
71+
packageuuid(pkg) === nothing && return false
72+
packagename(pkg) === nothing && return false
73+
tree_hash(pkg) === nothing && return false # stdlibs and dev-ed packages don't have tree_hash and aren't cached
74+
@static if VERSION >= v"1.7-"
75+
uuid_match = get(general_pkgs, packageuuid(pkg), nothing)
76+
uuid_match === nothing && return false
77+
uuid_match.name != packagename(pkg) && return false
78+
return true
79+
else
80+
uuid_match = get(general_pkgs, string(packageuuid(pkg)), nothing)
81+
uuid_match === nothing && return false
82+
uuid_match["name"] != packagename(pkg) && return false
83+
return true
84+
end
85+
end
86+
return pkgs
87+
end
88+
3089
function getstore(ssi::SymbolServerInstance, environment_path::AbstractString, progress_callback=nothing, error_handler=nothing; download = false)
3190
!ispath(environment_path) && return :success, recursive_copy(stdlibs)
3291

@@ -42,20 +101,33 @@ function getstore(ssi::SymbolServerInstance, environment_path::AbstractString, p
42101
if manifest !== nothing
43102
@debug "Downloading cache files for manifest at $(manifest_filename)."
44103
to_download = collect(validate_disc_store(ssi.store_path, manifest))
45-
batches = Iterators.partition(to_download, max(1, floor(Int, length(to_download)÷50)))
46-
for (i, batch) in enumerate(batches)
47-
percentage = round(Int, 100*(i - 1)/length(batches))
48-
progress_callback !== nothing && progress_callback("Downloading caches...", percentage)
49-
@sync for pkg in batch
50-
@async begin
51-
yield()
52-
uuid = packageuuid(pkg)
53-
get_file_from_cloud(manifest, uuid, environment_path, ssi.depot_path, ssi.store_path, download_dir, ssi.symbolcache_upstream)
54-
yield()
104+
try
105+
remove_non_general_pkgs!(to_download)
106+
catch err
107+
# if any errors, err on the side of caution and mark all as private, and continue
108+
@error """
109+
Symbol cache downloading: Failed to identify which packages to omit based on the General registry.
110+
All packages will be processsed locally""" err
111+
empty!(to_download)
112+
end
113+
if !isempty(to_download)
114+
n_done = 0
115+
n_total = length(to_download)
116+
for batch in Iterators.partition(to_download, 100) # 100 connections at a time
117+
@sync for pkg in batch
118+
@async begin
119+
yield()
120+
uuid = packageuuid(pkg)
121+
get_file_from_cloud(manifest, uuid, environment_path, ssi.depot_path, ssi.store_path, download_dir, ssi.symbolcache_upstream)
122+
yield()
123+
n_done += 1
124+
percentage = round(Int, 100*(n_done/n_total))
125+
progress_callback !== nothing && progress_callback("Downloading caches...", percentage)
126+
end
55127
end
56128
end
129+
progress_callback !== nothing && progress_callback("All cache files downloaded.", 100)
57130
end
58-
progress_callback !== nothing && progress_callback("All cache files downloaded.", 100)
59131
end
60132
end
61133
end

src/utils.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ else
143143
packageuuid(pkg::Pair{String,UUID}) = last(pkg)
144144
packageuuid(pkg::Pair{UUID,PackageEntry}) = first(pkg)
145145

146-
packagename(pkg::Pair{UUID,PackageEntry})::String = last(pkg).name
146+
packagename(pkg::Pair{UUID,PackageEntry})::Union{Nothing,String} = last(pkg).name
147147
packagename(c::Pkg.Types.Context, uuid::UUID) = manifest(c)[uuid].name
148148
packagename(manifest::Dict{UUID,PackageEntry}, uuid::UUID) = manifest[uuid].name
149149

@@ -162,7 +162,8 @@ else
162162
version(pe::Pair{UUID,PackageEntry}) = last(pe).version
163163
frommanifest(c::Pkg.Types.Context, uuid) = manifest(c)[uuid]
164164
frommanifest(manifest::Dict{UUID,PackageEntry}, uuid) = manifest[uuid]
165-
tree_hash(pe::PackageEntry) = VERSION >= v"1.3" ? pe.tree_hash : get(pe.other, "git-tree-sha1", nothing)
165+
tree_hash(pkg::Pair{UUID,PackageEntry}) = tree_hash(last(pkg))
166+
tree_hash(pe::PackageEntry) = VERSION >= v"1.3" ? pe.tree_hash : (pe.other === nothing ? nothing : get(pe.other, "git-tree-sha1", nothing))
166167

167168
is_package_deved(manifest, uuid) = manifest[uuid].path !== nothing
168169
end

test/runtests.jl

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,34 @@ end
146146
@test !isempty(SymbolServer.stdlibs[:Base][:VecOrMat].doc) # Union
147147
@test occursin("Cint", SymbolServer.stdlibs[:Base][:Cint].doc) # Alias
148148
end
149+
150+
if VERSION >= v"1.1-"
151+
@testset "Excluding private packages from cache download requests" begin
152+
pkgs = Dict{Base.UUID, Pkg.Types.PackageEntry}()
153+
if VERSION < v"1.3-"
154+
pkgs[UUID("7876af07-990d-54b4-ab0e-23690620f79a")] = Pkg.Types.PackageEntry(name="Example", other=Dict("git-tree-sha1" => Base.SHA1("0"^40)))
155+
pkgs[UUID("3e13f8c9-a9aa-412e-8b2a-fda000b375e2")] = Pkg.Types.PackageEntry(name="NotInGeneral", other=Dict("git-tree-sha1" => Base.SHA1("0"^40)))
156+
pkgs[UUID("eb4ab7d2-1172-48bd-a954-ae6825f2e6e3")] = Pkg.Types.PackageEntry(other=Dict("git-tree-sha1" => Base.SHA1("0"^40))) # no name
157+
pkgs[UUID("1fec9e91-426f-45f4-a317-da8b2730f864")] = Pkg.Types.PackageEntry(name="NoTreeHash") # no tree_hash, like stdlibs
158+
else
159+
pkgs[UUID("7876af07-990d-54b4-ab0e-23690620f79a")] = Pkg.Types.PackageEntry(name="Example", tree_hash=Base.SHA1("0"^40))
160+
pkgs[UUID("3e13f8c9-a9aa-412e-8b2a-fda000b375e2")] = Pkg.Types.PackageEntry(name="NotInGeneral", tree_hash=Base.SHA1("1"^40))
161+
pkgs[UUID("eb4ab7d2-1172-48bd-a954-ae6825f2e6e3")] = Pkg.Types.PackageEntry(tree_hash=Base.SHA1("2"^40)) # no name
162+
pkgs[UUID("1fec9e91-426f-45f4-a317-da8b2730f864")] = Pkg.Types.PackageEntry(name="NoTreeHash") # no tree_hash, like stdlibs
163+
end
164+
165+
SymbolServer.remove_non_general_pkgs!(pkgs)
166+
167+
@test length(pkgs) == 1
168+
@test haskey(pkgs, UUID("7876af07-990d-54b4-ab0e-23690620f79a"))
169+
@test pkgs[UUID("7876af07-990d-54b4-ab0e-23690620f79a")].name == "Example"
170+
if VERSION < v"1.3"
171+
@test pkgs[UUID("7876af07-990d-54b4-ab0e-23690620f79a")].other["git-tree-sha1"] == Base.SHA1("0"^40)
172+
else
173+
@test pkgs[UUID("7876af07-990d-54b4-ab0e-23690620f79a")].tree_hash == Base.SHA1("0"^40)
174+
end
175+
end
176+
end
149177
end
150178

151179
using SymbolServer: FakeTypeName

0 commit comments

Comments
 (0)