libutil: close file handle in async NAR parser
This bit us while upgrading Hydra[1]: when all the data was read into the hashing sink while receinving NAR contents, the hash was never created which lead to a test failing because file size was correct, but the hash was std::nullopt. [1] https://git.lix.systems/lix-project/hydra/src/commit/7a0dae579b53b4b96a829263b160c6dc9f42ce75/src/hydra-queue-runner/nar-extractor.cc#L70-L73 Change-Id: Ie71b5f1f17c926a2ab95fb2aabf23c7a575ff70b
This commit is contained in:
@@ -708,6 +708,7 @@ struct AsyncParser
|
||||
file->receiveContents({buf.data(), n});
|
||||
left -= n;
|
||||
}
|
||||
file->close();
|
||||
} else if (auto sl = std::get_if<Parser::Symlink>(&*i)) {
|
||||
target.createSymlink(name, sl->target);
|
||||
} else if (auto d = std::get_if<Parser::Directory>(&*i)) {
|
||||
|
||||
@@ -248,6 +248,7 @@ namespace parseAsync {
|
||||
{
|
||||
bool executable;
|
||||
uint64_t size;
|
||||
bool closed;
|
||||
std::string contents;
|
||||
operator nar::Entry() const
|
||||
{
|
||||
@@ -292,7 +293,10 @@ namespace parseAsync {
|
||||
file.contents += data;
|
||||
}
|
||||
|
||||
void close() override {}
|
||||
void close() override
|
||||
{
|
||||
file.closed = true;
|
||||
}
|
||||
};
|
||||
|
||||
explicit ReconstructVisitor(std::map<std::string, Entry> & parent) : parent(parent) {}
|
||||
@@ -306,7 +310,8 @@ namespace parseAsync {
|
||||
box_ptr<FileHandle>
|
||||
createRegularFile(const std::string & name, uint64_t size, bool executable) override
|
||||
{
|
||||
auto & file = std::get<File>(parent.emplace(name, File{executable, size}).first->second);
|
||||
auto & file =
|
||||
std::get<File>(parent.emplace(name, File{executable, size, false}).first->second);
|
||||
return make_box_ptr<FileReader>(file);
|
||||
}
|
||||
|
||||
@@ -331,6 +336,13 @@ TEST_P(NarTest, parseAsync)
|
||||
|
||||
auto entries = entriesFn()();
|
||||
parseDump(rv, source).wait(ws).value();
|
||||
|
||||
for (auto & [i, val] : contents) {
|
||||
if (auto f = std::get_if<parseAsync::File>(&val)) {
|
||||
ASSERT_TRUE(f->closed);
|
||||
}
|
||||
}
|
||||
|
||||
auto parsed = parseAsync::Directory::toNar(contents.at(""));
|
||||
while (true) {
|
||||
auto e = entries.next();
|
||||
|
||||
Reference in New Issue
Block a user