-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
provide a scratchspace for AtlasRep data if necessary #1026
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ module Packages | |
|
||
import Downloads | ||
import Pidfile | ||
import Scratch: @get_scratch! | ||
import ...GAP: Globals, GapObj, replace_global!, RNamObj, sysinfo, Wrappers | ||
|
||
const DEFAULT_PKGDIR = Ref{String}() | ||
|
@@ -119,7 +120,7 @@ function load(spec::String, version::String = ""; install::Union{Bool, String} = | |
warning_level_orig = Wrappers.InfoLevel(Globals.InfoWarning) | ||
Wrappers.SetInfoLevel(Globals.InfoWarning, 0) | ||
end | ||
loaded = Wrappers.LoadPackage(gspec, gversion, !quiet) | ||
loaded = _load_internal(gspec, gversion, !quiet) | ||
if spec_is_path | ||
Wrappers.SetInfoLevel(Globals.InfoWarning, warning_level_orig) | ||
end | ||
|
@@ -172,7 +173,7 @@ function load(spec::String, version::String = ""; install::Union{Bool, String} = | |
|
||
# ... then try to load the package, ... | ||
Wrappers.SetPackagePath(pkgname, gspec) | ||
loaded = Wrappers.LoadPackage(pkgname, gversion, !quiet) | ||
loaded = _load_internal(pkgname, gversion, !quiet) | ||
|
||
# ..., and reinstall the old info records | ||
# (which were removed by `Wrappers.SetPackagePath`). | ||
|
@@ -191,14 +192,14 @@ function load(spec::String, version::String = ""; install::Union{Bool, String} = | |
# without showing messages. | ||
if Packages.install(spec, version; interactive = false, quiet) | ||
# Make sure that the installed version is admissible. | ||
return Wrappers.LoadPackage(gspec, gversion, !quiet) == true | ||
return _load_internal(gspec, gversion, !quiet) == true | ||
end | ||
elseif install isa String | ||
# `Packages.install` deals with the `install` information. | ||
if Packages.install(install, version; interactive = false, quiet) | ||
# Make sure that the installed version is admissible | ||
# (and that the package given by `install` fits to `spec`). | ||
return Wrappers.LoadPackage(gspec, gversion, !quiet) == true | ||
return _load_internal(gspec, gversion, !quiet) == true | ||
end | ||
end | ||
|
||
|
@@ -207,6 +208,18 @@ function load(spec::String, version::String = ""; install::Union{Bool, String} = | |
# GAP unfortunately only gives us info messages... | ||
end | ||
|
||
function _load_internal(gspec::GapObj, gversion::GapObj, quiet::Bool) | ||
loaded = Wrappers.LoadPackage(gspec, gversion, quiet) | ||
|
||
# If the AtlasRep package is loaded afterwards (perhaps indirectly) | ||
# then provide its scratchspace if necessary. | ||
if atlasrep_download_cache == "" && Wrappers.IsPackageLoaded(GapObj("AtlasRep")) | ||
init_atlasrep() | ||
end | ||
|
||
return loaded | ||
end | ||
|
||
""" | ||
install(spec::String, version::String = ""; | ||
interactive::Bool = true, quiet::Bool = false, | ||
|
@@ -374,4 +387,53 @@ function locate_package(name::String) | |
return String(Wrappers.ELM_REC(loaded, lname)[1]) | ||
end | ||
|
||
|
||
############################################################################## | ||
# | ||
# special handling for the GAP package AtlasRep | ||
# | ||
# GAP.jl supports Julia artifacts for GAP packages. | ||
# One feature of the AtlasRep package is to download data files and | ||
# (if wanted) to store them in a local directory. | ||
# The path of this directory is either explicitly set in the user preference | ||
# `AtlasRepDataDirectory` of the package, or it is computed when the AtlasRep | ||
# package gets loaded. | ||
# The value of the user preference is an empty string if and only if | ||
# GAP does not know a path to a writable directory for the data files, | ||
# which means that downloaded files cannot be cached; | ||
# in this case, GAP.jl provides a scratchspace for the data, | ||
# and sets the value of the user preference accordingly. | ||
# We can use this scratchspace independent of the version of Julia, GAP.jl, | ||
# and AtlasRep. | ||
|
||
# The path to the scratchspace, will be filled by `init_atlasrep()` | ||
atlasrep_download_cache = "" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is type unstable. Better is something like this:
and so on. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. O.k. |
||
|
||
# If GAP's AtlasRep package does not yet know a writable directory | ||
# for storing downloaded data, provide a Julia scratch space. | ||
function init_atlasrep() | ||
atlasrep_download_cache == "" || return | ||
atlasrep = GapObj("atlasrep") | ||
AtlasRepDataDirectory = GapObj("AtlasRepDataDirectory") | ||
val = Wrappers.UserPreference(atlasrep, AtlasRepDataDirectory) | ||
if Wrappers.IsString(val) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it is not a string, then I think the only other value (baring a mistake in So isn't that a situation in which we should provide a path, too? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ideally, if AtlasRep does not get loaded at all then GAP.jl need not create a scratchspace at all. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But creating a scratch space is super cheap. If the price for avoiding it is complicated and error-prone logic to detect whether the scratch space is really needed, I would just forget about that and always create the scratch space. |
||
# A default is set. | ||
if length(val) == 0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did some tests with plain GAP locally: if I have no So if I read it right, then with atlasrep autoloaded (which is the case right now with GAP.jl), this code would be never triggered?! Can we perhaps instead somehow distinguish between "the user set a value (so honor that)" and "some kind of default value that we should override". E.g. perhaps one way to do that would be to perform just that check in Anyway, another potential issue: What if we set a path to a scratch dir, but then the user calls In closing, I think for 99.9% of all users, they are not aware of this setting and don't care about it and with that in mind the simples solution would be to just call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Accidentally storing the path to the scratchspace in a What I had mentioned already is that the currently proposed code ignores that a user may set an empty string in order to disable caching. One solution would be to check in the case of an empty string whether the package directory is writable, and if yes to conclude that the empty string is intentional, and to keep it. Concerning the fact that the replacement of the default does not get triggered if one starts GAP without packages and later on loads GAP packages only on the GAP side, we could argue that the situation is not worse as it was before, and if one does not use the features from the Julia side than one does not get its advantages. (I had thought whether a clean solution would be to put the relevant Julia code into the function for the default computation in AtlasRep's |
||
# There is no writable directory yet. | ||
# If the scratch space is not yet there, create it and the relevant | ||
# subdirectories. | ||
# (The AtlasRep package is perhaps not yet loaded at this time.) | ||
global atlasrep_download_cache = @get_scratch!("atlasrep_cache") | ||
Wrappers.SetUserPreference(atlasrep, AtlasRepDataDirectory, | ||
GapObj(atlasrep_download_cache)) | ||
for dir in ["datagens", "dataword", "dataext"] | ||
fname = joinpath(atlasrep_download_cache, dir) | ||
isdir(fname) || mkdir(fname) | ||
end | ||
else | ||
global atlasrep_download_cache = String(val) | ||
end | ||
end | ||
end | ||
|
||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will not catch the cases were a user calls GAP code that does
LoadPackage("atlasrep")
.I don't think we need this if we call
SetUserPreference
earlier and in more cases, see below.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we set the value of the preference before AtlasRep gets loaded then we have to set it unconditionally, and create the scratchspace even if the package will not be loaded.
I am not sure how to deal with several available package versions: As long as the package is not loaded, we do not know which version will be loaded, and there is only one path which we can set.