Skip to content

Commit 42a33bb

Browse files
authored
remove log spamming from precompilepkg code (#59652)
Improves consistency between serial and parallel code and reduces useless log spamming. Logging messages should convey useful content actionable in some form by the user. Neither non-interactive mode nor simple progress meters achieve either goal. Fix #59527
1 parent afb44f5 commit 42a33bb

File tree

3 files changed

+55
-45
lines changed

3 files changed

+55
-45
lines changed

base/loading.jl

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2668,33 +2668,37 @@ function __require_prelocked(pkg::PkgId, env)
26682668
if JLOptions().use_compiled_modules == 1
26692669
if !generating_output(#=incremental=#false)
26702670
project = active_project()
2671-
if !generating_output() && !parallel_precompile_attempted && !disable_parallel_precompile && @isdefined(Precompilation)
2672-
parallel_precompile_attempted = true
2673-
unlock(require_lock)
2674-
try
2675-
Precompilation.precompilepkgs([pkg]; _from_loading=true, ignore_loaded=false)
2676-
finally
2677-
lock(require_lock)
2678-
end
2679-
@goto load_from_cache
2680-
end
26812671
# spawn off a new incremental pre-compile task for recursive `require` calls
26822672
loaded = let path = path, reasons = reasons
26832673
maybe_cachefile_lock(pkg, path) do
26842674
# double-check the search now that we have lock
26852675
m = _require_search_from_serialized(pkg, path, UInt128(0), true)
26862676
m isa Module && return m
2687-
triggers = get(EXT_PRIMED, pkg, nothing)
2688-
loadable_exts = nothing
2689-
if triggers !== nothing # extension
2690-
loadable_exts = PkgId[]
2691-
for (ext′, triggers′) in EXT_PRIMED
2692-
if triggers′ triggers
2693-
push!(loadable_exts, ext′)
2677+
2678+
verbosity = isinteractive() ? CoreLogging.Info : CoreLogging.Debug
2679+
@logmsg verbosity "Precompiling $(repr("text/plain", pkg))$(list_reasons(reasons))"
2680+
2681+
unlock(require_lock)
2682+
try
2683+
if !generating_output() && !parallel_precompile_attempted && !disable_parallel_precompile && @isdefined(Precompilation)
2684+
parallel_precompile_attempted = true
2685+
Precompilation.precompilepkgs([pkg]; _from_loading=true, ignore_loaded=false)
2686+
return
2687+
end
2688+
triggers = get(EXT_PRIMED, pkg, nothing)
2689+
loadable_exts = nothing
2690+
if triggers !== nothing # extension
2691+
loadable_exts = PkgId[]
2692+
for (ext′, triggers′) in EXT_PRIMED
2693+
if triggers′ triggers
2694+
push!(loadable_exts, ext′)
2695+
end
26942696
end
26952697
end
2698+
return compilecache(pkg, path; loadable_exts)
2699+
finally
2700+
lock(require_lock)
26962701
end
2697-
return compilecache(pkg, path; reasons, loadable_exts)
26982702
end
26992703
end
27002704
loaded isa Module && return loaded
@@ -3221,18 +3225,18 @@ This can be used to reduce package load times. Cache files are stored in
32213225
`DEPOT_PATH[1]/compiled`. See [Module initialization and precompilation](@ref)
32223226
for important notes.
32233227
"""
3224-
function compilecache(pkg::PkgId, internal_stderr::IO = stderr, internal_stdout::IO = stdout; flags::Cmd=``, cacheflags::CacheFlags=CacheFlags(), reasons::Union{Dict{String,Int},Nothing}=Dict{String,Int}(), loadable_exts::Union{Vector{PkgId},Nothing}=nothing)
3228+
function compilecache(pkg::PkgId, internal_stderr::IO = stderr, internal_stdout::IO = stdout; flags::Cmd=``, cacheflags::CacheFlags=CacheFlags(), loadable_exts::Union{Vector{PkgId},Nothing}=nothing)
32253229
@nospecialize internal_stderr internal_stdout
32263230
path = locate_package(pkg)
32273231
path === nothing && throw(ArgumentError("$(repr("text/plain", pkg)) not found during precompilation"))
3228-
return compilecache(pkg, path, internal_stderr, internal_stdout; flags, cacheflags, reasons, loadable_exts)
3232+
return compilecache(pkg, path, internal_stderr, internal_stdout; flags, cacheflags, loadable_exts)
32293233
end
32303234

32313235
const MAX_NUM_PRECOMPILE_FILES = Ref(10)
32323236

32333237
function compilecache(pkg::PkgId, path::String, internal_stderr::IO = stderr, internal_stdout::IO = stdout,
32343238
keep_loaded_modules::Bool = true; flags::Cmd=``, cacheflags::CacheFlags=CacheFlags(),
3235-
reasons::Union{Dict{String,Int},Nothing}=Dict{String,Int}(), loadable_exts::Union{Vector{PkgId},Nothing}=nothing)
3239+
loadable_exts::Union{Vector{PkgId},Nothing}=nothing)
32363240

32373241
@nospecialize internal_stderr internal_stdout
32383242
# decide where to put the resulting cache file
@@ -3250,8 +3254,6 @@ function compilecache(pkg::PkgId, path::String, internal_stderr::IO = stderr, in
32503254
concrete_deps = empty(_concrete_dependencies)
32513255
end
32523256
# run the expression and cache the result
3253-
verbosity = isinteractive() ? CoreLogging.Info : CoreLogging.Debug
3254-
@logmsg verbosity "Precompiling $(repr("text/plain", pkg)) $(list_reasons(reasons))"
32553257

32563258
# create a temporary file in `cachepath` directory, write the cache in it,
32573259
# write the checksum, _and then_ atomically move the file to `cachefile`.
@@ -3949,7 +3951,7 @@ end
39493951
record_reason(::Nothing, ::String) = nothing
39503952
function list_reasons(reasons::Dict{String,Int})
39513953
isempty(reasons) && return ""
3952-
return "(cache misses: $(join(("$k ($v)" for (k,v) in reasons), ", ")))"
3954+
return " (cache misses: $(join(("$k ($v)" for (k,v) in reasons), ", ")))"
39533955
end
39543956
list_reasons(::Nothing) = ""
39553957

base/precompilation.jl

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module Precompilation
22

3-
using Base: PkgId, UUID, SHA1, parsed_toml, project_file_name_uuid, project_names,
3+
using Base: CoreLogging, PkgId, UUID, SHA1, parsed_toml, project_file_name_uuid, project_names,
44
project_file_manifest_path, get_deps, preferences_names, isaccessibledir, isfile_casesensitive,
55
base_project, isdefined
66

@@ -532,9 +532,16 @@ function _precompilepkgs(pkgs::Union{Vector{String}, Vector{PkgId}},
532532
num_tasks = parse(Int, get(ENV, "JULIA_NUM_PRECOMPILE_TASKS", string(default_num_tasks)))
533533
parallel_limiter = Base.Semaphore(num_tasks)
534534

535-
# suppress passive loading printing in julia test suite. `JULIA_TESTS` is set in Base.runtests
536-
io = (_from_loading && !Sys.isinteractive() && Base.get_bool_env("JULIA_TESTS", false)) ? IOContext{IO}(devnull) : _io
537-
535+
# suppress precompilation progress messages when precompiling for loading packages, except during interactive sessions
536+
# or when specified by logging heuristics that explicitly require it
537+
# since the complicated IO implemented here can have somewhat disastrous consequences when happening in the background (e.g. #59599)
538+
io = _io
539+
logcalls = nothing
540+
if _from_loading && !isinteractive()
541+
io = IOContext{IO}(devnull)
542+
fancyprint = false
543+
logcalls = isinteractive() ? CoreLogging.Info : CoreLogging.Debug # sync with Base.compilecache
544+
end
538545

539546
nconfigs = length(configs)
540547
hascolor = get(io, :color, false)::Bool
@@ -608,8 +615,6 @@ function _precompilepkgs(pkgs::Union{Vector{String}, Vector{PkgId}},
608615
# consider exts of project deps to be project deps so that errors are reported
609616
append!(project_deps, keys(filter(d->last(d).name in keys(env.project_deps), ext_to_parent)))
610617

611-
@debug "precompile: deps collected"
612-
613618
# An extension effectively depends on another extension if it has a strict superset of its triggers
614619
for ext_a in keys(ext_to_parent)
615620
for ext_b in keys(ext_to_parent)
@@ -664,7 +669,6 @@ function _precompilepkgs(pkgs::Union{Vector{String}, Vector{PkgId}},
664669
end
665670
end
666671
end
667-
@debug "precompile: extensions collected"
668672

669673
serial_deps = Base.PkgId[] # packages that are being precompiled in serial
670674

@@ -704,7 +708,6 @@ function _precompilepkgs(pkgs::Union{Vector{String}, Vector{PkgId}},
704708
was_recompiled[pkg_config] = false
705709
end
706710
end
707-
@debug "precompile: signalling initialized"
708711

709712
# find and guard against circular deps
710713
cycles = Vector{Base.PkgId}[]
@@ -732,7 +735,6 @@ function _precompilepkgs(pkgs::Union{Vector{String}, Vector{PkgId}},
732735
if !isempty(circular_deps)
733736
@warn excluded_circular_deps_explanation(io, ext_to_parent, circular_deps, cycles)
734737
end
735-
@debug "precompile: circular dep check done"
736738

737739
# If you have a workspace and want to precompile all projects in it, look through all packages in the manifest
738740
# instead of collecting from a project i.e. not filter out packages that are in the current project.
@@ -785,7 +787,6 @@ function _precompilepkgs(pkgs::Union{Vector{String}, Vector{PkgId}},
785787
else
786788
target[] = "for $nconfigs compilation configurations..."
787789
end
788-
@debug "precompile: packages filtered"
789790

790791
pkg_queue = PkgConfig[]
791792
failed_deps = Dict{PkgConfig, String}()
@@ -1013,16 +1014,23 @@ function _precompilepkgs(pkgs::Union{Vector{String}, Vector{PkgId}},
10131014
return
10141015
end
10151016
try
1016-
# allows processes to wait if another process is precompiling a given package to
1017-
# a functionally identical package cache (except for preferences, which may differ)
1018-
t = @elapsed ret = precompile_pkgs_maybe_cachefile_lock(io, print_lock, fancyprint, pkg_config, pkgspidlocked, hascolor, parallel_limiter, ignore_loaded) do
1019-
Base.with_logger(Base.NullLogger()) do
1020-
# whether to respect already loaded dependency versions
1021-
keep_loaded_modules = !ignore_loaded
1022-
# for extensions, any extension in our direct dependencies is one we have a right to load
1023-
# for packages, we may load any extension (all possible triggers are accounted for above)
1024-
loadable_exts = haskey(ext_to_parent, pkg) ? filter((dep)->haskey(ext_to_parent, dep), direct_deps[pkg]) : nothing
1025-
Base.compilecache(pkg, sourcepath, std_pipe, std_pipe, keep_loaded_modules;
1017+
# for extensions, any extension in our direct dependencies is one we have a right to load
1018+
# for packages, we may load any extension (all possible triggers are accounted for above)
1019+
loadable_exts = haskey(ext_to_parent, pkg) ? filter((dep)->haskey(ext_to_parent, dep), direct_deps[pkg]) : nothing
1020+
if _from_loading && pkg in requested_pkgids
1021+
# loading already took the cachefile_lock and printed logmsg for its explicit requests
1022+
t = @elapsed ret = begin
1023+
Base.compilecache(pkg, sourcepath, std_pipe, std_pipe, !ignore_loaded;
1024+
flags, cacheflags, loadable_exts)
1025+
end
1026+
else
1027+
# allows processes to wait if another process is precompiling a given package to
1028+
# a functionally identical package cache (except for preferences, which may differ)
1029+
t = @elapsed ret = precompile_pkgs_maybe_cachefile_lock(io, print_lock, fancyprint, pkg_config, pkgspidlocked, hascolor, parallel_limiter, ignore_loaded) do
1030+
logcalls === nothing || @lock print_lock begin
1031+
Base.@logmsg logcalls "Precompiling $(repr("text/plain", pkg))"
1032+
end
1033+
Base.compilecache(pkg, sourcepath, std_pipe, std_pipe, !ignore_loaded;
10261034
flags, cacheflags, loadable_exts)
10271035
end
10281036
end

test/precompile.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ precompile_test_harness(false) do dir
641641
end
642642
""")
643643

644-
cachefile, _ = @test_logs (:debug, r"Precompiling FooBar") min_level=Logging.Debug match_mode=:any Base.compilecache(Base.PkgId("FooBar"))
644+
cachefile, _ = @test_logs (:debug, r"Generating object cache file for FooBar") min_level=Logging.Debug match_mode=:any Base.compilecache(Base.PkgId("FooBar"))
645645
empty_prefs_hash = Base.get_preferences_hash(nothing, String[])
646646
@test cachefile == Base.compilecache_path(Base.PkgId("FooBar"), empty_prefs_hash)
647647
@test isfile(joinpath(cachedir, "FooBar.ji"))

0 commit comments

Comments
 (0)