Subject: | "parl foo.par script.pl ..." uses a cache area that doesn't depend on foo.par |
Originally posted to the PAR mailing list
(http://www.nntp.perl.org/group/perl.par/2293):
From: Linn White
I have a .par file stored on a network drive. All the computers running
the par file are using the parl.exe executable. The files are cached on
their pc and everything is working as it should. However, I have numerous
additional files packed into the par. When I make changes to these files,
recompile the par and place it on the network drive, other user cannot see
the updated files, because the old files are being pulled from their local
cache. Changes made to my scripts though are reflected. How do I make
sure the additional files replace the existing chache files?
Further post show that the application reads its data as actual
files from the caching area (i.e. below $ENV{PAR_TEMP}) (as opposed
to using Archive::Zip methods to read directly from the par archive).
Now you would expect that the name of the cache area would be based
on some checksum of the par archive and hence would get stale
when the par is updated. But that's not in the case. In fact, every
par "executed" via parl gets the same cache area, because its
name is based on the checksum of the parl executable itself.
It's not clear that this is a bug, since the caching behaviour
of "parl foo.par ..." isn't specified anywhere. If you view
"parl foo.par ..." as an abbreviation for "perl -MPAR=foo.par ..."
you wouldn't expect that any cache whatsoever would be involved.
In this light the use of parl as described above could be considered
abuse. On the hand, you could view "parl foo.par ..." as being
functionally equivalent to "pp -o foo.exe foo.par", followed
by "foo.exe ...". Here a cache area is expected and it is definitely
dependent on some checksum of foo.exe.
I don't see an easy fix, here's what's happening:
"parl foo.par script.pl"
First par_mktmpdir (C function in myldr/mktmpdir.c) is called.
It determines progname=.../parl, then uses the checksum of
that file to construct the name $ENV{PAR_TEMP} and creates the
directory if necessary. Then the Perl code in script/par.pl is run.
It sets $progname=".../parl", detects that it is a PAR packed executable
and extracts some files from the executable into $ENV{PAR_TEMP}.
Next the code from package main in script/par.pl runs. By this time
$progname has changed to "foo.par", but $ENV{PAR_TEMP} is already
defined, so the checksum of foo.par doesn't matter.
PAR->import is called and extracts the PAR archive into $ENV{PAR_TEMP}.
Finally (with foo.par in @INC) script.pl is called via 'do "script.pl"'.
"foo.exe ..."
foo.exe is essentially the parl executable with foo.par piggy-backed.
It goes thru the same motions as above, but $progname is always
"foo.exe", hence the checksum (and $ENV{PAR_TEMP}) is based on foo.exe.
Cheers, Roderich