Как использовать: так как с CompUnit - PullRequest
0 голосов
/ 26 октября 2018

Я пытаюсь создать кеш POD6, предварительно скомпилировав их с помощью набора классов CompUnit.

Я могу создавать, хранить и извлекать модуль следующим образом:

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 содержит время после компиляции, то значение дескриптора будет ноль. Кажется, это не так.

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

Вывод «У меня новый дескриптор».

Что я делаю не так? Вот ссылка для вставки с кодом и выводом: https://pastebin.com/wtA9a0nP

1 Ответ

0 голосов
/ 26 октября 2018

Кэши кода загрузки модуля ищут и по существу начинают с:

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

Таким образом, возникает вопрос: «Как загрузить модуль, а затем выгрузить его (чтобы я мог загрузить его снова)?» на что ответ: вы не можете выгрузить модуль. Однако вы можете изменить имя файла, длинное имя дистрибутива (через изменение имени, auth, api или версии) или идентификатор предварительной компоновки - независимо от того, какой конкретный CompUnit :: Repository использует для уникальной идентификации модулей - чтобы обойти кеш.

То, что кажется упущенным, - это то, что $key предназначен для представления неизменного имени, так что оно всегда будет указывать на одно и то же содержимое. Какая версия foo.pm должна быть загружена для модуля Used::Inside::A, если foo.pm загружается одновременно модулями A и B, модуль A сначала загружает foo, а затем модуль B изменяет Foo? Старая версия Module A загружена, или (возможно, конфликтует с предыдущей версией) загруженная версия Module B? И как эта дифференциация будет работать для генерации файлов precomp (что опять может происходить параллельно)?

Конечно, если мы игнорируем вышесказанное, мы можем добавить код, чтобы сделать дорогостоящими .IO.modified вызовы для каждой загрузки каждого модуля для всех типов CompUnit :: Repository (замедление скорости запуска), чтобы сказать «эй, эта неизменная вещь изменена». Но гранулярность измененных временных отметок файловой системы в некоторых ОС делала проверку довольно хрупкой (особенно для загрузки многопоточных модулей с генерируемыми файлами precomp), а это означает, что каждый раз требуются даже более дорогие вызовы для получения контрольной суммы.

...