Commit Graph
100 Commits
Author SHA1 Message Date
eldritch horrors 2e5780ebc8 libexpr: simplify HAVE_BOEHMGC ifdefs
if we define a TraceableAllocator at all times and use that in places
that want maybe-traceable allocation we can simplify things a lot. we
also unconditionally allocate cache root pointers for Value and Env-1
caches, even though we don't need them without gc (they're so cheap).
defaulting to `std::allocator` without gc recovers previous behavior.

Change-Id: I236da8c3b0669b40cdfe355ec3ec4e764d096074
2024-11-29 17:55:08 +01:00
eldritch horrors 1e064e08fa libexpr: move builtin env to new class
Change-Id: Ib76891372be756917bddcf5eaa24ccf8e1288035
2024-11-29 17:55:07 +01:00
eldritch horrors 1ed0814859 libexpr: use eval() for builtin-using value printer tests
if we're relying on the behavior of builtins we can also use the parser.

Change-Id: I682722b2a22fbb6e748da2cab1bfeb76788bfb48
2024-11-29 17:45:04 +01:00
eldritch horrors 12802b492a libexpr: treat derivation like a normal primop for baseEnv construction
that way we don't need to eval while initializing the evaluator. this
will make a lot more sense once we start pushing asyncio through here

Change-Id: I3663052438ed97d48e213b71395ad1dd5e1318bb
2024-11-29 17:45:02 +01:00
eldritch horrors e9520ffd06 libexpr: add hidden pos origin for builtin code
currently only used to hide the nix code of derivation from stack traces
and debug frames, but perhaps we'll find it useful for other things too.

Change-Id: Ie5667873d8858d25dd4113bdf454e800b59082d7
2024-11-29 17:42:15 +01:00
eldritch horrors 63006438c4 libexpr: remove state reference from EvalError
nothing actually needs it. EvalErrorBuilder can have its own reference.

Change-Id: I8bf301d03a9c161519c130c95e58b1d5400e6411
2024-11-29 17:42:15 +01:00
eldritch horrors e44dbfe97a libexpr: move flake.nix attrsetness check out of eval state
this doesn't belong here, getFlake should be handling this instead. we
do lose the debug frame for loading a root flake, but that seems fine.
there's no point in starting a debugger if the root isn't even a flake

Change-Id: I24ad32b6716baee81a1a0f8bf9ce26814d97c7aa
2024-11-29 17:42:15 +01:00
eldritch horrors 94bb66c867 libexpr: remove maxPrimOpArity
this was only used to enable an optimization we no longer need such
strong guarantees for: SmallVector can be used with a dynamic size.

Change-Id: I4513fb7e665827fe363ce6308448656e6c5badb7
2024-11-29 17:42:15 +01:00
eldritch horrors 85d600ca4d libexpr: drop bison-specific \0\0 input trailer
bison needed it for internal reasons, the new parser does not.

Change-Id: I91f7aa23fb151e3152eee793a4fdce423fcf98d9
2024-11-29 17:42:15 +01:00
eldritch horrors 37aeb3059d libexpr: remove EvalState::addErrorTrace
Error::addTrace exists and is used far more often already. let's
standardize on the variant that doesn't need yet more templates.

Change-Id: If66b69ca02dbb546ce98cf385181bd13ce7ad9b5
2024-11-29 14:19:31 +00:00
eldritch horrors 105d8ceb36 libexpr: remove templated forceAttrs
the callback is always called immediately, which defeats the purpose of
the callback and the purpose of the template itself. there seems to not
be any performance impact of this. optimizing Value::determinePos would
be nice, but it's not used nearly often enough to matter at this point.

Change-Id: I2aec6a38103630652112f4b273653f11d2404c04
2024-11-29 14:19:31 +00:00
eldritch horrors 66d7128512 libexpr: remove EvalState parse caches
nothing needs these any more. the CLI calls evalFile, but only in places
where it'll only be called *once* per process lifetime. __import does so
too, but import doesn't care about the parse tree, only the eval result.

interestingly this improves eval performance by 6% on system eval unless
GC never occurs. no idea why this makes a GCing eval faster, but it does

Change-Id: I8289528550244e0a8b5ebc7284d8fb9aaac59e20
2024-11-29 13:29:31 +00:00
eldritch horrors f815b966c4 doc: remove utils.nix
only generate-manpage.nix uses it any more, so we can inline it there
instead of keeping it around as a separate generated header. doing so
will also allow us to remove caching functions needed *only for this*

Change-Id: I97ee91f1dd7140ecb69dbafd8479b82fba7981b8
2024-11-29 13:29:31 +00:00
eldritch horrors 2297d3f895 doc: remove obsolete files
these must've been forgotten during the move to generated builtins.

Change-Id: I0989847abc020e9356b996f26196d2c07953f77b
2024-11-29 13:29:31 +00:00
eldritch horrors 7c650ea241 libexpr: remove eval caches from EvalState
eval caches are not used by actual eval at all, only by the flake-shaped
wrappers around evaluation. moving caches into a subclass both clarifies
that eval caches and eval states are coupled and separates concerns that
should not have been intermixed as they were here. in the future we will
want to split up and decouple things even further. that'll have to wait.

Change-Id: I7b69510c0f8b212f05fae62e7b992d9475b4841f
2024-11-29 13:29:31 +00:00
eldritch horrors 564f464772 libcmd, nix: remove duplicated arguments
installables already have a ref<EvalState>. why are we passing the same
eval state in again, by reference, everywhere? that's just unnecessary.

Change-Id: I8225ea2575146edc55d283c0b5173b804553ceec
2024-11-29 13:29:31 +00:00
eldritch horrors f5754dc90a libexpr: move eval memory allocation to own struct
Change-Id: I9d472c9606fe66fdc1cb7cb9dcf6d1b6b46c6686
2024-11-28 15:12:22 +00:00
eldritch horrors cb8262e11c libexpr: remove EvalState::rootPath
this belongs to lazy trees, which we neither have nor intend to have.
we will keep SourcePath as that may come in handy at some later date.

Change-Id: I44b8f1dd6c435d7486c393fabdcd272766b2b56b
2024-11-28 15:12:22 +00:00
eldritch horrors 3593f5555e libexpr: handle debug trace frames as parent pointer list
this also fixes a debugger bug where leaving the debugger does not clean
up old debugger state completely. in such cases the fake frame withFrame
created was left behind after the corresponding caller frame was unwound

Change-Id: I45adcd116276b03b2f87076518c9eae6fe844e06
2024-11-28 15:12:22 +00:00
eldritch horrors 985afeeb4d libexpr: allocate debug state only when debugger is active
Change-Id: Id30f388264c5d1e472e3bdce5078db3914f3b475
2024-11-28 15:08:35 +00:00
eldritch horrors 35cb0cb28b libutil: make enumerate iter deref non-const
there's no need for this. no concept requires unary deref to be const.

Change-Id: I4e4592c5917382ad2dcc70e5d3f12662614b2fd1
2024-11-28 14:49:23 +00:00
eldritch horrors 5892ed2731 libutil: make generators iterable
range-for on generators sounds like a pretty good thing, right?

Change-Id: Ibed5e038c8dc50c918cf7c1f1aa70d822fb3efa2
2024-11-27 02:09:08 +01:00
eldritch horrors 89a0ddc108 libcmd: don't enter debugger immediately on nix repl --debugger
checking whether a repl hook is set does not tell whether it's running,
which in turn means we will enter a debug repl even when not debugging.
this is not very useful when we have no debug frames to inspect at all,
as commonly happens when starting a new repl with --debugger specified.

Change-Id: I7065dc4ec29743bdd53ed99c29d6592e2ceea89c
2024-11-27 02:09:08 +01:00
eldritch horrors 9554a1ae29 libexpr: remove dead code
Change-Id: Ife3a23822102b6038401e4944777392836039472
2024-11-27 02:09:08 +01:00
eldritch horrors 003883306d libexpr: move debug repl state into own struct
just to keep debug-related state closer together. eventually this will
also allow us to not allocate debugger state altogether unless needed.

Change-Id: Id83fea75d96d0ecbe21683cb1b57dd5b11b13535
2024-11-27 02:09:08 +01:00
eldritch horrors e635db77e3 libexpr: only runDebugRepl with EvalErrors
only break ever passed a non-EvalError, and even that was erroneous.

Change-Id: I03bb74d7fc449d9bab1e7d8e774389d2381ab457
2024-11-27 02:09:08 +01:00
eldritch horrors 7af000ddff libexpr: move symbols into own struct
not all of these are even used by eval itself. notably sWith wasn't used
at all, sEpsilon was only used by the eval cache one layer up, and other
attributes are used in places even further away from eval itself. we can
keep this commingling for now, but eventually we should clean it up too.

Change-Id: I5684ac614361bf008e04472130c6c02082b4c2d7
2024-11-27 02:09:08 +01:00
eldritch horrors f017f9ddd3 libexpr: extract some global constants from EvalState
these do not rely on the GC being initialized. there's no reason for
them to not be statics, shared between all eval states in a process.

Change-Id: Ib9675f3945d3a0a7097d6c85096adcbd6f441d83
2024-11-27 02:09:08 +01:00
eldritch horrors 650809f66e drop unnecessary EvalState shared pointers
currently ref<>s are used to share eval states between whatever created
that state and the various repl instances. repls however do not own any
eval states, not even partially. they only provide interactive use of a
previously allocated state that is owned by something else, notably for
debug repls which are run from *within* an evaluation which may already
be wrapped by another repl instance. presumably this was originally set
up like this to guarantee memory safety, even though it's never needed.

Change-Id: I29a2cd1d4245c077f9270452a0873d4c47448729
2024-11-27 02:09:08 +01:00
eldritch horrors f5cddcfc09 libcmd: make Repl instances proper scopes
there's no reason to ever *own* a repl instance. everything either wants
to run a repl and receive the result of that run, or run a repl and then
totally ignore the result. allowing non-transient repl instances doesn't
do anything useful for us, unless making ownership analysis hard counts.

this also fixes a bug in which a repl could ignore the store it was told
to use during construction, using the one returned by openStore instead.
this never showed up in lix because openStore() was always passed anyway

Change-Id: If2b1ad24ab74377340199b36af1dd629d7ce3f25
2024-11-27 02:09:08 +01:00
eldritch horrors 66f6dbda32 libstore: remove an unused function
Change-Id: If5e24046409f3c1d444e558306a98f3eba5845f4
2024-11-20 14:17:02 +00:00
eldritch horrors a911b44a31 libstore: break up QueryMissingContext::doPath
std::visit makes coroutines nearly impossible to use correctly.

Change-Id: I085c08b595a5d4a43208eb97f023aa00b48bff45
2024-11-20 14:17:02 +00:00
eldritch horrors 74d820e5e8 libstore: move Store::queryMissing into a fresh struct
we want to get rid of all these local lambdas, they make coroutines impossible.

Change-Id: I94336f0844e9cdb0aa27788d0ee5f99925f24e0c
2024-11-20 14:17:02 +00:00
eldritch horrors 9cf91b7385 cli infra: modernize legacy command interface
give legacy commands their program name and c++-converted argv directly
instead of passing on the (argc, argv) pair untouched. all are required
to process these things, and all of them do it in exactly the same way.
we can also remove a few old helpers only used to make this less awful.

Change-Id: I4ecd02343bca0cf85faf6fe043031d4f64c5f29c
2024-11-20 14:17:02 +00:00
eldritch horrors c4a077d0b8 libcmd: drop non-default ctors virtual inheritance
it's a trap. it's always a trap. non-default ctors of virtual base
classes must be called with the same parameters every time or very
surprising things will happen. good luck if you virtually derive a
class more than once with different ctor arguments. that'll break.

Change-Id: I1345963e69e98f37c3cbd070bae164d89eade455
2024-11-20 14:17:02 +00:00
eldritch horrors ac74dc3a2b treewide: drop trivial leaf virtual inheritance
this does nothing on classes that are never used as base classes and
have only a single base class of their own. all of these classes are
also made final to prove that they are indeed in this category. once
we need to derive any of them we can erase their `final` specifiers.

Change-Id: I4bd8e50a58815227392b5a5a762fda4542d15bae
2024-11-20 14:17:02 +00:00
eldritch horrors 34e592ea6a libcmd, nix: drop NixMultiCommand
there are no uses of plain MultiCommand as a base class *except* in
NixArgs, which is the only one that does not implement run(). there
is not much of a reason not to implement a run member there though,
so let's just do that and get rid of this weird intermediate class.

Change-Id: Ie84e3acd071b43bc186a2bac87646cbfb3aff845
2024-11-20 14:17:02 +00:00
eldritch horrors 95a9a4cece libstore: don't derive store classes from their configs
the very slight speedup in config setting access is not worth the
maintenance overhead of conflating concers like this. the virtual
inheritance scheme used for configs requires too much duplication
of base class constructor arguments to be worth doing. perhaps we
should get rid of all virtual inheritance of data-membered bases?

Change-Id: I4acf5ceaedb4ed7476efe1114c2e065ec72d2c6d
2024-11-20 14:59:40 +01:00
eldritch horrorsandjade b0d7a81613 fix tooling after include reorganization
clangd broke because it can't look through symlinks. compile_commands
manipulation does not fix it, clangd configuration does not fix it, a
vfs overlay does not fix it, and while a combination of those can fix
it with a bind mount in place that's just too cursed to even consider

clangd bug: https://github.com/llvm/llvm-project/issues/116877

Change-Id: I8e3e8489548eb3a7aa65ac9d12a5ec8abf814aec
2024-11-19 22:55:32 +00:00
eldritch horrors 16bed313c6 libstore: abort all curl transfers on interrupt
give the transfer progress callback a chance to register all transfers
as aborted when an interrupt event occurs. checkInterrupt() will throw
an Interrupted exception if an interrupt signal was caught, which will
immediately break out of the curl loop. it isn't even necessary within
the curl main loop as curl guarantees to call progress callbacks about
once per second (or more often), and we already abort transfers from a
progress update if a signal was caught. this may delay shutdown a bit,
but "about one second" as should not be noticeable in most situations.

fixes #577

Change-Id: Ida4e72732562bdf6560e4f182ecdcdb663c6dda5
2024-11-19 02:49:41 +01:00
eldritch horrors c859d03013 libfetchers: remove scheme static initializers
provide a initLibFetchers function instead that runs them explicitly.

Change-Id: Ida532e6ff18b72fdc21c9f98df7aceda6713e5df
2024-11-15 16:15:11 +01:00
eldritch horrors 8088927b90 libexpr: initGC -> initLibExpr
we'll put more stuff in there shortly. unfortunately.

Change-Id: I74be957469c3dcd5157f999e2cf23b1c668426d8
2024-11-15 16:15:11 +01:00
eldritch horrors 3dba1d341a libstore: remove TransferItem::phase
transferComplete has outlived its usefulness, and the other two phases
can be a boolean flag telling us whether we're still receiving headers

Change-Id: Ia943f95dcf0ce8ee2cc6d0f44ddf13151aef4346
2024-11-15 16:15:11 +01:00
eldritch horrors 3b1298efce libstore: simplify TransferSource::read
things can be much simpler if the read loop knows whether the transfer
is done or not. this information is available, let's pass it back down

Change-Id: Idb99afeb06a0d7a0999c3f4a1c6ce5adeab5f054
2024-11-15 16:15:11 +01:00
eldritch horrors b22f2bc8e9 libstore: use http for exceptionAbortsDownload tests
file:// urls are no longer handled by curl itself, and this is supposed
to test the curl wrapper. use http to force the wrapper to be involved.

Change-Id: Ib13087db07b3b2f1ae44ce8e3ec7a96d935b1bab
2024-11-15 16:15:11 +01:00
eldritch horrors 986a98d32f libstore: remove curlFileTransfer reference from transfers
they don't need these any more if we consider unpausing and cancelling
of transfers a cooperative affair between transfers and the curl_multi
handler. we can also remove an enable_shared_from_this base class now.

Change-Id: Iefa380df60c0cada53719cdaa500bab953892319
2024-11-15 16:15:11 +01:00
eldritch horrors 4ba19f68fb libstore: improve curl wrapper resource handling
wrap all curl pointers in unique pointers for move correctness. the
destructor of TransferItem can go away completely since it does not
do anything special any more: memory bookkeeping is done using raii
wrappers, and its effects on the transfer state are not observable.
only TransferSource inspects the result, and even it does not check
for transfer results in its own destructor (only during transfers).

Change-Id: Ibb58484703854d5d5425e7c63cf2985d93920e97
2024-11-15 16:15:11 +01:00
eldritch horrors 43777939eb libstore: simplify download buffer handling
keep the download buffer in TransferItem. keep only *one* download
buffer (not one for success returns and one for failures). we also
remove the asynchronous callbacks since they are no longer needed.

Change-Id: I9b1c1e4c59d5333602aea1c36e477c481eaaf98e
2024-11-12 14:01:57 +01:00
eldritch horrors 7d7e16ecec libstore: use curl-builtin read callback
when no custom READFUNCTION is set curl will fall back to using its
READDATA as a FILE pointer and calling fread on it to retrieve data
to send to the peer. we can wrap our upload data in a FILE pointer.
doing so also allows for upload retries, but we don't do that here.

Change-Id: I0509f936229dd978e89135862dacc8a3937cd4de
2024-11-12 14:01:57 +01:00
eldritch horrors 5be7956592 libstore: move remaining retry state out of TransferItem
Change-Id: Ie2c22722bdda18027017e12d10e16931a694743e
2024-11-12 14:01:57 +01:00
eldritch horrors efb04754be libstore: inline TransferItem::init into constructor
this function is called only once per object lifetime, and it's no
longer written such that it must be called by the curl thread. all
curl options set here are independent of the multi handle, there's
no good reason any more to split the constructor in two like that.

Change-Id: Ibfa9075bc1cfdbab979f995c5a942b47add9789d
2024-11-09 20:08:48 +00:00
eldritch horrors 001a078b96 libstore: move file transfer retry handling out of TransferItem
this simplifies the immediate curl wrappers significantly and clarifies
control flow for retries. we can almost see the promise land from here!

Change-Id: Idc66b744631eec9c1ad5a2be388beb942a04f1f9
2024-11-09 20:08:48 +00:00
eldritch horrors d75c399b29 libstore: delocalize TransferSource
future changes will need to add template functions to this class, which
cannot be done for classes declared locally in unctions. otherwise this
is mostly code motion to clean up enqueueFileTransfer a little further.

Change-Id: If9a9d9eb47ceadfa75a4eebd54e2db39f2305643
2024-11-09 20:08:48 +00:00
eldritch horrors 1338e93bc9 libstore: remove curlFileTransfer::enqueueItem return type
it's used only once, and the transfer is used for something else
afterwards as well. returning it hides that the same transfer is
being returned unchanged, and pointlessly extends the signature.

Change-Id: Idbd0af00f9aebd3606f6b537b9b7cc9263a45cf7
2024-11-09 20:08:48 +00:00
eldritch horrors 60e984f0cf libstore: allow explicit cancellation of transfers
we only wait for the worker thread to remove the handle from its multi
and then signal us back. after that's done the transfer can be cleaned
up independently of the multi handle and no transfer progress is made.

we also no longer remove transfer items from multi handles in the item
destructor; only the worker thread can add a transfer and as such only
the worker thread should be responsible for removing them again later.

Change-Id: I6ff57bb5e7c1e91faf8657b257e73d6a72aa928e
2024-11-09 20:08:48 +00:00
eldritch horrors 40cf413a48 libstore: make acceptRanges a function
we don't need to keep this as state. it's only used for retries anyway.

Change-Id: I807f161a516a226567972757ec07ff91b3cf0899
2024-11-09 20:08:48 +00:00
eldritch horrors 90536e27e1 libstore: simplify TransferSource::awaitData
don't pass in a lock that's only used inside this function.

Change-Id: I15c01e9cfe343cf13828ae3b3742c36ae697291f
2024-11-09 20:08:48 +00:00
eldritch horrors 5d02800e57 libstore: do not retry FileTransfer uploads
this only ever worked for empty uploads, and there it worked only by
complete accident: curl was asked to send more data than the wrapper
would provide, which curl would not like and report as an error. the
error would cause a retry with even less data to send, until finally
failing by running into the retry limit. let's just forbid all this.

Change-Id: I229a94b3b8b33e2c6cdb8ea19edd57cd6740e6c6
2024-11-09 20:08:48 +00:00
eldritch horrors 40be91afbf libstore: add filetranfer retry handling tests
we did not have any, despite retry handling being somewhat complex.

Change-Id: I5051a1c0a3861849ff67f512b33f6d3dda12cc95
2024-11-09 20:08:48 +00:00
eldritch horrors fb85228755 libstore: extract eager transfers into new method
we'll need this shared code for kjified transfers that don't use
sources. it's a while out, but we can clean this up now already.

Change-Id: Ife8c160e6ab379761362d6c54aba05093deee99e
2024-11-09 20:08:48 +00:00
eldritch horrors 12156d3beb libstore: fix download thread notifications
since 4ae6fb5a8f dropping a source of a
download might not properly cancel the associated curl transfer after
the transfer was paused. we have also not unpaused the transfer often
enough, only if the transfer buffer had been drained in its entirety.

Change-Id: Ic9298d9df71daa0f3d1c3fd718ed441edae9e863
2024-11-09 20:08:48 +00:00
eldritch horrors 1c28270c9d libstore: don't hold state lock while unpausing transfers
libcurl may call callbacks during unpause. if libcurl calls these
callbacks often enough they may find that they've exhausted their
allotted buffer space, at which point they will call dataCallback
as provided in enqueueFileTransfer. download() provides callbacks
that have their own state locks and may call unpause on transfers
with *their* state locks they share with curlFileTransfer. it was
possible to cause a deadlock between these two if the curl worker
thread tried to provide some data to a callback with the transfer
state lock held and the user transfer simultaneously unpaused its
associated curl transfer, with its own state lock held. obviously
not a great situation, but avoidable by not holding any lock when
we unpause transfers and execute their callbacks, as is otherwise
the case when a transfer runs normally and is never paused at all

Change-Id: I58556d292adaf7dfb14001d3a6c5c38fa71994da
2024-11-04 23:54:41 +00:00
eldritch horrors beb193d1e2 libstore: remove our custom early timeout handling
curl handles timeouts internally when it acts as the main event loop. we
only need to wake up to add new transfers to the multi handle or restart
an existing transfer that has passed its restart wait time. periodically
waking up is not required for curl, and we don't need it any more either

Change-Id: Ic774e1d9519f807cda1a89694bc3ede75216f329
2024-10-30 22:52:19 +00:00
eldritch horrors 4ae6fb5a8f libstore: pause only stalling transfers
don't pause the entire curl thread. we have multiple consumer threads
after all, not just one, so stalling all of them is likely not great.

note that libcurl advises against using transfer pauses if compressed
encodings are allowed and automatically decoded. this should not lead
to problems in practice because our data is usually not compressed to
such a degree that curl buffering *uncompressed* data matters. should
this cause problems we can reintroduce the whole-thread pause, but we
will probably get away with this until the entire file transfer class
is made kj::Promise-using async (and *then* curl can be hardpaused if
it cannot get rid of its data, solving the problem once and for all).

Change-Id: I218e41bfa5a27c7454eafb0bdb54f2a29a7f6493
2024-10-30 22:52:19 +00:00
eldritch horrors 9c22a4d31b libstore: don't use curl for file:// downloads
curl can't pause downloads of file:// urls, which is very much in the
way of making the curl wrapper fully asynchronous. we can emulate all
the things curl does, but unfortunately curl is *rather extensive* in
its support of frankly weird shit. hopefully this subset of features,
which notably does not include curl readdir support, is enough for us

Change-Id: I5f67768c4b512565655b94b0421270c7dbbd8d11
2024-10-28 18:52:49 +00:00
eldritch horrors c83b13eafd libstore: reunify all file transfer methods again
with the api cleaned up we can suddenly reunify uploads, downloads, and
existence checks through curl in the same wrapper function. uploads and
existence checks simply don't use the result source, and given that all
transfers (or at least *most* transfers to date) go through the network
the few extra allocations do not hurt us at all. even for file:// calls
the overhead won't much matter as going to disk and back *is* expensive

Change-Id: I4f9ca6681a8fc303377b4cf4c63e3363ae32c18b
2024-10-28 18:52:49 +00:00
eldritch horrors d65838a900 libstore: remove FileTransfer::enqueueDownload
it's no longer needed. `download` can do everything `enqueueDownload`
did, and a lot more. e.g. not block the calling thread, for instance.

Change-Id: I4b36235ed707c92d117b4c33efa3db50d26f9a84
2024-10-28 18:52:49 +00:00
eldritch horrors c68f0cdf00 libstore: return transfer metadata from download
as promised earlier. nothing uses it yet, but just you wait.

Change-Id: I77d185578d96c2134b756d20f2fcf1c02de0da6f
2024-10-28 18:52:49 +00:00
eldritch horrors 14eff10fe4 libstore: split callback into metadata and finished parts
this will let us return metadata from FileTransfer::download, which in
turn is necessary to remove enqueueDownload. it also opens avenues for
streaming downloads that keep download metadata instead of dropping it

Change-Id: If0fc6af5eb2aeb689fc866c345c9d7bce4d59f2d
2024-10-28 18:52:49 +00:00
eldritch horrors 923abe347c libstore: use data callback for simple downloads too
this is an intermediate step towards removing enqueueDownload entirely.

Change-Id: I05ec0c7f4a234fdc966e5005308b37f6f905d433
2024-10-28 18:52:49 +00:00
eldritch horrors 64864c3730 libstore: pass only data to TransferItem data callback
with encoding being handled by curl the reference is no longer needed.

Change-Id: Ibfaf5f55e5314e81ce45ba4523b960c401dd2e1c
2024-10-28 18:52:49 +00:00
eldritch horrors 10488f7431 libstore: use curl content-encoding support, not our own
let's use the automatic decoding functions curl provides instead of
implementing them ourselves for the dubious ability to support both
xz and bzip2 encodings as well, neither of which anything will send

Change-Id: I3edfebeb596a0e9d5c986efca9270501c996f2dd
2024-10-28 18:52:49 +00:00
eldritch horrorsandGerrit Code Review 61146c73ce Merge changes I0220cedd,Ide0c0512,I6fcd920e,I85ec62ff,I35853a91, ... into main
* changes:
  libstore: check that transfer headers don't change during retries
  libstore: use effective transfer url for retries
  libstore: collect effective url and cachedness earlier
  libstore: remove TransferItem::active
  libstore: always allocate TransferItem::req
  libstore: remove FileTransferResult::data
  libstore: de-future-ize FileTransfer::enqueueUpload
  libstore: remove FileTransferRequest
  libstore: remove FileTransferRequest::expectedETag
  libstore: remove FileTransferResult::bodySize
  libstore: remove FileTransferRequest::verifyTLS
  libstore: remove FiletransferRequest::head
2024-10-28 01:36:45 +00:00
eldritch horrors 212a14bb1f libstore: check that transfer headers don't change during retries
etag changing implies with high probability that the content of the
resource changed. immutable url changing implies that the immutable
url we got previously was wrong, which is probably a server bug. if
the encoding changes our decoding will break completely, so that is
also very illegal. one notable change we still allow is etags going
away completely, mostly since this does not imply any data changes.

Change-Id: I0220ceddc3fd732cd1b3bb39b40021cc631baadc
2024-10-27 21:44:38 +00:00
eldritch horrors 7c716b9716 libstore: use effective transfer url for retries
do not retread the entire redirection path if we've seen the end of the
road. this avoids silently downloading wrong data, and notifies us when
a url we've received data from turns into a redirect when retrying. for
reasons of simplicity we don't turn of libcurl redirects on retries. if
we did that we'd have to conditionally process http status codes, which
sounds annoying and would make the header callback even more of a mess.

Change-Id: Ide0c0512ef9b2579350101246d654a2375541a39
2024-10-27 21:44:38 +00:00
eldritch horrors 2b3bdda027 libstore: collect effective url and cachedness earlier
this will let us return metadata for a transfer without having to wait
for the entire transfer to complete. more importantly for current uses
though is that we could now send retries to the effective url directly
instead of retreading the entire redirect path. this improves latency,
and in such cases where redirects change while we're downloading it'll
also improve correctness (previously we'd silently download bad data).

Change-Id: I6fcd920eb96fbdb2e960b73773c0b854e0300e99
2024-10-27 21:44:38 +00:00
eldritch horrors 97c76c4655 libstore: remove TransferItem::active
it's always legal to call curl_multi_remove_handle on a valid pair of
multi and easy handles. removing an easy handle that is not currently
attached to a multi handle is a no-op, and removing an easy handle of
a different multi handle is something we can't reasonably trigger. if
we *did* ever manage it would result in an error we'd ignore, and the
handles in question would not be changed at all. this is just simpler

Change-Id: I85ec62ff89385981ca49d243376b9c32586bd128
2024-10-27 21:44:38 +00:00
eldritch horrors c82407fc1e libstore: always allocate TransferItem::req
there's no reason not to do this. also improve error handling a bit.

Change-Id: I35853a919fa58a9a34ad47ffab6de77ba6f7fb86
2024-10-27 21:44:38 +00:00
eldritch horrors 982d049d3b libstore: remove FileTransferResult::data
return it as a separate item in a pair instead. this will let us remove
enqueueDownload() in favor of returning metadata from download() itself

Change-Id: I74fad2ca15f920da1eefabc950c2baa2c360f2ba
2024-10-27 21:44:38 +00:00
eldritch horrors 5cd7055044 libstore: de-future-ize FileTransfer::enqueueUpload
it's only used once, and synchronously at that.

Change-Id: Ife9db15dd97bc0de8de59a25d27f3f7afeb8791b
2024-10-27 21:44:38 +00:00
eldritch horrors 6f18e1ebde libstore: remove FileTransferRequest
it's just a uri and some headers now. those can be function arguments
with no loss of clarity. *actual* additional arguments, for example a
TLS context with additional certificates, could be added on a new and
improved FileTransfer class that carries not just a backend reference
but some real, visible context for its transfers. curl not being very
multi-threading-friendly when using multi handles will make sharing a
bit hard anyway once we drop the single global download worker thread

Change-Id: Id2112c95cbd118c6d920488f38d272d7da926460
2024-10-27 21:44:38 +00:00
eldritch horrors a839c31e6c libstore: remove FileTransferRequest::expectedETag
just another http specific used in only one place.

Change-Id: I99361a7226f4e6cd8f18170d3683c0025657bcb3
2024-10-27 21:44:38 +00:00
eldritch horrors 30bec83fa4 libstore: remove FileTransferResult::bodySize
it's only used for internal bookkeeping in TransferItem.

Change-Id: I467c5be023488be4a8a76e5f98a4ef25762df6f3
2024-10-27 21:44:38 +00:00
eldritch horrors d82b212d33 libstore: remove FileTransferRequest::verifyTLS
it's never set to false.

Change-Id: I1e436c82f1097091a08faa1dfada75e51bd5edf9
2024-10-27 21:44:38 +00:00
eldritch horrors 220251ba51 libstore: remove FiletransferRequest::head
add a method to FileTransfer that provides this functionality instead.

Change-Id: Ic1933a5df76a109c248c9c5efea065356b20a6f9
2024-10-27 21:44:38 +00:00
eldritch horrors 6c2609c5f9 libstore: remove FileTransferRequest::tries
it's never set, and then only used internally. *once*.

Change-Id: I32585b1821e979f3ebb53b794ba0d1f576126b92
2024-10-26 21:42:35 +00:00
eldritch horrors af27d1ecd8 libstore: make baseRetryTimeMs a FileTransfer property
we don't even need this outside of tests. maybe we should not do
automatic retries at this level at all and use retrying wrappers
instead? at some point we may have to do this, but not just yet.

Change-Id: If0088aa55215be81f1770c25b3bb1b5268c65cf8
2024-10-26 21:42:35 +00:00
eldritch horrors 1e3b45546c libstore: remove FileTransferRequest::parentAct
never set explicitly, and transfers are never instantiated with one
current activity but submitted with a *different* current activity.

Change-Id: I1a3ec57c02013565aeb9e9398ea42d0c4279095e
2024-10-26 21:42:35 +00:00
eldritch horrors ce3e1d1e7a libstore: remove FileTransferRequests::data
use separate upload and download methods instead.

Change-Id: I5baa2177c8ddd70268c75ff074e361b2f17dddbd
2024-10-26 21:42:35 +00:00
eldritch horrors 2d49efaa2e libstore: remove Filetransfer::transfer
just use enqueueFileTransfer().get() insteaad.

Change-Id: I67a43c9d3d5f68ac3f9e8ba7973c243dd78b86a3
2024-10-26 21:42:35 +00:00
eldritch horrors 98b55c3a1d libstore: move FileTransferRequest::verb to TransferItem
this function is only used internally by curl wrapper.

Change-Id: I71d4c430cb069e2c949be769c17fede8dd04d480
2024-10-26 21:42:35 +00:00
eldritch horrors a83bf24281 libstore: remove FileTransferRequest::mimeType
it's only used by HttpBinaryCacheStore, and even there used in only on
place. this one place can set the header explicitly, which it now does

Change-Id: Id89228150669e25e7f59a3d6bd939e46059ce29e
2024-10-26 21:42:35 +00:00
eldritch horrors a8d6577bf0 libstore: HttpBinaryCacheStore::{makeRequest -> makeURI}
it only sets the one field anyway (and the parent activity as a side
effect that does not depend on the exact location of the constructor
call). when FileTransferRequest goes away we would need this anyway.

Change-Id: I35cf2ed3533239181449a62cf34cd282b395e5db
2024-10-26 20:35:16 +00:00
eldritch horrors 59e364c2a8 tests: stop using OCR for nix copy tests
this is fragile, slow as fuck, breaks constantly under high concurrency,
and completely unnecessary since ssh bypasses the stdio file descriptors
*anyway*. we do still check that we see ssh messages to ensure that none
of our subprocess handling messes with ssh's /dev/tty, but that's it now

Change-Id: Ib8e31e1999f813d07a27efc63a9d3454a9e4fcdd
2024-10-26 17:50:54 +00:00
eldritch horrors 5f1344dd8a libstore: turn Worker::run into a promise
a first little step into pushing the event loops up, up and away.
eventually we will want them to be instantiated only at the roots
of every thread (since kj binds loops to threads), but not today.

Change-Id: Ic97f1debba382a5a3f46daeaf2d6d434ee42569f
2024-10-23 11:55:12 +00:00
eldritch horrors faee771b30 libstore: hide Worker and goals where possible
goals should be considered internal to the worker architecture due to
the tight coupling of the two, and we can finally do that. doing this
is also a prerequisite for turning Worker::run() into a real promise.

Change-Id: I7cf273d4a6fdb75b8d192fce1af07c6265ff6980
2024-10-23 11:55:12 +00:00
eldritch horrors b8cc54df0a libstore: return relevant store path in goal result
we now do not need the goal pointers any more to process worker results.

Change-Id: I1a021b862ca666bcd23fee9f38973e90e6f94a72
2024-10-23 11:55:12 +00:00
eldritch horrors 67f1aafd61 libstore: restrict curl protocols
previously it was possible to fetchurl a dict server, or an ldap server,
or an imap server. this is a bit of a problem, both because rare schemes
may not be available on all systems, and because some schemes (e.g. scp)
are inherently insecure in potentially surprising ways we needn't allow.

Change-Id: I18fc567c6f58c3221b5ea8ce927f4da780057828
2024-10-23 11:32:14 +00:00
eldritch horrors 1d9d40b2a6 libstore: move failingExitStatus into worker results
we already have a results type for the entire worker call, we may as
well put this bit of info in there. we do keep the assumption of the
old code that the field will only be read if some goals have failed;
fixing that is a very different mess, and not immediately necessary.

Change-Id: If3fc32649dcd88e1987cdd1758c6c5743e3b35ac
2024-10-22 15:32:36 +00:00
eldritch horrors 343aca3a27 libstore: clear derivation build activities when done
without this derivations do not show as completely processed in the
internal-json logs (or the newer multiline output). the former also
breaks external tools like nix-output-monitor which, like multiline
output, grow vertically until at least some goals are finally freed

Change-Id: I55758daf526ba29ae15fb82e0d88da8afb45bf5c
2024-10-22 14:55:55 +00:00