Hi Roderich,

I thought some more about this:

Roderich Schupp wrote:
- How can modifying find_par_last help in implementing "fallback => 0", i.e.
 "prefer loading modules from a repository over the locally installed modules",
 when find_par_last is _appended_ to @INC: if a module is already found using
 the built-in @INC the find_par_last will not be called at all?

Actually, it's find_par that's modified between 0.991 and 0.992. find_par_last has "always" been the place where repositories were checked.

- If find_par_last works as intended, why is there no corresponding
  modification for the code path dealing with bootstrapping DLLs, i.e. XS parts?
  The modification to find_par_last in 0.992 explicitly deals only
with .pm files.
  The function in PAR.pm that replaces DynaLoader::bootstrap still calls
  _find_par_any.

Hmm. Let me explain the logic a bit. Maybe you can spot what's wrong with it (I can't). First, without repositories:

- There's a list of .par files that have been loaded preferentially. They take precedence over the installed modules and are tracked via the list in @PAR_INC. - Then, there's a list of .par's which are considered fallbacks. They are tracked in the last @PAR_INC_LAST.

- When a module's used, the first @INC entry is a hook (find_par) that tries to load he modules from the .pars in @PAR_INC. If that fails, @INC is trawled normally until it hits the last hook (find_par_last). That one checks the .pars in @PAR_INC_LAST. - When a module tries to load a shared library via DynaLoader it triggers _find_par_any. That one simply calls _find_par_internals (just like find_par and find_par_last if you disregard repositories), but instead of passing either @PAR_INC or @PAR_INC_LAST, it passes both, so the shared library is sought in either place. If it's not found, control is handed to the ordinary DynaLoader bootstrap routine.

==> Here's where I guess there might be a bug: Since the overridden bootstrap routine searches ALL pars before handing control back to DynaLoader. That means it will happily load shared libraries from the fallback pars even if it should have checked the system first. I'll try a hacky fix for this later.

With repositories, things become a bit more complicated:

- If any repository that's checked for a particular module has it, the corresponding par file will be downloaded to the computer and loaded with PAR. Therefore, it'll feed back into the @PAR_INC or @PAR_INC_LAST lists of loaded pars at that point (see above).

- If there are repositories in upgrade mode, they are checked first in find_par. (First hook in @INC) - After checking for the upgrade repositories, PAR_INC is checked as usual. Then comes checking @PriorityRepositoryObjects, which is repositories with "fallback => 0" set. This is the new addition in 0.992!

==> Now that I looked at the code some more, it seems there may be another bug here: If one of those fallback=>0 repositories returns a hit, the par is loaded but appended to @PAR_INC_LAST. That means any modules that may still be loaded from those PAR's will suddenly live at the end of the priority chain!

- Finally, the find_par_last routine will first try locally loaded PAR files (including those from repositories) with fallback=>1 and then repositories.

Now, I don't think that the DynaLoader override needs to know about repositories. That's because repositories don't track all files anyway but only modules. It's probably a rather good assumption to expect only shared libraries for modules to be required that have just been loaded from the repository anyway.

Cheers,
Steffen

Reply via email to