Skip to content
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

File cache isn't updated while a template is in memory #257

Open
sewi-cpan opened this issue Mar 6, 2020 · 0 comments
Open

File cache isn't updated while a template is in memory #257

sewi-cpan opened this issue Mar 6, 2020 · 0 comments

Comments

@sewi-cpan
Copy link

sewi-cpan commented Mar 6, 2020

Reproduce:
echo 'initial value' >test.tt
perl -MTemplate -le '$tt = Template->new(COMPILE_EXT => ".ttc", COMPILE_DIR => "."); for (1..100) { system "ls -l test.tt test.tt.ttc"; $tt->process("test.tt"); sleep 3; }'
Another shell:
echo 'second value' >test.tt

What happens?
initial value is shown until the template content changes, then second value is shown.
The cache file test.tt.ttc still contains initial value after the change.

What should happen?
The cache file should also be updated.

Why
Based on 3.007, but also confirmed since 2.24:
sub _fetch first checks if the requested template file is found within the memory cache of $self->{ LOOKUP }. Any template not found there is checked for an up-to-date cached version or the original version on disk which is compiled into the compiled version afterward.
Any template found in the memory cache is regularly checked for file updates using _refresh.
_refresh checks if the last check is older than STATS_TTL seconds and re-reads the mtime of the original template file if it should be re-checked.
If the mtime of the original template now differs from the one stored in memory, the original template file is re-read using _load and compiled using _compile:

        if ( ! defined $template_mtime || ( $template_mtime != $slot->[ LOAD ] )) {
            $self->debug("refreshing cache file ", $slot->[ NAME ])
                if $self->{ DEBUG };

            ($data, $error) = $self->_load($slot->[ NAME ], $slot->[ DATA ]->{ name });
            ($data, $error) = $self->_compile($data)
                unless $error;

sub _compile does also write the disk cache, but only if the filename of the template in the disk cache is passed as the second argument - which is not.
Once a new process (without the template memory cache) does read the template, it discovers the difference between the original file and disk cache file - and recompiles the template to a new disk cache file. That's why the problem never ends up in old template content being used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant