-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
inspector: split main thread interface from transport #21182
Conversation
@@ -90,7 +90,7 @@ class SignalWrap : public HandleWrap { | |||
#if defined(__POSIX__) && HAVE_INSPECTOR | |||
if (signum == SIGPROF) { | |||
Environment* env = Environment::GetCurrent(args); | |||
if (env->inspector_agent()->IsStarted()) { | |||
if (env->inspector_agent()->IsListening()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I am unsure about the semantics. Do we want this warning printed out when Inspector is installed on the isolate (which is currently "always", because of JS API and _debugProcess support) or when the WS server is running.
src/inspector_agent.cc
Outdated
client_ = | ||
std::shared_ptr<NodeInspectorClient>( | ||
new NodeInspectorClient(parent_env_, platform)); | ||
client_ = std::make_shared<NodeInspectorClient>(parent_env_, platform); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding is that make_shared should be fine as it is a part of C++11 (make_unique was introduced shortly after C++11)
src/inspector_agent.h
Outdated
}; | ||
|
||
class Agent { | ||
public: | ||
explicit Agent(node::Environment* env); | ||
~Agent(); | ||
|
||
// Create client_, may create io_ if option enabled | ||
// // Create client_, may create io_ if option enabled |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed locally, will upload when addressing future review comments.
src/inspector_io.cc
Outdated
int id_; | ||
}; | ||
|
||
// Passed to InspectorSocketServer to handle WS inspector protocol events, | ||
// mostly session start, message received, and session end. | ||
class InspectorIoDelegate: public node::inspector::SocketServerDelegate { | ||
public: | ||
InspectorIoDelegate(InspectorIo* io, const std::string& target_id, | ||
InspectorIoDelegate(std::shared_ptr<RequestQueue> queue, | ||
std::weak_ptr<MainThreadInterface> interface, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this is a first usage of std::weak_ptr in Node codebase. Standard seems to require it to be thread-safe. I would like to confirm with people familiar with less wide-spread platforms it is ok to use it here.
@@ -1,3 +1,4 @@ | |||
// Flags: --inspect=0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is because I assume handling SIGPROF should only produce the warning when the WS server is running
@@ -84,6 +83,7 @@ class InspectorSocketServerTest : public ::testing::Test { | |||
} | |||
}; | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will remove this delta in next upload.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work! I’ll need more time to look at this in detail, but I’ll try to do it if I find that time.
node.gyp
Outdated
'src/connection_wrap.h', | ||
'src/connect_wrap.h', | ||
'src/debug_utils.h', | ||
'src/env.h', | ||
'src/env-inl.h', | ||
'src/exceptions.h', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two headers don’t exist anymore, I think we want to remove them from this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
public: | ||
explicit DeleteSessionRequest(std::unique_ptr<InspectorSession> session) | ||
: session_(std::move(session)) {} | ||
void Call() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you mark these override
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
||
void DispatchFromInterrupt(v8::Isolate* isolate, | ||
void* interface) { | ||
reinterpret_cast<MainThreadInterface*>(interface)->DispatchMessages(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style nit: static_cast
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Thanks for the review. |
This PR needs bit more significant changes then anticipated, it is still in progress. |
I've uploaded a new change and this PR is now ready for review. This change addresses a race condition that caused some inspector tests to become unreliable, I will run stress tests to confirm it. |
CI link (all green): https://ci.nodejs.org/job/node-test-pull-request/15500/ |
Stress tests: https://ci.nodejs.org/job/node-stress-single-test/1926/nodes=win2016-1p-vs2017/console My understanding is that the tests were not flaky. Did I have to remove them from the flaky tests list first? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few nits.
src/inspector_io.h
Outdated
#include <memory> | ||
#include <stddef.h> | ||
|
||
#if !HAVE_INSPECTOR | ||
#error("This header can only be used when inspector is enabled") | ||
#endif | ||
|
||
|
||
// Forward declaration to break recursive dependency chain with src/env.h. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment should move with class Environment
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/inspector_io.cc
Outdated
for (const auto& outgoing : GetMessages()) { | ||
int session_id = std::get<1>(outgoing); | ||
switch (std::get<0>(outgoing)) { | ||
case TransportAction::kKill: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more level of indentaiton.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM but I'd like @addaleax to review also :-)
I did a rebase. I was unable to reintegrate WS messages logging, it was not implemented correctly (was accessing env from the non-main thread). Is it really necessary? |
@addaleax can you please take a look? |
Another CI, previous push excluded some fixes from another workstation: https://ci.nodejs.org/job/node-test-pull-request/15772/ |
template <typename T> | ||
class DeleteRequest : public Request { | ||
public: | ||
explicit DeleteRequest(T object) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I’d use std::shared_ptr<T> object
here explicitly, and std::shared_ptr<T> object_;
as the member, to be clearer about how this is being used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Added some asserts to ensure resetting the pointer actually destroys the object.
void DispatchFromInterrupt(v8::Isolate* isolate, | ||
void* interface) { | ||
static_cast<MainThreadInterface*>(interface)->DispatchMessages(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This can just be an inline lambda, that makes it a bit more readable since it’s much closer to the call site then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
~CrossThreadInspectorSessionBlock() { | ||
DeleteOnAnotherThread(handle_, std::move(session_)); | ||
} | ||
void Connect( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style nit: Leave a space between method definitions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
new DeleteRequest<Type>(std::move(object)))); | ||
} | ||
|
||
class CrossThreadInspectorSessionBlock { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be good to add a comment explaining what “Block” means in this context (It’s not clear to me at this point)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I renamed the class, hope now it is more clear. It is meant to keep the parts of the state that live on another thread separate.
|
||
private: | ||
void DispatchOnMainThread(std::unique_ptr<StringBuffer> message) { | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this unused?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
// when we reenter the DispatchMessages function. | ||
MessageQueue dispatching_message_queue_; | ||
bool dispatching_messages_ = false; | ||
Mutex state_lock_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a comment indicating which members exactly are protected by this lock?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Also, renamed the lock.
src/inspector_agent.cc
Outdated
int session_id, std::shared_ptr<NodeInspectorClient> client) | ||
: session_id_(session_id), client_(client) {} | ||
~SameThreadInspectorSession() override; | ||
void Dispatch(v8_inspector::StringView message) override; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const v8_inspector::StringView&
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/inspector_io.cc
Outdated
std::deque<std::tuple<TransportAction, int, | ||
std::unique_ptr<v8_inspector::StringBuffer>>>; | ||
|
||
explicit RequestQueueData(uv_loop_t* loop): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(tiny) style nit: put :
on the next line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/inspector_io.cc
Outdated
public: | ||
using MessageQueue = | ||
std::deque<std::tuple<TransportAction, int, | ||
std::unique_ptr<v8_inspector::StringBuffer>>>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth using std::deque<Message>
for some struct Message { … };
instead, for readability?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/inspector_io.cc
Outdated
node::ContainerOf(&RequestQueueData::async_, | ||
reinterpret_cast<uv_async_t*>(handle)); | ||
delete wrapper; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’d personally make both of these lambdas as well, for readability
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Thank you for the review. I addressed the comments. |
Investigating a test failure. |
Stress test for the fixed Windows failure: https://ci.nodejs.org/job/node-stress-single-test/1943/ New CI for this change: https://ci.nodejs.org/job/node-test-pull-request/15786/ |
100 iterations of the tests marked as flaky on Windows - https://ci.nodejs.org/job/node-stress-single-test/nodes=win2012r2-mp-vs2017/1944/ Looks like no failures, there is some weird macOS 10.10 failure, will need to investigate. |
I redid management for objects living on another thread. CI is green now: https://ci.nodejs.org/job/node-test-pull-request/15816/ I also run a stress test on a number of inspector flaky tests, seems like they should be fixed now. Delta with the reviewed version: 14cb71a I do not think the changes are big enough to invalidate the approvals, but I will wait a couple days in case there are any comments. |
Workers debugging will require interfacing between the "main" inspector and per-worker isolate inspectors. This is consistent with what WS interface does. This change is a refactoring change and does not change the functionality. PR-URL: #21182 Fixes: #21725 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
CI failure in the status bar looks weird (edit: see Eugene’s run below) |
CI: https://ci.nodejs.org/job/node-test-pull-request/15856/ There is one failure, when building V8 files on CentOS7. I am fairly confident this can be ignored. I will land the change. |
Landed in 39977db |
Workers debugging will require interfacing between the "main" inspector and per-worker isolate inspectors. This is consistent with what WS interface does. This change is a refactoring change and does not change the functionality. PR-URL: nodejs#21182 Fixes: nodejs#21725 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
After nodejs#21182, the test is no longer flaky. Since it doesn’t use a static port, moving it to parallel seems justified.
Workers debugging will require interfacing between the "main" inspector and per-worker isolate inspectors. This is consistent with what WS interface does. This change is a refactoring change and does not change the functionality. PR-URL: #21182 Fixes: #21725 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
Workers debugging will require interfacing between the "main" inspector and per-worker isolate inspectors. This is consistent with what WS interface does. This change is a refactoring change and does not change the functionality. PR-URL: nodejs#21182 Fixes: nodejs#21725 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
Unfortunately, this change seems to have increased the failure of sequential/test-debug-prompt test on OS X 10.10 (Yosemite) in CI from about 0.01% failure to about a 24% failure. See #21724. I'm not sure if the problem lies here or in the test or is something specific to older versions of OS X. EDIT: PR to possibly fix test: #21826. |
After #21182, the test is no longer flaky. Since it doesn’t use a static port, moving it to parallel seems justified. PR-URL: #21806 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Jon Moss <me@jonathanmoss.me> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Minwoo Jung <minwoo@nodesource.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
After #21182, the test is no longer flaky. Since it doesn’t use a static port, moving it to parallel seems justified. PR-URL: #21806 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Jon Moss <me@jonathanmoss.me> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Minwoo Jung <minwoo@nodesource.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Workers debugging will require interfacing between the "main" inspector
and per-worker isolate inspectors. This is consistent with what WS
interface does. This change is a refactoring change and does not change
the functionality.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes