1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2024-10-18 00:16:11 -04:00

Compare commits

...

16 commits

Author SHA1 Message Date
Jörg Thalheim 935c32eee5
Merge 794007cab7 into 1cd48008f0 2024-10-17 14:53:33 +02:00
Eelco Dolstra 1cd48008f0
Merge pull request #11710 from NixOS/doc-onboarding
maintainers/onboarding: Start documenting
2024-10-17 11:06:23 +02:00
Eelco Dolstra 2e2c7f3b14
Merge pull request #11709 from DeterminateSystems/remove-team-list
maintainers/README.md: Remove the list of team members
2024-10-17 11:05:55 +02:00
Robert Hensing c196011d23 maintainers/onboarding: Start documenting 2024-10-16 22:06:28 +02:00
Eelco Dolstra 7bd0c70b37 maintainers/README.md: Remove the list of team members
Let's have one canonical location for the team membership.
2024-10-16 22:03:44 +02:00
Robert Hensing f51974d698
Merge pull request #11665 from roberth/fix-Interrupted-falling-out-of-thread
Fix `Interrupted` falling out of thread crash
2024-10-16 20:09:29 +02:00
Robert Hensing ed184f0b61
Typo
Co-authored-by: Cole Helbling <cole.e.helbling@outlook.com>
2024-10-16 19:40:45 +02:00
Eelco Dolstra facc502bc8
Merge pull request #11695 from DeterminateSystems/override-lastModified
path fetcher: Allow the lastModified attribute to be overriden again
2024-10-16 18:03:29 +02:00
Robert Hensing fd8a4a86d9 ThreadPool: don't silently ignore non-std exceptions
Introduced in 8f6b347abd without explanation.

Throwing anything that's not that is a programming mistake that we don't want
to ignore silently. A crash would be ok, because that means we/they can fix
the offending throw.
2024-10-16 17:56:08 +02:00
Robert Hensing 16320f6d24 Handle ThreadPoolShutdown with normal catch 2024-10-16 17:56:08 +02:00
Robert Hensing 3f9ff10786 ThreadPool: catch Interrupted 2024-10-16 17:56:08 +02:00
Robert Hensing de41e46175 Document recursive-nix startDaemon/stopDaemon 2024-10-16 17:56:08 +02:00
Robert Hensing 0e5a5303ad fix: Ignore Interrupted in recursive-nix daemon worker
Otherwise, if checkInterrupt() in any of the supported store operations
would catch onto a user interrupt, the exception would bubble to the thread
start and be handled by std::terminate(): a crash.
2024-10-16 17:56:08 +02:00
Eelco Dolstra 781ff7672e Add test 2024-10-16 17:18:07 +02:00
Eelco Dolstra 5d35424445 path fetcher: Allow the lastModified attribute to be overriden again
Fixes #11660.
2024-10-14 16:17:18 +02:00
Jörg Thalheim 794007cab7 add stack sampling profiler for flamegraphs
This is code is a bit rough in the sense that I have taken shortcuts to
quickly iterate.
This is not ready for merging yet, but I think it's already useful for
people that want to generate flamegraphs for things as large as NixOS.

Usage:

NIX_PROFILE_FILE=/tmp/nixos-trace nix eval -v --no-eval-cache
.#nixosConfigurations.turingmachine.config.system.build.toplevel

The result can be imported in tools that support folded stacks i.e.
https://www.speedscope.app/ or the original flamegraph script
(https://github.com/brendangregg/FlameGraph)

The profiler records stack trace of the nix evaluation every 10ms (100Hz).
The resulting file is 1.9GB uncompressed and 5.4MB compressed with zstd.

Change-Id: I3484d3bd832e612747d02c251f2763e0c133a5dc
2024-09-09 07:35:53 +02:00
9 changed files with 91 additions and 10 deletions

View file

@ -29,11 +29,7 @@ We aim to achieve this by improving the contributor experience and attracting mo
## Members ## Members
- Eelco Dolstra (@edolstra) Team lead See https://nixos.org/community/teams/nix/ for the current team membership.
- Valentin Gagarin (@fricklerhandwerk)
- Thomas Bereknyei (@tomberek)
- Robert Hensing (@roberth)
- John Ericson (@Ericson2314)
The team is on Github as [@NixOS/nix-team](https://github.com/orgs/NixOS/teams/nix-team). The team is on Github as [@NixOS/nix-team](https://github.com/orgs/NixOS/teams/nix-team).

View file

@ -0,0 +1,6 @@
# Onboarding a new team member
- https://github.com/NixOS/nixos-homepage/
- https://github.com/orgs/NixOS/teams/nix-team
- Matrix room

View file

@ -332,6 +332,36 @@ EvalState::EvalState(
EvalState::~EvalState() EvalState::~EvalState()
{ {
auto profileFile = getEnv("NIX_PROFILE_FILE");
std::map<PosIdx, std::string> cachedPositions;
if (!profileFile.has_value()) {
return;
}
std::ofstream profileStream(profileFile.value());
if (!profileStream) {
return;
}
for (auto & [stack, count] : callCount) {
auto first = true;
for (auto & pos : stack) {
if (first) {
first = false;
} else {
profileStream << ";";
}
if (auto it = cachedPositions.find(pos); it != cachedPositions.end()) {
profileStream << it->second;
} else {
std::stringstream posStr;
posStr << positions[pos];
cachedPositions[pos] = posStr.str();
profileStream << posStr.str();
}
}
profileStream << " " << count << std::endl;
}
} }
@ -1448,15 +1478,36 @@ void ExprOpHasAttr::eval(EvalState & state, Env & env, Value & v)
v.mkBool(true); v.mkBool(true);
} }
void ExprLambda::eval(EvalState & state, Env & env, Value & v) void ExprLambda::eval(EvalState & state, Env & env, Value & v)
{ {
v.mkLambda(&env, this); v.mkLambda(&env, this);
} }
static const std::chrono::duration SAMPLE_INTERVAL = std::chrono::microseconds(10);
namespace {
class SampleStack {
EvalState & state;
public:
SampleStack(EvalState & state, const PosIdx pos) : state(state) {
state.stack.push_back(pos);
}
~SampleStack() {
auto now = std::chrono::high_resolution_clock::now();
if (now - state.lastStackSample > SAMPLE_INTERVAL) {
state.callCount[state.stack] += 1;
state.lastStackSample = now;
}
if (state.stack.size() > 0) {
state.stack.pop_back();
}
}
};
};
void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & vRes, const PosIdx pos) void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & vRes, const PosIdx pos)
{ {
auto _level = addCallDepth(pos); auto _level = addCallDepth(pos);
SampleStack _sample(*this, pos);
auto trace = settings.traceFunctionCalls auto trace = settings.traceFunctionCalls
? std::make_unique<FunctionCallTrace>(positions[pos]) ? std::make_unique<FunctionCallTrace>(positions[pos])

View file

@ -15,6 +15,7 @@
#include "search-path.hh" #include "search-path.hh"
#include "repl-exit-status.hh" #include "repl-exit-status.hh"
#include "ref.hh" #include "ref.hh"
#include "pos-idx.hh"
#include <map> #include <map>
#include <optional> #include <optional>
@ -363,6 +364,10 @@ private:
public: public:
std::vector<PosIdx> stack = {};
std::map<std::vector<PosIdx>, int> callCount = {};
std::chrono::time_point<std::chrono::high_resolution_clock> lastStackSample = std::chrono::high_resolution_clock::now();
EvalState( EvalState(
const LookupPath & _lookupPath, const LookupPath & _lookupPath,
ref<Store> store, ref<Store> store,
@ -838,6 +843,7 @@ private:
bool countCalls; bool countCalls;
typedef std::map<std::string, size_t> PrimOpCalls; typedef std::map<std::string, size_t> PrimOpCalls;
PrimOpCalls primOpCalls; PrimOpCalls primOpCalls;

View file

@ -157,7 +157,11 @@ struct PathInputScheme : InputScheme
}); });
storePath = store->addToStoreFromDump(*src, "source"); storePath = store->addToStoreFromDump(*src, "source");
} }
input.attrs.insert_or_assign("lastModified", uint64_t(mtime));
/* Trust the lastModified value supplied by the user, if
any. It's not a "secure" attribute so we don't care. */
if (!input.getLastModified())
input.attrs.insert_or_assign("lastModified", uint64_t(mtime));
return {makeStorePathAccessor(store, *storePath), std::move(input)}; return {makeStorePathAccessor(store, *storePath), std::move(input)};
} }

View file

@ -65,6 +65,7 @@
#include <iostream> #include <iostream>
#include "strings.hh" #include "strings.hh"
#include "signals.hh"
namespace nix { namespace nix {
@ -1579,6 +1580,8 @@ void LocalDerivationGoal::startDaemon()
FdSink(remote.get()), FdSink(remote.get()),
NotTrusted, daemon::Recursive); NotTrusted, daemon::Recursive);
debug("terminated daemon connection"); debug("terminated daemon connection");
} catch (const Interrupted &) {
debug("interrupted daemon connection");
} catch (SystemError &) { } catch (SystemError &) {
ignoreExceptionExceptInterrupt(); ignoreExceptionExceptInterrupt();
} }

View file

@ -225,8 +225,15 @@ struct LocalDerivationGoal : public DerivationGoal
*/ */
void writeStructuredAttrs(); void writeStructuredAttrs();
/**
* Start an in-process nix daemon thread for recursive-nix.
*/
void startDaemon(); void startDaemon();
/**
* Stop the in-process nix daemon thread.
* @see startDaemon
*/
void stopDaemon(); void stopDaemon();
/** /**

View file

@ -110,10 +110,15 @@ void ThreadPool::doWork(bool mainThread)
propagate it. */ propagate it. */
try { try {
std::rethrow_exception(exc); std::rethrow_exception(exc);
} catch (const Interrupted &) {
// The interrupted state may be picked up by multiple
// workers, which is expected, so we should ignore
// it silently and let the first one bubble up,
// rethrown via the original state->exception.
} catch (const ThreadPoolShutDown &) {
// Similarly expected.
} catch (std::exception & e) { } catch (std::exception & e) {
if (!dynamic_cast<ThreadPoolShutDown*>(&e)) ignoreExceptionExceptInterrupt();
ignoreExceptionExceptInterrupt();
} catch (...) {
} }
} }
} }

View file

@ -6,3 +6,6 @@ touch "$TEST_ROOT/foo" -t 202211111111
# We only check whether 2022-11-1* **:**:** is the last modified date since # We only check whether 2022-11-1* **:**:** is the last modified date since
# `lastModified` is transformed into UTC in `builtins.fetchTarball`. # `lastModified` is transformed into UTC in `builtins.fetchTarball`.
[[ "$(nix eval --impure --raw --expr "(builtins.fetchTree \"path://$TEST_ROOT/foo\").lastModifiedDate")" =~ 2022111.* ]] [[ "$(nix eval --impure --raw --expr "(builtins.fetchTree \"path://$TEST_ROOT/foo\").lastModifiedDate")" =~ 2022111.* ]]
# Check that we can override lastModified for "path:" inputs.
[[ "$(nix eval --impure --expr "(builtins.fetchTree { type = \"path\"; path = \"$TEST_ROOT/foo\"; lastModified = 123; }).lastModified")" = 123 ]]