如何使用 :since 与 CompUnit [英] How to use :since with CompUnit

查看:55
本文介绍了如何使用 :since 与 CompUnit的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过使用 CompUnit 类集进行预编译来创建 POD6 的缓存.

我可以按如下方式创建、存储和检索 pod:

使用v6.c;使用 nqp;my $precomp-store = CompUnit::PrecompilationStore::File.new(prefix=>'cache'.IO);我的 $precomp = CompUnit::PrecompilationRepository::Default.new(store=> $precomp-store );我的 $key = nqp::sha1('test.pod6');'test.pod6'.IO.spurt(q:to/CONTENT/);=开始吊舱=TITLE 越来越多还有一些文字=结束豆荚内容$precomp.precompile('test.pod6'.IO, $key, :force);我的 $handle = $precomp.load($key, )[0];我的 $resurrected = nqp::atkey($handle.unit,'$=pod')[0];说 $resurrected ~~ Pod::Block::Named;

那么现在我更改了 POD,如何使用 :since 标志?我认为如果 :since 包含编译后的时间,则句柄的值将为 Nil.情况似乎并非如此.

my $new-handle = $precomp.load($key, :since('test.pod6'.IO.modified));用 $new-handle 说我得到了一个新句柄";

输出是我得到了一个新句柄".

我做错了什么?这是带有代码和输出的 pastebin 链接:https://pastebin.com/wtA9a0nP

解决方案

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

$lock.protect: {如果 %loaded{$id}:exists,则返回 %loaded{$id};}

所以问题变成了我如何加载一个模块然后卸载它(以便我可以再次加载它)?"答案是:您不能卸载模块.但是,您可以更改文件名、分发长名称(通过更改名称、身份验证、api 或版本)或 precomp id - 无论特定 CompUnit::Repository 用于唯一标识模块的任何内容 - 以绕过缓存.

似乎被忽略的是 $key 旨在表示一个不可变的名称,这样它就始终指向相同的内容.如果 foo.pm 正在由模块 加载,则应该为模块 Used::Inside::A 加载什么版本的 foo.pm>AB 同时,模块 A 先加载 foo,然后模块 B 修改 foo?旧版本的模块 A 加载,或(可能与以前的版本冲突)模块 B 加载的版本?以及这种差异对于 precomp 文件生成本身如何起作用(这也可以并行发生)?

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

I am trying to create a cache of POD6 by precompiling them using the CompUnit set of classes.

I can create, store and retrieve pod as follows:

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;

So now I change the POD, how do I use the :since flag? I thought that if :since contains a time after the compilation, then the value of the handle would be Nil. That does not seem to be the case.

my $new-handle = $precomp.load($key, :since('test.pod6'.IO.modified));
say 'I got a new handle' with $new-handle;

Output is 'I got a new handle'.

What I am doing wrong? Here is a pastebin link with code and output: https://pastebin.com/wtA9a0nP

解决方案

Module loading code caches look ups and essentially start with:

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

So the question becomes "how do I load a module and then unload it (so i can load it again)?" to which the answer is: you cannot unload a module. You can however change the filename, distribution longname ( via changing the name, auth, api, or version ), or precomp id -- whatever a specific CompUnit::Repository uses to uniquely identify modules -- to bypass the cache.

What seems to be overlooked is that $key is intended to represent an immutable name, such that it will always point at the same content. What version of foo.pm should be loaded for Module Used::Inside::A if foo.pm is being loaded by Module A and B at the same time, Module A loads foo first, and then Module B modifies foo? The old version Module A loaded, or the ( possibly conflicting with previous version ) Module B loaded version? And how would this differentiation work for precomp file generation themselves ( which again can happen in parallel )?

Of course if we ignore the above we could add code to make expensive .IO.modified calls for every single module load for all CompUnit::Repository types ( slowing down startup speed ) to say "hey this immutable thing changed". But the granularity of file system modified timestamps on some OS's made the check pretty fragile ( especially for multi-threaded module loading with precomp files being generated ), meaning that even more expensive calls to get a checksum would be necessary every single time.

这篇关于如何使用 :since 与 CompUnit的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆