Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
3bd9fc0
PTP: Use uv_executor_queue_work and add options for zlib, crypto
davisjam Aug 31, 2018
bc0f42e
PTP: First pass at node::threadpool
davisjam Sep 3, 2018
7200111
pTP: rewire NodePlatform to use Threadpool
davisjam Sep 6, 2018
662825f
PTP: Refactor out a LibuvExecutor
davisjam Sep 6, 2018
a894655
PTP: linting
davisjam Sep 6, 2018
8771ad8
PTP: Add state tracking for Tasks
davisjam Sep 6, 2018
3a2bbb6
PTP: Bugfix: start and stop DelayedTaskScheduler
davisjam Sep 6, 2018
8f6df02
PTP: BlockingDrain for Threadpool and TaskQueue
davisjam Sep 6, 2018
5892ef7
PTP: CreatePlatform creates its own TP
davisjam Sep 7, 2018
95bdaad
PTP: linting, comments, etc.
davisjam Sep 7, 2018
76ca768
PTP: More unit tests
davisjam Sep 7, 2018
83e91b4
PTP: Threadpool RAII; UV_THREADPOOL_SIZE
davisjam Sep 7, 2018
a654044
PTP: Cancel Tasks Post'ed to the Threadpool
davisjam Sep 7, 2018
706f2c6
PTP: Add WorkerGroup class to manage Workers
davisjam Sep 9, 2018
d79920f
PTP: Expose NodeThreadpool as public TP face
davisjam Sep 9, 2018
223cfc4
PTP: Subclass NodeThreadpool for CPU/IO split
davisjam Sep 9, 2018
f462078
PTP: Generalize subclass type
davisjam Sep 9, 2018
153dcdb
PTP: ByTaskOriginPartitonedNodeThreadpool
davisjam Sep 9, 2018
8cf91cd
PTP: ByTaskOriginAndTypePartitonedNodeThreadpool
davisjam Sep 10, 2018
21a931a
PTP: Track Task queue and run times
davisjam Sep 10, 2018
076ccca
PTP: Refactor to DRY in PartitionedNodeThreadpool
davisjam Sep 11, 2018
ec5e624
PTP: Profiling: Sample TaskQueue lengths
davisjam Sep 11, 2018
2547f52
PTP: Add UnpartitionedPartitionedNodeThreadpool
davisjam Sep 11, 2018
61b4cd3
PTP: Visualize threadpool behavior
davisjam Sep 11, 2018
0c40738
PTP: change env vars for consistency
davisjam Sep 16, 2018
003c147
PTP: dump stats in either [Signal]Exit or Start
davisjam Sep 16, 2018
c289dcd
PTP: PrintStats tweaks for easy parsing
davisjam Sep 17, 2018
c98c8d6
PTP: address changes in the libuv PR
davisjam Sep 30, 2018
64ce6e1
REMOVE ME: PTP: include libuv changes so people can try prototype
davisjam Sep 30, 2018
883d7fc
PTP: make linter happy
davisjam Sep 30, 2018
83e4214
REMOVE ME: PTP: include libuv changes so people can try prototype
davisjam Sep 30, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
PTP: dump stats in either [Signal]Exit or Start
Problem:
Apparently some uses of node go through Exit without fully cleaning up,
so printing stats in the PartitionedNodeThreadpool d'tor was not
giving us stats.

This was true, for example, for 'npm install'.

Solution:
DrainAndPrintStats in both node.cc::Start and node.cc::Exit,
and only keep the first one if we see it twice.

This should not be merged. Just performance profiling.
And dumping stats in SignalExit is unsafe.
  • Loading branch information
davisjam committed Sep 17, 2018
commit 003c147065f144de0e758e5bc83b567b1b146ea8
19 changes: 19 additions & 0 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -306,10 +306,20 @@ static struct {

libuv_executor_ = std::unique_ptr<threadpool::LibuvExecutor>(
new threadpool::LibuvExecutor(tp_));
printed_stats = false;
}

void DrainAndPrintStats(void) {
if (!printed_stats) {
tp_->BlockingDrain();
tp_->PrintStats();
printed_stats = true;
}
}

std::shared_ptr<threadpool::NodeThreadpool> tp_;
std::unique_ptr<threadpool::LibuvExecutor> libuv_executor_;
bool printed_stats;
} node_threadpool;

static struct {
Expand Down Expand Up @@ -1224,6 +1234,9 @@ static void Exit(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
WaitForInspectorDisconnect(env);
v8_platform.StopTracingAgent();

node_threadpool.DrainAndPrintStats();

env->Exit(args[0]->Int32Value());
}

Expand Down Expand Up @@ -2213,6 +2226,9 @@ void SetupProcessObject(Environment* env,


void SignalExit(int signo) {
// Yeah, yeah, this is not signal safe.
node_threadpool.DrainAndPrintStats();

uv_tty_reset_mode();
v8_platform.StopTracingAgent();
#ifdef __FreeBSD__
Expand Down Expand Up @@ -3377,6 +3393,7 @@ int Start(int argc, char** argv) {
// Replace the default V8 platform with our implementation.
// Use our threadpool.
v8_platform.Initialize(node_threadpool.tp_);

V8::Initialize();
performance::performance_v8_start = PERFORMANCE_NOW();
v8_initialized = true;
Expand All @@ -3394,6 +3411,8 @@ int Start(int argc, char** argv) {
// will never be fully cleaned up.
v8_platform.Dispose();

node_threadpool.DrainAndPrintStats();

return exit_code;
}

Expand Down
10 changes: 9 additions & 1 deletion src/node_threadpool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ int NodeThreadpool::NWorkers() const {
return tp_->NWorkers();
}

void NodeThreadpool::PrintStats() const {
}

/**************
* PartitionedNodeThreadpool
***************/
Expand All @@ -112,12 +115,17 @@ void PartitionedNodeThreadpool::Initialize(const std::vector<int>& tp_sizes) {
}

PartitionedNodeThreadpool::~PartitionedNodeThreadpool() {
LOG("PartitionedNodeThreadpool::~PartitionedNodeThreadpool: Goodbye\n");
fflush(stderr);

// If we just return, the destructors of the tp's will drain them.
// But if we want to report meaningful statistics we must drain them first.
for (auto &tp : tps_) {
tp->BlockingDrain();
}
}

void PartitionedNodeThreadpool::PrintStats(void) const {
// TODO(davisjam) Let's hope the application didn't make more than one of these :-D.
char logFile[128];
snprintf(logFile, sizeof(logFile), "/tmp/node-%d-PartitionedNodeThreadpool-result.log", getpid());
Expand All @@ -129,7 +137,7 @@ PartitionedNodeThreadpool::~PartitionedNodeThreadpool() {
// so we can slice and dice quickly.
LOG_TO_FILE(fd, "TP key format: TP,name,size\n");
for (auto pair : tp_labels_) {
LOG_TO_FILE(fd, "TP key: %d,%s,%d\n", pair.first, tp_labels_[pair.first].c_str(), tp_sizes_[pair.first]);
LOG_TO_FILE(fd, "TP key: %d,%s,%d\n", pair.first, tp_labels_.at(pair.first).c_str(), tp_sizes_.at(pair.first));
}

LOG_TO_FILE(fd, "QueueLengths data format: TP,queue-length,n_cpu,n_io,time\n");
Expand Down
5 changes: 5 additions & 0 deletions src/node_threadpool.h
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,9 @@ class NodeThreadpool {
// Attributes
virtual int NWorkers() const;

// Does nothing. Subclasses can implement.
virtual void PrintStats() const;

protected:
int GoodCPUThreadpoolSize();

Expand Down Expand Up @@ -422,6 +425,8 @@ class PartitionedNodeThreadpool : public NodeThreadpool {

virtual int NWorkers() const override;

virtual void PrintStats() const override;

protected:
// Sub-classes should call this after computing tp_sizes in their c'tors.
void Initialize(const std::vector<int>& tp_sizes);
Expand Down