inspector: split HTTP/WS server from the inspector #9630

Merged
merged 0 commits into from Dec 6, 2016

Projects

None yet

5 participants

@eugeneo
Contributor
eugeneo commented Nov 16, 2016
Checklist
  • make -j8 test (UNIX), or vcbuild test nosign (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines
Affected core subsystem(s)

inspector: HTTP server code was reworked and moved to a new file. No impact if the inspector is not started.

Description of change

Both our team experiments and some embedder request indicate a potential
in implementing alternative transport for inspector - e.g. IPC pipes or
custom embedder APIs. This change moves all HTTP specific code into a
separate class and is a first attempt at defining a boundary between the
inspector agent and transport. This API will be refined as new
transports are implemented.
Note that even without considering alternative transports, this change
enables better testing of the HTTP server (Valgrind it possible to identify
and fix some existing memory leaks).

CC: @ofrobots

@bnoordhuis
Member

Related test failures on the OS X buildbot: https://ci.nodejs.org/job/node-test-commit-osx/6038/nodes=osx1010/console - some inspector cctests are failing.

@eugeneo
Contributor
eugeneo commented Nov 17, 2016

I fixed the issues CI identified. New CI run (https://ci.nodejs.org/job/node-test-pull-request/4863/) seems to pass on all platforms, except ARM. Failures there seem to have to do with infrastructure failures unrelated to this PR.

node.gyp
@@ -865,10 +867,11 @@
{
'target_name': 'cctest',
'type': 'executable',
- 'dependencies': [ 'deps/gtest/gtest.gyp:gtest' ],
+ 'dependencies': ['deps/gtest/gtest.gyp:gtest' ],
@bnoordhuis
bnoordhuis Nov 17, 2016 Member

Unnecessary change.

@eugeneo
eugeneo Nov 17, 2016 Contributor

Fixed

src/inspector_agent.cc
+ const std::string& script_name, bool wait);
+ InspectorSession* StartSession(const std::string& id) override;
+ void MessageReceived(InspectorSession* session,
+ const std::string& message) override;
@bnoordhuis
bnoordhuis Nov 17, 2016 Member

Alignment is off here.

@eugeneo
eugeneo Nov 17, 2016 Contributor

Fixed

src/inspector_agent.cc
+ void EndSession(InspectorSession* session) override;
+ const std::vector<std::string> GetTargetIds() override;
+ const std::string GetTargetTitle(const std::string& id) override;
+ const std::string GetTargetUrl(const std::string& id) override;
@bnoordhuis
bnoordhuis Nov 17, 2016 Member

Returning const values (not references) is kind of odd. Doesn't g++ complain about that?

@eugeneo
eugeneo Nov 17, 2016 Contributor

It did not complain (neither did clang/Mac), I removed the const none the less.

src/inspector_agent.cc
bool AgentImpl::IsStarted() {
return !!platform_;
}
void AgentImpl::WaitForDisconnect() {
shutting_down_ = true;
+ Write(0, StringView());
@bnoordhuis
bnoordhuis Nov 17, 2016 Member

Why is this necessary? An explaining comment would be good.

@eugeneo
eugeneo Nov 17, 2016 Contributor

This is a temporary "command" to stop accepting new connections. In next pull request there will be a better API with meaningful requests as opposed to magical strings...

src/inspector_agent.cc
- }
- if (err != 0) {
+ InspectorAgentDelegate delegate(this, script_path, script_name_, wait_);
+ delegate_ = &delegate;
@bnoordhuis
bnoordhuis Nov 17, 2016 Member

You don't seem to reset delegate_ to nullptr anywhere.

@eugeneo
eugeneo Nov 17, 2016 Contributor

Fixed.

src/inspector_agent.cc
uv_loop_close(&child_loop_);
uv_sem_post(&start_sem_);
return;
}
- PrintDebuggerReadyMessage(port_, id_);
+ server_ = &server;
@bnoordhuis
bnoordhuis Nov 17, 2016 Member

Ditto for server_, it looks like.

@eugeneo
eugeneo Nov 17, 2016 Contributor

Fixed.

src/inspector_agent.h
#if !HAVE_INSPECTOR
#error("This header can only be used when inspector is enabled")
#endif
+
@bnoordhuis
bnoordhuis Nov 17, 2016 Member

Unnecessary whitespace change.

@eugeneo
eugeneo Nov 17, 2016 Contributor

Fixed.

src/inspector_agent.h
@@ -37,6 +40,10 @@ class Agent {
bool IsConnected();
void WaitForDisconnect();
+ void PostMessage(char* data, size_t len);
+ void StartSession();
+ void EndSession();
@bnoordhuis
bnoordhuis Nov 17, 2016 Member

These methods don't seem to be used or defined anywhere.

@eugeneo
eugeneo Nov 17, 2016 Contributor

Removed, at some points was considering a slightly different API.

src/inspector_socket_server.cc
+ }
+}
+
+std::string GetProcessTitle() {
@bnoordhuis
bnoordhuis Nov 17, 2016 Member

Seems to be unused.

@eugeneo
eugeneo Nov 17, 2016 Contributor

Yes, this ultimately remained in inspector_agent.cc...

src/inspector_socket_server.cc
+ fprintf(stderr,
+ "Debugger listening on port %d.\n"
+ "Warning: This is an experimental feature and could change at any time.\n",
+ port);
@bnoordhuis
bnoordhuis Nov 17, 2016 Member

Can you line up the arguments?

@eugeneo
eugeneo Nov 17, 2016 Contributor

Done.

@eugeneo
Contributor
eugeneo commented Nov 17, 2016 edited

@bnoordhuis Thank you for reviewing it. I addressed your comments (and also did another pass through function names and such). Please take another look.

@eugeneo
Contributor
eugeneo commented Nov 22, 2016

I am looking to rework this quite a bit, to define an easier to use API. Please do not review it for now.

@eugeneo
Contributor
eugeneo commented Nov 22, 2016

PR had been reworked, please review. I replaced the Session object with an integer session_id, it simplified the API.

src/inspector_socket_server.cc
+ auto found = std::find(callbacks_.begin(), callbacks_.end(), callback);
+ if (found == callbacks_.end()) {
+ callbacks_.push_back(callback);
+ }
@bnoordhuis
bnoordhuis Nov 24, 2016 Member

Not at all critical but doesn't it make more sense to use a std::set?

@eugeneo
eugeneo Nov 28, 2016 Contributor

Done.

src/inspector_socket_server.cc
+ const uv_buf_t* buf);
+ static void ReleaseMemory(InspectorSocket* socket, int code) {
+ delete SocketSession::From(socket);
+ }
@bnoordhuis
bnoordhuis Nov 24, 2016 Member

Unused, it seems?

@eugeneo
eugeneo Nov 28, 2016 Contributor

Removed, thanks.

src/inspector_socket_server.cc
+}
+
+bool InspectorSocketServer::TargetExists(const std::string& id) {
+ const std::vector<std::string>& targetIds = delegate_->GetTargetIds();
@bnoordhuis
bnoordhuis Nov 24, 2016 Member

target_ids

@eugeneo
eugeneo Nov 28, 2016 Contributor

Done.

+ }
+ EXPECT_EQ(0, err);
+ }
+};
@bnoordhuis
bnoordhuis Nov 24, 2016 Member

Can you share this code with test_inspector_socket.cc?

@eugeneo
eugeneo Nov 28, 2016 Contributor

That test is due for a more comprehensive cleanup so I will do it then (this will require adding new files, etc).

+ }
+
+ bool StartSession(int session_id,
+ const std::string& target_id) override {
@bnoordhuis
bnoordhuis Nov 24, 2016 Member

Funny alignment.

@eugeneo
eugeneo Nov 28, 2016 Contributor

Fixed.

+ uv_ip4_addr(host.c_str(), PORT, &addr);
+ int err = uv_tcp_connect(&connect_, &socket_,
+ reinterpret_cast<const sockaddr*>(&addr),
+ Connected_);
@bnoordhuis
bnoordhuis Nov 24, 2016 Member

Indentation is off.

@eugeneo
eugeneo Nov 28, 2016 Contributor

Fixed

+ uv_ip4_addr(host.c_str(), PORT, &addr);
+ int err = uv_tcp_connect(&connect_, &socket_,
+ reinterpret_cast<const sockaddr*>(&addr),
+ ConnectionMustFail_);
+ wrapper->eof_ = true;
+ } else {
+ wrapper->contents_.insert(wrapper->contents_.end(), buf->base,
+ buf->base + read);
@bnoordhuis
bnoordhuis Nov 24, 2016 Member

Indentation is off.

@eugeneo
eugeneo Nov 28, 2016 Contributor

Fixed.

+
+class ServerHolder {
+ public:
+ template<typename Delegate>
@bnoordhuis
bnoordhuis Nov 24, 2016 Member

Teeny tiny nit: we usually put a space before the <.

@eugeneo
eugeneo Nov 28, 2016 Contributor

Fixed.

+ socket1.TestHttpRequest("/json/list", "[ ]");
+ socket1.Close();
+ uv_run(&loop, UV_RUN_DEFAULT);
+}
@bnoordhuis
bnoordhuis Nov 24, 2016 Member

Can you fix the long lines in this file?

@eugeneo
eugeneo Nov 28, 2016 Contributor

Done.

@eugeneo
Contributor
eugeneo commented Nov 28, 2016

@bnoordhuis Thank you for the review. I uploaded updated commit, please take another look.

@eugeneo
Contributor
eugeneo commented Dec 2, 2016

@bnoordhuis I've updated the change, fixing the cpplint comment on the new test.

@eugeneo
Contributor
eugeneo commented Dec 2, 2016

I see a FreeBSD test failure that does not seem to be connected to this change.

@bnoordhuis

LGTM with a suggestion.

src/inspector_socket_server.cc
+
+// static
+void InspectorSocketServer::ServerClosedCallback(uv_handle_t* server) {
+ InspectorSocketServer* sserver = InspectorSocketServer::From(server);
@bnoordhuis
bnoordhuis Dec 5, 2016 Member

Suggestion: s/sserver/socket_server/ - the difference between server and sserver is very subtle.

@eugeneo
eugeneo Dec 6, 2016 Contributor

Done.

+#include <sstream>
+
+using InspectorSocketServer = node::inspector::InspectorSocketServer;
+using SocketServerDelegate = node::inspector::SocketServerDelegate;
@bnoordhuis
bnoordhuis Dec 5, 2016 Member

Isn't the linter complaining about a using directive outside a namespace?

@eugeneo
eugeneo Dec 6, 2016 Contributor

I moved the directives inside the namespace. Linter was fine - don't know if it is because of its settings.

@jasnell
jasnell approved these changes Dec 5, 2016 View changes
@eugeneo
Contributor
eugeneo commented Dec 6, 2016

Looks like https://ci.nodejs.org/job/node-test-pull-request/5271/ is all green but some glitch is preventing thew results to be reported back to GitHuib.

@eugeneo eugeneo added a commit to eugeneo/node that referenced this pull request Dec 6, 2016
@eugeneo eugeneo inspector: split HTTP/WS server from the inspector
Both our team experiments and some embedder request indicate a potential
in implementing alternative transport for inspector - e.g. IPC pipes or
custom embedder APIs. This change moves all HTTP specific code into a
separate class and is a first attempt at defining a boundary between the
inspector agent and transport. This API will be refined as new
transports are implemented.
Note that even without considering alternative transports, this change
enables better testing of the HTTP server (Valgrind made it possible to
identify and fix some existing memory leaks).

PR-URL: nodejs#9630
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
f7ca260
@eugeneo eugeneo closed this Dec 6, 2016
@eugeneo eugeneo merged commit 42da740 into nodejs:master Dec 6, 2016
@eugeneo eugeneo deleted the eugeneo:socket_server branch Dec 6, 2016
@eugeneo
Contributor
eugeneo commented Dec 6, 2016

Landed as 42da740

@MylesBorins
Member

@Fishrock123 this is another example of something that likely should not have gotten the dont-land label

@MylesBorins
Member

@eugeneo should this be backported to v6 or is this an example of something that requires the latest version of inspector api?

@eugeneo
Contributor
eugeneo commented Dec 21, 2016

This is a refactoring and does not require a new V8 inspector. I am not sure if it is needed for v6 (I'm not familiar with the policies) as main goal is to enable development of new features.

@evanlucas evanlucas added a commit that referenced this pull request Jan 3, 2017
@eugeneo @evanlucas eugeneo + evanlucas inspector: split HTTP/WS server from the inspector
Both our team experiments and some embedder request indicate a potential
in implementing alternative transport for inspector - e.g. IPC pipes or
custom embedder APIs. This change moves all HTTP specific code into a
separate class and is a first attempt at defining a boundary between the
inspector agent and transport. This API will be refined as new
transports are implemented.
Note that even without considering alternative transports, this change
enables better testing of the HTTP server (Valgrind made it possible to
identify and fix some existing memory leaks).

PR-URL: #9630
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
75129bb
@evanlucas evanlucas referenced this pull request Jan 3, 2017
Merged

v7.4.0 release proposal #10589

@evanlucas evanlucas added a commit that referenced this pull request Jan 3, 2017
@eugeneo @evanlucas eugeneo + evanlucas inspector: split HTTP/WS server from the inspector
Both our team experiments and some embedder request indicate a potential
in implementing alternative transport for inspector - e.g. IPC pipes or
custom embedder APIs. This change moves all HTTP specific code into a
separate class and is a first attempt at defining a boundary between the
inspector agent and transport. This API will be refined as new
transports are implemented.
Note that even without considering alternative transports, this change
enables better testing of the HTTP server (Valgrind made it possible to
identify and fix some existing memory leaks).

PR-URL: #9630
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
47310b6
@evanlucas evanlucas added a commit that referenced this pull request Jan 4, 2017
@eugeneo @evanlucas eugeneo + evanlucas inspector: split HTTP/WS server from the inspector
Both our team experiments and some embedder request indicate a potential
in implementing alternative transport for inspector - e.g. IPC pipes or
custom embedder APIs. This change moves all HTTP specific code into a
separate class and is a first attempt at defining a boundary between the
inspector agent and transport. This API will be refined as new
transports are implemented.
Note that even without considering alternative transports, this change
enables better testing of the HTTP server (Valgrind made it possible to
identify and fix some existing memory leaks).

PR-URL: #9630
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
0239561
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment