libstore: return transfer metadata from download
as promised earlier. nothing uses it yet, but just you wait.
Change-Id: I77d185578d96c2134b756d20f2fcf1c02de0da6f
This commit is contained in:
parent
14eff10fe4
commit
c68f0cdf00
|
@ -36,7 +36,7 @@ void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData,
|
||||||
|
|
||||||
auto fetch = [&](const std::string & url) {
|
auto fetch = [&](const std::string & url) {
|
||||||
|
|
||||||
auto raw = fileTransfer->download(url);
|
auto raw = fileTransfer->download(url).second;
|
||||||
auto decompressor = makeDecompressionSource(
|
auto decompressor = makeDecompressionSource(
|
||||||
unpack && mainUrl.ends_with(".xz") ? "xz" : "none", *raw);
|
unpack && mainUrl.ends_with(".xz") ? "xz" : "none", *raw);
|
||||||
|
|
||||||
|
|
|
@ -821,7 +821,8 @@ struct curlFileTransfer : public FileTransfer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
box_ptr<Source> download(const std::string & uri, const Headers & headers) override
|
std::pair<FileTransferResult, box_ptr<Source>>
|
||||||
|
download(const std::string & uri, const Headers & headers) override
|
||||||
{
|
{
|
||||||
struct State {
|
struct State {
|
||||||
bool done = false, failed = false;
|
bool done = false, failed = false;
|
||||||
|
@ -832,7 +833,7 @@ struct curlFileTransfer : public FileTransfer
|
||||||
|
|
||||||
auto _state = std::make_shared<Sync<State>>();
|
auto _state = std::make_shared<Sync<State>>();
|
||||||
|
|
||||||
auto transfer = enqueueFileTransfer(
|
auto [metadataFuture, _done] = enqueueFileTransfer(
|
||||||
uri,
|
uri,
|
||||||
headers,
|
headers,
|
||||||
[_state](std::exception_ptr ex) {
|
[_state](std::exception_ptr ex) {
|
||||||
|
@ -939,10 +940,11 @@ struct curlFileTransfer : public FileTransfer
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto metadata = metadataFuture.get();
|
||||||
auto source = make_box_ptr<DownloadSource>(_state);
|
auto source = make_box_ptr<DownloadSource>(_state);
|
||||||
auto lock(_state->lock());
|
auto lock(_state->lock());
|
||||||
source->awaitData(lock);
|
source->awaitData(lock);
|
||||||
return source;
|
return {std::move(metadata), std::move(source)};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,8 @@ struct FileTransfer
|
||||||
* thrown by the returned source. The source will only throw errors detected
|
* thrown by the returned source. The source will only throw errors detected
|
||||||
* during the transfer itself (decompression errors, connection drops, etc).
|
* during the transfer itself (decompression errors, connection drops, etc).
|
||||||
*/
|
*/
|
||||||
virtual box_ptr<Source> download(const std::string & uri, const Headers & headers = {}) = 0;
|
virtual std::pair<FileTransferResult, box_ptr<Source>>
|
||||||
|
download(const std::string & uri, const Headers & headers = {}) = 0;
|
||||||
|
|
||||||
enum Error { NotFound, Forbidden, Misc, Transient, Interrupted };
|
enum Error { NotFound, Forbidden, Misc, Transient, Interrupted };
|
||||||
};
|
};
|
||||||
|
|
|
@ -147,7 +147,7 @@ protected:
|
||||||
{
|
{
|
||||||
checkEnabled();
|
checkEnabled();
|
||||||
try {
|
try {
|
||||||
return getFileTransfer()->download(makeURI(path));
|
return getFileTransfer()->download(makeURI(path)).second;
|
||||||
} catch (FileTransferError & e) {
|
} catch (FileTransferError & e) {
|
||||||
if (e.error == FileTransfer::NotFound || e.error == FileTransfer::Forbidden)
|
if (e.error == FileTransfer::NotFound || e.error == FileTransfer::Forbidden)
|
||||||
throw NoSuchBinaryCacheFile("file '%s' does not exist in binary cache '%s'", path, getUri());
|
throw NoSuchBinaryCacheFile("file '%s' does not exist in binary cache '%s'", path, getUri());
|
||||||
|
|
|
@ -98,7 +98,7 @@ std::tuple<StorePath, Hash> prefetchFile(
|
||||||
|
|
||||||
FdSink sink(fd.get());
|
FdSink sink(fd.get());
|
||||||
|
|
||||||
getFileTransfer()->download(url)->drainInto(sink);
|
getFileTransfer()->download(url).second->drainInto(sink);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Optionally unpack the file. */
|
/* Optionally unpack the file. */
|
||||||
|
|
|
@ -136,7 +136,7 @@ TEST(FileTransfer, exceptionAbortsDownload)
|
||||||
|
|
||||||
LambdaSink broken([](auto block) { throw Done(); });
|
LambdaSink broken([](auto block) { throw Done(); });
|
||||||
|
|
||||||
ASSERT_THROW(ft->download("file:///dev/zero")->drainInto(broken), Done);
|
ASSERT_THROW(ft->download("file:///dev/zero").second->drainInto(broken), Done);
|
||||||
|
|
||||||
// makeFileTransfer returns a ref<>, which cannot be cleared. since we also
|
// makeFileTransfer returns a ref<>, which cannot be cleared. since we also
|
||||||
// can't default-construct it we'll have to overwrite it instead, but we'll
|
// can't default-construct it we'll have to overwrite it instead, but we'll
|
||||||
|
@ -155,7 +155,7 @@ TEST(FileTransfer, exceptionAbortsRead)
|
||||||
auto [port, srv] = serveHTTP("200 ok", "content-length: 0\r\n", [] { return ""; });
|
auto [port, srv] = serveHTTP("200 ok", "content-length: 0\r\n", [] { return ""; });
|
||||||
auto ft = makeFileTransfer();
|
auto ft = makeFileTransfer();
|
||||||
char buf[10] = "";
|
char buf[10] = "";
|
||||||
ASSERT_THROW(ft->download(fmt("http://[::1]:%d/index", port))->read(buf, 10), EndOfFile);
|
ASSERT_THROW(ft->download(fmt("http://[::1]:%d/index", port)).second->read(buf, 10), EndOfFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FileTransfer, NOT_ON_DARWIN(reportsSetupErrors))
|
TEST(FileTransfer, NOT_ON_DARWIN(reportsSetupErrors))
|
||||||
|
@ -179,7 +179,7 @@ TEST(FileTransfer, NOT_ON_DARWIN(defersFailures))
|
||||||
return std::string(1024 * 1024, ' ');
|
return std::string(1024 * 1024, ' ');
|
||||||
});
|
});
|
||||||
auto ft = makeFileTransfer(0);
|
auto ft = makeFileTransfer(0);
|
||||||
auto src = ft->download(fmt("http://[::1]:%d/index", port));
|
auto src = ft->download(fmt("http://[::1]:%d/index", port)).second;
|
||||||
ASSERT_THROW(src->drain(), FileTransferError);
|
ASSERT_THROW(src->drain(), FileTransferError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ TEST(FileTransfer, NOT_ON_DARWIN(handlesContentEncoding))
|
||||||
auto ft = makeFileTransfer();
|
auto ft = makeFileTransfer();
|
||||||
|
|
||||||
StringSink sink;
|
StringSink sink;
|
||||||
ft->download(fmt("http://[::1]:%d/index", port))->drainInto(sink);
|
ft->download(fmt("http://[::1]:%d/index", port)).second->drainInto(sink);
|
||||||
EXPECT_EQ(sink.s, original);
|
EXPECT_EQ(sink.s, original);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue