【问题标题】:How to use :since with CompUnit如何使用 :since with CompUnit
【发布时间】:2018-10-26 08:57:24
【问题描述】:

我正在尝试通过使用 CompUnit 类集进行预编译来创建 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

【问题讨论】:

    标签: raku


    【解决方案1】:

    模块加载代码缓存查找并基本上开始于:

    $lock.protect: { 
        return %loaded{$id} if %loaded{$id}:exists; 
    }
    

    所以问题变成了“我如何加载一个模块然后卸载它(这样我可以再次加载它)?”答案是:您无法卸载模块。但是,您可以更改文件名、分发长名(通过更改名称、身份验证、api 或版本)或 precomp id(无论特定 CompUnit::Repository 使用什么来唯一标识模块)来绕过缓存。

    似乎被忽视的是$key 旨在表示一个不可变的名称,这样它总是指向相同的内容。如果foo.pm同时被Module AB加载,Module Used::Inside::A应该为Module Used::Inside::A加载什么版本的foo.pm,Module A先加载foo,然后Module B修改富?已加载旧版本 Module A,还是(可能与先前版本冲突)Module B 已加载版本?以及这种差异化对 precomp 文件生成本身有何作用(这又可以并行发生)?

    当然,如果我们忽略上述内容,我们可以添加代码来为所有 CompUnit::Repository 类型的每个单个模块加载进行昂贵的 .IO.modified 调用(减慢启动速度),以说“嘿,这个不可变的东西改变了”。但是某些操作系统上文件系统修改时间戳的粒度使得检查非常脆弱(特别是对于生成预编译文件的多线程模块加载),这意味着每次都需要更昂贵的调用来获取校验和。

    【讨论】:

    • 问题是它是什么:它试图通过使用预编译来创建 POD6 的缓存。如果我理解正确,您是说我们需要将上次修改时间保留在其他地方,因为每次我们“安装”(在我们的例子中,预编译文档模块)时,它都会生成一个新句柄。对吗?
    • “问题是什么”——这个问题与你总结的问题几乎没有关系。如果目标只是预编译一些 pod,那么调用 .load 的目的是什么(通过 :since 在问题标题本身中间接引用)?
    • 不是我的话。 OP 的第一句话说:“我正在尝试通过使用 CompUnit 类集预编译它们来创建 POD6 的缓存。”因此,正如您所说,准确地说,目标是预编译一些 Pod。 load 被调用是为了使用预编译的 Pod,我猜。可能是错的,但这就是他首先在这里提出问题的原因,以找出正确的方法。
    • 问题的焦点是:since。答案在 ugexe 的评论中,即“时间戳的粒度......易碎”。所以:since 现在是 Noop。我没有做错任何事情,我显示的结果是当前预期的结果。由于 CompUnit 旨在提高速度,因此不能用于代码管理。没关系。
    • @ralph 抱歉耽搁了。搬家。问题是 CompUnit 中的文档级别低,以及编码的复杂性,例如类语句的嵌套。代码中没有任何注释,像我这样的新手并不清楚为什么要使用这种策略。我想找到一些方法来跟踪编译文件之间的变化——POD 文档文件变化很快。 POD 已编译。由于有数百个POD文件,每次编译效率低下。所以我不得不继承 CompUnit 来实现我的目标。并单独存储更改。无法“接受” ugexe ans,因为它无法实现我的目标。
    猜你喜欢
    • 2017-07-17
    • 1970-01-01
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    • 2017-11-10
    • 1970-01-01
    • 2020-12-22
    • 2013-02-02
    相关资源
    最近更新 更多