我试图通过使用 CompUnit 类集预编译 POD6 来创建 POD6 缓存。
我可以创建、存储和检索 pod,如下所示:
use v6.c;
use nqp;
my $precomp-store = CompUnit::PrecompilationStore::File.new(prefix=>'cache'.IO);
my $precomp = CompUnit::PrecompilationRepository::Default.new(store=> $precomp-store );
my $key = nqp::sha1('test.pod6');
'test.pod6'.IO.spurt(q:to/CONTENT/);
=begin pod
=TITLE More and more
Some more text
=end pod
CONTENT
$precomp.precompile('test.pod6'.IO, $key, :force);
my $handle = $precomp.load($key, )[0];
my $resurrected = nqp::atkey($handle.unit,'$=pod')[0];
say $resurrected ~~ Pod::Block::Named;
那么现在我换了POD,我该如何使用:since
旗帜?我想如果:since
如果包含编译后的时间,则句柄的值为 Nil。事实似乎并非如此。
my $new-handle = $precomp.load($key, :since('test.pod6'.IO.modified));
say 'I got a new handle' with $new-handle;
输出是“我有一个新句柄”。
我做错了什么?
这是包含代码和输出的 Pastebin 链接:https://pastebin.com/wtA9a0nP
模块加载代码缓存查找,本质上是从以下开始:
$lock.protect: {
return %loaded{$id} if %loaded{$id}:exists;
}
所以问题变成了“如何加载模块然后卸载它(这样我可以再次加载它)?”答案是:您无法卸载模块。但是,您可以更改文件名、分发长名称(通过更改名称、身份验证、api 或版本)或预编译 ID(无论特定 CompUnit::Repository 使用什么来唯一标识模块),以绕过缓存。
似乎被忽视的是$key
旨在表示一个不可变的名称,以便它始终指向相同的内容。什么版本的foo.pm
应该为模块加载Used::Inside::A
if foo.pm
正在由模块加载A
and B
同时,模块A
首先加载 foo,然后加载 ModuleB
修改 foo?旧版本模块A
已加载,还是(可能与以前的版本冲突)模块 B 加载的版本?这种差异如何用于预编译文件生成本身(这又可以并行发生)?
当然,如果我们忽略上面的内容,我们可以添加代码来使成本昂贵.IO.modified
要求所有 CompUnit::Repository 类型的每个模块加载(减慢启动速度)说“嘿,这个不可变的东西改变了”。但是某些操作系统上文件系统修改时间戳的粒度使得检查非常脆弱(特别是对于生成预编译文件的多线程模块加载),这意味着每次都需要更昂贵的调用来获取校验和。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)