Как использовать: так как с CompUnit
Я пытаюсь создать кеш 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
содержит время после компиляции, тогда значение дескриптора будет Nil. Кажется, это не так.
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 ответ
Кэши кода загрузки модуля ищут и по существу начинают с:
$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? Старая версия модуля A
загружен или (возможно, конфликтует с предыдущей версией) загруженной версии модуля B? И как эта дифференциация будет работать для генерации файлов precomp (что опять может происходить параллельно)?
Конечно, если мы игнорируем вышесказанное, мы можем добавить код, чтобы сделать его дороже .IO.modified
вызывает загрузку каждого модуля для всех типов CompUnit::Repository (замедляя скорость запуска), чтобы сказать "эй, эта неизменная вещь изменена". Но гранулярность измененных временных отметок файловой системы на некоторых ОС делала проверку довольно хрупкой (особенно для многопоточной загрузки модулей с генерируемыми файлами предварительной компоновки), а это означает, что каждый раз требуются даже более дорогие вызовы для получения контрольной суммы.