From f9e83af4753054b2033e074c75d0cb19128b2b3f Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Wed, 12 Mar 2025 12:26:58 -0400 Subject: [PATCH] LibDevTools: Re-implement how we handle ordered responses We must reply to requests received from the client in the order they are received. The wrench in this requirement is handling requests that must be performed asynchronously, such as fetching the serialized DOM tree from the WebContent process. We currently handle this with a "block token". Async request handlers hold a token that blocks any subsequent responses from being sent. When that token is removed (i.e. the async request now has a response to be sent), the async response is then sent followed by the blocked responses in-order. This strategy had a limitation that we could not handle an actor trying to take 2 block tokens, meaning only one async request could be handled at a time. This has been fine so far, but an upcoming feature (style sheet sources) will break this limitation. The client will request N sources at a time, which would try to take N block tokens. The new strategy is to assign all requests an ID, and store a list of request IDs that are awaiting a response. When the server wants to send a reply, we match the ID of the replied-to message to this list of IDs. If it is not the first in this list, then we are blocked waiting for an earlier reply, and just store the response. When the earlier request(s) receive their response, we can then send out all blocked replies (up to the next request that has not yet received a response). --- Libraries/LibDevTools/Actor.cpp | 113 +++++++++--------- Libraries/LibDevTools/Actor.h | 56 +++++---- .../LibDevTools/Actors/CSSPropertiesActor.cpp | 2 +- Libraries/LibDevTools/Actors/ConsoleActor.cpp | 6 +- Libraries/LibDevTools/Actors/DeviceActor.cpp | 2 +- Libraries/LibDevTools/Actors/FrameActor.cpp | 4 +- .../LibDevTools/Actors/HighlighterActor.cpp | 4 +- .../LibDevTools/Actors/InspectorActor.cpp | 8 +- .../Actors/LayoutInspectorActor.cpp | 4 +- Libraries/LibDevTools/Actors/NodeActor.cpp | 14 +-- .../LibDevTools/Actors/PageStyleActor.cpp | 14 +-- Libraries/LibDevTools/Actors/PageStyleActor.h | 2 +- .../LibDevTools/Actors/PreferenceActor.cpp | 2 +- Libraries/LibDevTools/Actors/RootActor.cpp | 18 +-- Libraries/LibDevTools/Actors/TabActor.cpp | 4 +- .../Actors/TargetConfigurationActor.cpp | 2 +- .../Actors/ThreadConfigurationActor.cpp | 2 +- Libraries/LibDevTools/Actors/WalkerActor.cpp | 60 +++++----- Libraries/LibDevTools/Actors/WatcherActor.cpp | 10 +- Libraries/LibDevTools/DevToolsServer.cpp | 6 +- 20 files changed, 165 insertions(+), 168 deletions(-) diff --git a/Libraries/LibDevTools/Actor.cpp b/Libraries/LibDevTools/Actor.cpp index 427f589d320..6365809fada 100644 --- a/Libraries/LibDevTools/Actor.cpp +++ b/Libraries/LibDevTools/Actor.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -20,29 +21,70 @@ Actor::~Actor() = default; void Actor::message_received(StringView type, JsonObject message) { - handle_message({ type, move(message) }); + auto message_id = m_next_message_id++; + m_pending_responses.empend(message_id, OptionalNone {}); + + handle_message({ type, move(message), message_id }); } -void Actor::send_message(JsonObject message, Optional block_token) +void Actor::send_response(Message const& message, JsonObject response) { - if (m_block_responses && !block_token.has_value()) { - m_blocked_responses.append(move(message)); + auto& connection = devtools().connection(); + if (!connection) return; + + response.set("from"sv, name()); + + for (auto const& [i, pending_response] : enumerate(m_pending_responses)) { + if (pending_response.id != message.id) + continue; + + pending_response.response = move(response); + + if (i != 0) + return; } + size_t number_of_sent_messages = 0; + + for (auto const& pending_response : m_pending_responses) { + if (!pending_response.response.has_value()) + break; + + connection->send_message(*pending_response.response); + ++number_of_sent_messages; + } + + m_pending_responses.remove(0, number_of_sent_messages); +} + +void Actor::send_message(JsonObject message) +{ + auto& connection = devtools().connection(); + if (!connection) + return; + message.set("from"sv, name()); - if (auto& connection = devtools().connection()) - connection->send_message(move(message)); + if (m_pending_responses.is_empty()) { + connection->send_message(message); + return; + } + + m_pending_responses.empend(OptionalNone {}, move(message)); } // https://firefox-source-docs.mozilla.org/devtools/backend/protocol.html#error-packets -void Actor::send_missing_parameter_error(StringView parameter) +void Actor::send_missing_parameter_error(Optional message, StringView parameter) { JsonObject error; error.set("error"sv, "missingParameter"sv); error.set("message"sv, MUST(String::formatted("Missing parameter: '{}'", parameter))); - send_message(move(error)); + + if (message.has_value()) + send_response(*message, move(error)); + else + send_message(move(error)); } // https://firefox-source-docs.mozilla.org/devtools/backend/protocol.html#error-packets @@ -51,64 +93,21 @@ void Actor::send_unrecognized_packet_type_error(Message const& message) JsonObject error; error.set("error"sv, "unrecognizedPacketType"sv); error.set("message"sv, MUST(String::formatted("Unrecognized packet type: '{}'", message.type))); - send_message(move(error)); + send_response(message, move(error)); } // https://github.com/mozilla/gecko-dev/blob/master/devtools/server/actors/object.js // This error is not documented, but is used by Firefox nonetheless. -void Actor::send_unknown_actor_error(StringView actor) +void Actor::send_unknown_actor_error(Optional message, StringView actor) { JsonObject error; error.set("error"sv, "unknownActor"sv); error.set("message"sv, MUST(String::formatted("Unknown actor: '{}'", actor))); - send_message(move(error)); -} -Actor::BlockToken Actor::block_responses() -{ - // https://firefox-source-docs.mozilla.org/devtools/backend/protocol.html#the-request-reply-pattern - // The actor processes packets in the order they are received, and the client can trust that the i’th reply - // corresponds to the i’th request. - - // The above requirement gets tricky for actors which require an async implementation. For example, the "getWalker" - // message sent to the InspectorActor results in the server fetching the DOM tree as JSON from the WebContent process. - // We cannot reply to the message until that is received. However, we will likely receive more messages from the - // client in that time. We cannot reply to those messages until we've replied to the "getWalker" message. Thus, we - // use this token to queue responses from the actor until that reply can be sent. - return { {}, *this }; -} - -Actor::BlockToken::BlockToken(Badge, Actor& actor) - : m_actor(actor) -{ - // If we end up in a situtation where an actor has multiple async handlers at once, we will need to come up with a - // more sophisticated blocking mechanism. - VERIFY(!actor.m_block_responses); - actor.m_block_responses = true; -} - -Actor::BlockToken::BlockToken(BlockToken&& other) - : m_actor(move(other.m_actor)) -{ -} - -Actor::BlockToken& Actor::BlockToken::operator=(BlockToken&& other) -{ - m_actor = move(other.m_actor); - return *this; -} - -Actor::BlockToken::~BlockToken() -{ - auto actor = m_actor.strong_ref(); - if (!actor) - return; - - auto blocked_responses = move(actor->m_blocked_responses); - actor->m_block_responses = false; - - for (auto& message : blocked_responses) - actor->send_message(move(message)); + if (message.has_value()) + send_response(*message, move(error)); + else + send_message(move(error)); } } diff --git a/Libraries/LibDevTools/Actor.h b/Libraries/LibDevTools/Actor.h index 75040122986..02cf30dc74d 100644 --- a/Libraries/LibDevTools/Actor.h +++ b/Libraries/LibDevTools/Actor.h @@ -6,7 +6,6 @@ #pragma once -#include #include #include #include @@ -25,8 +24,9 @@ class Actor , public Weakable { public: struct Message { - StringView type; - JsonObject data; + StringView type {}; + JsonObject data {}; + u64 id { 0 }; }; virtual ~Actor(); @@ -35,25 +35,15 @@ public: void message_received(StringView type, JsonObject); - class [[nodiscard]] BlockToken { - public: - BlockToken(Badge, Actor&); - ~BlockToken(); + // Use send_response when replying directly to a request received from the client. + void send_response(Message const&, JsonObject); - BlockToken(BlockToken const&) = delete; - BlockToken& operator=(BlockToken const&) = delete; + // Use send_message when sending an unprompted message to the client. + void send_message(JsonObject); - BlockToken(BlockToken&&); - BlockToken& operator=(BlockToken&&); - - private: - WeakPtr m_actor; - }; - - void send_message(JsonObject, Optional block_token = {}); - void send_missing_parameter_error(StringView parameter); + void send_missing_parameter_error(Optional, StringView parameter); void send_unrecognized_packet_type_error(Message const&); - void send_unknown_actor_error(StringView actor); + void send_unknown_actor_error(Optional, StringView actor); protected: explicit Actor(DevToolsServer&, String name); @@ -63,8 +53,6 @@ protected: DevToolsServer& devtools() { return m_devtools; } DevToolsServer const& devtools() const { return m_devtools; } - BlockToken block_responses(); - template auto get_required_parameter(Message const& message, StringView parameter) { @@ -84,15 +72,17 @@ protected: }(); if (!result.has_value()) - send_missing_parameter_error(parameter); + send_missing_parameter_error(message, parameter); return result; } template - auto async_handler(Handler&& handler) + auto async_handler(Optional message, Handler&& handler) { - return [weak_self = make_weak_ptr(), handler = forward(handler), block_token = block_responses()](auto result) mutable { + auto message_id = message.map([](auto const& message) { return message.id; }); + + return [weak_self = make_weak_ptr(), message_id, handler = forward(handler)](auto result) mutable { if (result.is_error()) { dbgln_if(DEVTOOLS_DEBUG, "Error performing async action: {}", result.error()); return; @@ -101,22 +91,30 @@ protected: if (auto self = weak_self.strong_ref()) { JsonObject response; handler(*self, result.release_value(), response); - self->send_message(move(response), move(block_token)); + + if (message_id.has_value()) + self->send_response({ .id = *message_id }, move(response)); + else + self->send_message(move(response)); } }; } - auto default_async_handler() + auto default_async_handler(Message const& message) { - return async_handler([](auto&, auto, auto) { }); + return async_handler(message, [](auto&, auto, auto) { }); } private: DevToolsServer& m_devtools; String m_name; - Vector m_blocked_responses; - bool m_block_responses { false }; + struct PendingResponse { + Optional id; + Optional response; + }; + Vector m_pending_responses; + u64 m_next_message_id { 0 }; }; } diff --git a/Libraries/LibDevTools/Actors/CSSPropertiesActor.cpp b/Libraries/LibDevTools/Actors/CSSPropertiesActor.cpp index 6287ec97050..9a1c6545842 100644 --- a/Libraries/LibDevTools/Actors/CSSPropertiesActor.cpp +++ b/Libraries/LibDevTools/Actors/CSSPropertiesActor.cpp @@ -47,7 +47,7 @@ void CSSPropertiesActor::handle_message(Message const& message) } response.set("properties"sv, move(properties)); - send_message(move(response)); + send_response(message, move(response)); return; } diff --git a/Libraries/LibDevTools/Actors/ConsoleActor.cpp b/Libraries/LibDevTools/Actors/ConsoleActor.cpp index 80ebbf81ca3..2ad2a94bf8b 100644 --- a/Libraries/LibDevTools/Actors/ConsoleActor.cpp +++ b/Libraries/LibDevTools/Actors/ConsoleActor.cpp @@ -46,7 +46,7 @@ void ConsoleActor::handle_message(Message const& message) if (message.type == "autocomplete"sv) { response.set("matches"sv, JsonArray {}); response.set("matchProp"sv, String {}); - send_message(move(response)); + send_response(message, move(response)); return; } @@ -58,7 +58,7 @@ void ConsoleActor::handle_message(Message const& message) auto result_id = MUST(String::formatted("{}-{}", name(), m_execution_id++)); response.set("resultID"sv, result_id); - send_message(move(response)); + send_response(message, move(response)); // FIXME: We do not support eager evaluation of scripts. Just bail for now. if (message.data.get_bool("eager"sv).value_or(false)) { @@ -67,7 +67,7 @@ void ConsoleActor::handle_message(Message const& message) if (auto tab = m_tab.strong_ref()) { devtools().delegate().evaluate_javascript(tab->description(), *text, - async_handler([result_id, input = *text](auto&, auto result, auto& response) { + async_handler({}, [result_id, input = *text](auto&, auto result, auto& response) { received_console_result(response, move(result_id), move(input), move(result)); })); } diff --git a/Libraries/LibDevTools/Actors/DeviceActor.cpp b/Libraries/LibDevTools/Actors/DeviceActor.cpp index aece6a8a391..45eb10a5e75 100644 --- a/Libraries/LibDevTools/Actors/DeviceActor.cpp +++ b/Libraries/LibDevTools/Actors/DeviceActor.cpp @@ -49,7 +49,7 @@ void DeviceActor::handle_message(Message const& message) JsonObject response; response.set("value"sv, move(value)); - send_message(move(response)); + send_response(message, move(response)); return; } diff --git a/Libraries/LibDevTools/Actors/FrameActor.cpp b/Libraries/LibDevTools/Actors/FrameActor.cpp index c8c2502b87d..36c49d708cd 100644 --- a/Libraries/LibDevTools/Actors/FrameActor.cpp +++ b/Libraries/LibDevTools/Actors/FrameActor.cpp @@ -62,12 +62,12 @@ void FrameActor::handle_message(Message const& message) tab->reset_selected_node(); } - send_message(move(response)); + send_response(message, move(response)); return; } if (message.type == "listFrames"sv) { - send_message(move(response)); + send_response(message, move(response)); return; } diff --git a/Libraries/LibDevTools/Actors/HighlighterActor.cpp b/Libraries/LibDevTools/Actors/HighlighterActor.cpp index 169a85be2ab..0da90e0ad22 100644 --- a/Libraries/LibDevTools/Actors/HighlighterActor.cpp +++ b/Libraries/LibDevTools/Actors/HighlighterActor.cpp @@ -43,7 +43,7 @@ void HighlighterActor::handle_message(Message const& message) response.set("value"sv, true); } - send_message(move(response)); + send_response(message, move(response)); return; } @@ -51,7 +51,7 @@ void HighlighterActor::handle_message(Message const& message) if (auto tab = InspectorActor::tab_for(m_inspector)) devtools().delegate().clear_highlighted_dom_node(tab->description()); - send_message(move(response)); + send_response(message, move(response)); return; } diff --git a/Libraries/LibDevTools/Actors/InspectorActor.cpp b/Libraries/LibDevTools/Actors/InspectorActor.cpp index 2f6d4ea5b5b..34328a9320d 100644 --- a/Libraries/LibDevTools/Actors/InspectorActor.cpp +++ b/Libraries/LibDevTools/Actors/InspectorActor.cpp @@ -38,7 +38,7 @@ void InspectorActor::handle_message(Message const& message) m_page_style = devtools().register_actor(*this); response.set("pageStyle"sv, m_page_style->serialize_style()); - send_message(move(response)); + send_response(message, move(response)); return; } @@ -52,14 +52,14 @@ void InspectorActor::handle_message(Message const& message) }); response.set("highlighter"sv, highlighter->serialize_highlighter()); - send_message(move(response)); + send_response(message, move(response)); return; } if (message.type == "getWalker"sv) { if (auto tab = m_tab.strong_ref()) { devtools().delegate().inspect_tab(tab->description(), - async_handler([](auto& self, auto dom_tree, auto& response) { + async_handler(message, [](auto& self, auto dom_tree, auto& response) { if (!WalkerActor::is_suitable_for_dom_inspection(dom_tree)) { dbgln_if(DEVTOOLS_DEBUG, "Did not receive a suitable DOM tree: {}", dom_tree); return; @@ -74,7 +74,7 @@ void InspectorActor::handle_message(Message const& message) if (message.type == "supportsHighlighters"sv) { response.set("value"sv, true); - send_message(move(response)); + send_response(message, move(response)); return; } diff --git a/Libraries/LibDevTools/Actors/LayoutInspectorActor.cpp b/Libraries/LibDevTools/Actors/LayoutInspectorActor.cpp index 9473d173f55..d0f8dab1796 100644 --- a/Libraries/LibDevTools/Actors/LayoutInspectorActor.cpp +++ b/Libraries/LibDevTools/Actors/LayoutInspectorActor.cpp @@ -28,13 +28,13 @@ void LayoutInspectorActor::handle_message(Message const& message) if (message.type == "getCurrentFlexbox"sv) { response.set("flexbox"sv, JsonValue {}); - send_message(move(response)); + send_response(message, move(response)); return; } if (message.type == "getGrids"sv) { response.set("grids"sv, JsonArray {}); - send_message(move(response)); + send_response(message, move(response)); return; } diff --git a/Libraries/LibDevTools/Actors/NodeActor.cpp b/Libraries/LibDevTools/Actors/NodeActor.cpp index 27fe2aef829..25668b8bcec 100644 --- a/Libraries/LibDevTools/Actors/NodeActor.cpp +++ b/Libraries/LibDevTools/Actors/NodeActor.cpp @@ -100,12 +100,12 @@ void NodeActor::handle_message(Message const& message) if (message.type == "getUniqueSelector"sv) { auto dom_node = WalkerActor::dom_node_for(m_walker, name()); if (!dom_node.has_value()) { - send_unknown_actor_error(name()); + send_unknown_actor_error(message, name()); return; } response.set("value"sv, dom_node->node.get_string("name"sv)->to_ascii_lowercase()); - send_message(move(response)); + send_response(message, move(response)); return; } @@ -120,14 +120,14 @@ void NodeActor::handle_message(Message const& message) auto dom_node = WalkerActor::dom_node_for(m_walker, name()); if (!dom_node.has_value()) { - send_unknown_actor_error(name()); + send_unknown_actor_error(message, name()); return; } if (attribute_to_replace.has_value()) - devtools().delegate().replace_dom_node_attribute(dom_node->tab->description(), dom_node->identifier.id, *attribute_to_replace, move(replacement_attributes), default_async_handler()); + devtools().delegate().replace_dom_node_attribute(dom_node->tab->description(), dom_node->identifier.id, *attribute_to_replace, move(replacement_attributes), default_async_handler(message)); else - devtools().delegate().add_dom_node_attributes(dom_node->tab->description(), dom_node->identifier.id, move(replacement_attributes), default_async_handler()); + devtools().delegate().add_dom_node_attributes(dom_node->tab->description(), dom_node->identifier.id, move(replacement_attributes), default_async_handler(message)); return; } @@ -139,11 +139,11 @@ void NodeActor::handle_message(Message const& message) auto dom_node = WalkerActor::dom_node_for(m_walker, name()); if (!dom_node.has_value()) { - send_unknown_actor_error(name()); + send_unknown_actor_error(message, name()); return; } - devtools().delegate().set_dom_node_text(dom_node->tab->description(), dom_node->identifier.id, *value, default_async_handler()); + devtools().delegate().set_dom_node_text(dom_node->tab->description(), dom_node->identifier.id, *value, default_async_handler(message)); return; } diff --git a/Libraries/LibDevTools/Actors/PageStyleActor.cpp b/Libraries/LibDevTools/Actors/PageStyleActor.cpp index e239cd1ca4d..796d1330a9e 100644 --- a/Libraries/LibDevTools/Actors/PageStyleActor.cpp +++ b/Libraries/LibDevTools/Actors/PageStyleActor.cpp @@ -93,7 +93,7 @@ void PageStyleActor::handle_message(Message const& message) // FIXME: This provides information to the "styles" pane in the inspector tab, which allows toggling and editing // styles live. We do not yet support figuring out the list of styles that apply to a specific node. response.set("entries"sv, JsonArray {}); - send_message(move(response)); + send_response(message, move(response)); return; } @@ -102,7 +102,7 @@ void PageStyleActor::handle_message(Message const& message) if (!node.has_value()) return; - inspect_dom_node(*node, [](auto& response, auto const& properties) { + inspect_dom_node(message, *node, [](auto& response, auto const& properties) { received_computed_style(response, properties.computed_style); }); @@ -114,7 +114,7 @@ void PageStyleActor::handle_message(Message const& message) if (!node.has_value()) return; - inspect_dom_node(*node, [](auto& response, auto const& properties) { + inspect_dom_node(message, *node, [](auto& response, auto const& properties) { received_layout(response, properties.computed_style, properties.node_box_sizing); }); @@ -123,7 +123,7 @@ void PageStyleActor::handle_message(Message const& message) if (message.type == "isPositionEditable") { response.set("value"sv, false); - send_message(move(response)); + send_response(message, move(response)); return; } @@ -145,16 +145,16 @@ JsonValue PageStyleActor::serialize_style() const } template -void PageStyleActor::inspect_dom_node(StringView node_actor, Callback&& callback) +void PageStyleActor::inspect_dom_node(Message const& message, StringView node_actor, Callback&& callback) { auto dom_node = WalkerActor::dom_node_for(InspectorActor::walker_for(m_inspector), node_actor); if (!dom_node.has_value()) { - send_unknown_actor_error(node_actor); + send_unknown_actor_error(message, node_actor); return; } devtools().delegate().inspect_dom_node(dom_node->tab->description(), dom_node->identifier.id, dom_node->identifier.pseudo_element, - async_handler([callback = forward(callback)](auto&, auto properties, auto& response) { + async_handler(message, [callback = forward(callback)](auto&, auto properties, auto& response) { callback(response, properties); })); } diff --git a/Libraries/LibDevTools/Actors/PageStyleActor.h b/Libraries/LibDevTools/Actors/PageStyleActor.h index 7d05f80d759..f930435c673 100644 --- a/Libraries/LibDevTools/Actors/PageStyleActor.h +++ b/Libraries/LibDevTools/Actors/PageStyleActor.h @@ -32,7 +32,7 @@ private: virtual void handle_message(Message const&) override; template - void inspect_dom_node(StringView node_actor, Callback&&); + void inspect_dom_node(Message const&, StringView node_actor, Callback&&); WeakPtr m_inspector; }; diff --git a/Libraries/LibDevTools/Actors/PreferenceActor.cpp b/Libraries/LibDevTools/Actors/PreferenceActor.cpp index e0164c3b1db..608fcacd17f 100644 --- a/Libraries/LibDevTools/Actors/PreferenceActor.cpp +++ b/Libraries/LibDevTools/Actors/PreferenceActor.cpp @@ -31,7 +31,7 @@ void PreferenceActor::handle_message(Message const& message) if (message.type == "getBoolPref"sv) { JsonObject response; response.set("value"sv, false); - send_message(move(response)); + send_response(message, move(response)); return; } diff --git a/Libraries/LibDevTools/Actors/RootActor.cpp b/Libraries/LibDevTools/Actors/RootActor.cpp index 0a2abb89585..e08c0d44896 100644 --- a/Libraries/LibDevTools/Actors/RootActor.cpp +++ b/Libraries/LibDevTools/Actors/RootActor.cpp @@ -46,7 +46,7 @@ void RootActor::handle_message(Message const& message) JsonObject response; if (message.type == "connect") { - send_message(move(response)); + send_response(message, move(response)); return; } @@ -60,7 +60,7 @@ void RootActor::handle_message(Message const& message) response.set("preferenceActor"sv, actor.key); } - send_message(move(response)); + send_response(message, move(response)); return; } @@ -80,7 +80,7 @@ void RootActor::handle_message(Message const& message) break; } - send_message(move(response)); + send_response(message, move(response)); return; } @@ -100,13 +100,13 @@ void RootActor::handle_message(Message const& message) break; } - send_message(move(response)); + send_response(message, move(response)); return; } if (message.type == "listAddons"sv) { response.set("addons"sv, JsonArray {}); - send_message(move(response)); + send_response(message, move(response)); return; } @@ -119,13 +119,13 @@ void RootActor::handle_message(Message const& message) } response.set("processes"sv, move(processes)); - send_message(move(response)); + send_response(message, move(response)); return; } if (message.type == "listServiceWorkerRegistrations"sv) { response.set("registrations"sv, JsonArray {}); - send_message(move(response)); + send_response(message, move(response)); return; } @@ -140,13 +140,13 @@ void RootActor::handle_message(Message const& message) } response.set("tabs"sv, move(tabs)); - send_message(move(response)); + send_response(message, move(response)); return; } if (message.type == "listWorkers"sv) { response.set("workers"sv, JsonArray {}); - send_message(move(response)); + send_response(message, move(response)); return; } diff --git a/Libraries/LibDevTools/Actors/TabActor.cpp b/Libraries/LibDevTools/Actors/TabActor.cpp index 429c67d2928..74c038d55ff 100644 --- a/Libraries/LibDevTools/Actors/TabActor.cpp +++ b/Libraries/LibDevTools/Actors/TabActor.cpp @@ -36,7 +36,7 @@ void TabActor::handle_message(Message const& message) // FIXME: Firefox DevTools wants a favicon URL here, but supplying a URL seems to prevent this tab from being // listed on the about:debugging page. Both Servo and Firefox itself supply `null` here. response.set("favicon"sv, JsonValue {}); - send_message(move(response)); + send_response(message, move(response)); return; } @@ -46,7 +46,7 @@ void TabActor::handle_message(Message const& message) response.set("actor"sv, m_watcher->name()); response.set("traits"sv, m_watcher->serialize_description()); - send_message(move(response)); + send_response(message, move(response)); return; } diff --git a/Libraries/LibDevTools/Actors/TargetConfigurationActor.cpp b/Libraries/LibDevTools/Actors/TargetConfigurationActor.cpp index fc20703c24f..39da24bf3ae 100644 --- a/Libraries/LibDevTools/Actors/TargetConfigurationActor.cpp +++ b/Libraries/LibDevTools/Actors/TargetConfigurationActor.cpp @@ -31,7 +31,7 @@ void TargetConfigurationActor::handle_message(Message const& message) if (!configuration.has_value()) return; - send_message(move(response)); + send_response(message, move(response)); return; } diff --git a/Libraries/LibDevTools/Actors/ThreadConfigurationActor.cpp b/Libraries/LibDevTools/Actors/ThreadConfigurationActor.cpp index 3a2bd7f7e1c..45b3bad2d3b 100644 --- a/Libraries/LibDevTools/Actors/ThreadConfigurationActor.cpp +++ b/Libraries/LibDevTools/Actors/ThreadConfigurationActor.cpp @@ -31,7 +31,7 @@ void ThreadConfigurationActor::handle_message(Message const& message) if (!configuration.has_value()) return; - send_message(move(response)); + send_response(message, move(response)); return; } diff --git a/Libraries/LibDevTools/Actors/WalkerActor.cpp b/Libraries/LibDevTools/Actors/WalkerActor.cpp index 12618e27c63..98e4153c1f9 100644 --- a/Libraries/LibDevTools/Actors/WalkerActor.cpp +++ b/Libraries/LibDevTools/Actors/WalkerActor.cpp @@ -54,7 +54,7 @@ void WalkerActor::handle_message(Message const& message) auto ancestor_node = WalkerActor::dom_node_for(*this, *node); if (!ancestor_node.has_value()) { - send_unknown_actor_error(*node); + send_unknown_actor_error(message, *node); return; } @@ -69,7 +69,7 @@ void WalkerActor::handle_message(Message const& message) response.set("hasFirst"sv, !nodes.is_empty()); response.set("hasLast"sv, !nodes.is_empty()); response.set("nodes"sv, move(nodes)); - send_message(move(response)); + send_response(message, move(response)); return; } @@ -80,11 +80,11 @@ void WalkerActor::handle_message(Message const& message) auto dom_node = WalkerActor::dom_node_for(*this, *node); if (!dom_node.has_value()) { - send_unknown_actor_error(*node); + send_unknown_actor_error(message, *node); return; } - devtools().delegate().clone_dom_node(dom_node->tab->description(), dom_node->identifier.id, default_async_handler()); + devtools().delegate().clone_dom_node(dom_node->tab->description(), dom_node->identifier.id, default_async_handler(message)); return; } @@ -99,11 +99,11 @@ void WalkerActor::handle_message(Message const& message) auto dom_node = WalkerActor::dom_node_for(*this, *node); if (!dom_node.has_value()) { - send_unknown_actor_error(*node); + send_unknown_actor_error(message, *node); return; } - devtools().delegate().set_dom_node_tag(dom_node->tab->description(), dom_node->identifier.id, *tag_name, default_async_handler()); + devtools().delegate().set_dom_node_tag(dom_node->tab->description(), dom_node->identifier.id, *tag_name, default_async_handler(message)); return; } @@ -115,13 +115,13 @@ void WalkerActor::handle_message(Message const& message) actor.set("actor"sv, m_layout_inspector->name()); response.set("actor"sv, move(actor)); - send_message(move(response)); + send_response(message, move(response)); return; } if (message.type == "getMutations"sv) { response.set("mutations"sv, serialize_mutations()); - send_message(move(response)); + send_response(message, move(response)); m_has_new_mutations_since_last_mutations_request = false; return; @@ -129,7 +129,7 @@ void WalkerActor::handle_message(Message const& message) if (message.type == "getOffsetParent"sv) { response.set("node"sv, JsonValue {}); - send_message(move(response)); + send_response(message, move(response)); return; } @@ -140,12 +140,12 @@ void WalkerActor::handle_message(Message const& message) auto dom_node = WalkerActor::dom_node_for(*this, *node); if (!dom_node.has_value()) { - send_unknown_actor_error(*node); + send_unknown_actor_error(message, *node); return; } devtools().delegate().get_dom_node_inner_html(dom_node->tab->description(), dom_node->identifier.id, - async_handler([](auto&, auto html, auto& response) { + async_handler(message, [](auto&, auto html, auto& response) { response.set("value"sv, move(html)); })); @@ -162,12 +162,12 @@ void WalkerActor::handle_message(Message const& message) auto dom_node = WalkerActor::dom_node_for(*this, *node); if (!dom_node.has_value()) { - send_unknown_actor_error(*node); + send_unknown_actor_error(message, *node); return; } devtools().delegate().create_child_element(dom_node->tab->description(), dom_node->identifier.id, - async_handler([](auto& self, auto node_id, auto& response) { + async_handler(message, [](auto& self, auto node_id, auto& response) { JsonArray nodes; if (auto actor = self.m_dom_node_id_to_actor_map.get(node_id); actor.has_value()) { @@ -193,13 +193,13 @@ void WalkerActor::handle_message(Message const& message) auto dom_node = WalkerActor::dom_node_for(*this, *node); if (!dom_node.has_value()) { - send_unknown_actor_error(*node); + send_unknown_actor_error(message, *node); return; } auto parent_dom_node = WalkerActor::dom_node_for(*this, *parent); if (!parent_dom_node.has_value()) { - send_unknown_actor_error(*parent); + send_unknown_actor_error(message, *parent); return; } @@ -207,14 +207,14 @@ void WalkerActor::handle_message(Message const& message) if (auto sibling = message.data.get_string("sibling"sv); sibling.has_value()) { auto sibling_dom_node = WalkerActor::dom_node_for(*this, *sibling); if (!sibling_dom_node.has_value()) { - send_unknown_actor_error(*sibling); + send_unknown_actor_error(message, *sibling); return; } sibling_node_id = sibling_dom_node->identifier.id; } - devtools().delegate().insert_dom_node_before(dom_node->tab->description(), dom_node->identifier.id, parent_dom_node->identifier.id, sibling_node_id, default_async_handler()); + devtools().delegate().insert_dom_node_before(dom_node->tab->description(), dom_node->identifier.id, parent_dom_node->identifier.id, sibling_node_id, default_async_handler(message)); return; } @@ -224,7 +224,7 @@ void WalkerActor::handle_message(Message const& message) return; response.set("attached"sv, m_actor_to_dom_node_map.contains(*node)); - send_message(move(response)); + send_response(message, move(response)); return; } @@ -235,12 +235,12 @@ void WalkerActor::handle_message(Message const& message) auto dom_node = WalkerActor::dom_node_for(*this, *node); if (!dom_node.has_value()) { - send_unknown_actor_error(*node); + send_unknown_actor_error(message, *node); return; } devtools().delegate().get_dom_node_outer_html(dom_node->tab->description(), dom_node->identifier.id, - async_handler([](auto&, auto html, auto& response) { + async_handler(message, [](auto&, auto html, auto& response) { response.set("value"sv, move(html)); })); @@ -254,7 +254,7 @@ void WalkerActor::handle_message(Message const& message) auto dom_node = WalkerActor::dom_node_for(*this, *node); if (!dom_node.has_value()) { - send_unknown_actor_error(*node); + send_unknown_actor_error(message, *node); return; } @@ -263,7 +263,7 @@ void WalkerActor::handle_message(Message const& message) previous_sibling = serialize_node(*previous_sibling_node); response.set("node"sv, move(previous_sibling)); - send_message(move(response)); + send_response(message, move(response)); return; } @@ -278,7 +278,7 @@ void WalkerActor::handle_message(Message const& message) auto ancestor_node = WalkerActor::dom_node_for(*this, *node); if (!ancestor_node.has_value()) { - send_unknown_actor_error(*node); + send_unknown_actor_error(message, *node); return; } @@ -294,7 +294,7 @@ void WalkerActor::handle_message(Message const& message) } } - send_message(move(response)); + send_response(message, move(response)); return; } @@ -305,7 +305,7 @@ void WalkerActor::handle_message(Message const& message) auto dom_node = WalkerActor::dom_node_for(*this, *node); if (!dom_node.has_value()) { - send_unknown_actor_error(*node); + send_unknown_actor_error(message, *node); return; } @@ -318,7 +318,7 @@ void WalkerActor::handle_message(Message const& message) return; devtools().delegate().remove_dom_node(dom_node->tab->description(), dom_node->identifier.id, - async_handler([next_sibling = move(next_sibling)](auto&, auto, auto& response) mutable { + async_handler(message, [next_sibling = move(next_sibling)](auto&, auto, auto& response) mutable { response.set("nextSibling"sv, move(next_sibling)); })); @@ -326,7 +326,7 @@ void WalkerActor::handle_message(Message const& message) } if (message.type == "retainNode"sv) { - send_message(move(response)); + send_response(message, move(response)); return; } @@ -341,18 +341,18 @@ void WalkerActor::handle_message(Message const& message) auto dom_node = WalkerActor::dom_node_for(*this, *node); if (!dom_node.has_value()) { - send_unknown_actor_error(*node); + send_unknown_actor_error(message, *node); return; } - devtools().delegate().set_dom_node_outer_html(dom_node->tab->description(), dom_node->identifier.id, value.release_value(), default_async_handler()); + devtools().delegate().set_dom_node_outer_html(dom_node->tab->description(), dom_node->identifier.id, value.release_value(), default_async_handler(message)); return; } if (message.type == "watchRootNode"sv) { response.set("type"sv, "root-available"sv); response.set("node"sv, serialize_root()); - send_message(move(response)); + send_response(message, move(response)); send_message({}); return; diff --git a/Libraries/LibDevTools/Actors/WatcherActor.cpp b/Libraries/LibDevTools/Actors/WatcherActor.cpp index 272bb99d51c..371787c98fb 100644 --- a/Libraries/LibDevTools/Actors/WatcherActor.cpp +++ b/Libraries/LibDevTools/Actors/WatcherActor.cpp @@ -43,7 +43,7 @@ void WatcherActor::handle_message(Message const& message) return; response.set("browsingContextID"sv, *browsing_context_id); - send_message(move(response)); + send_response(message, move(response)); return; } @@ -52,7 +52,7 @@ void WatcherActor::handle_message(Message const& message) m_target_configuration = devtools().register_actor(); response.set("configuration"sv, m_target_configuration->serialize_configuration()); - send_message(move(response)); + send_response(message, move(response)); return; } @@ -61,7 +61,7 @@ void WatcherActor::handle_message(Message const& message) m_thread_configuration = devtools().register_actor(); response.set("configuration"sv, m_thread_configuration->serialize_configuration()); - send_message(move(response)); + send_response(message, move(response)); return; } @@ -79,7 +79,7 @@ void WatcherActor::handle_message(Message const& message) } } - send_message(move(response)); + send_response(message, move(response)); return; } @@ -99,7 +99,7 @@ void WatcherActor::handle_message(Message const& message) response.set("type"sv, "target-available-form"sv); response.set("target"sv, target.serialize_target()); - send_message(move(response)); + send_response(message, move(response)); target.send_frame_update_message(); diff --git a/Libraries/LibDevTools/DevToolsServer.cpp b/Libraries/LibDevTools/DevToolsServer.cpp index adbbf605ac6..5b4b25fe5e3 100644 --- a/Libraries/LibDevTools/DevToolsServer.cpp +++ b/Libraries/LibDevTools/DevToolsServer.cpp @@ -87,19 +87,19 @@ void DevToolsServer::on_message_received(JsonObject message) { auto to = message.get_string("to"sv); if (!to.has_value()) { - m_root_actor->send_missing_parameter_error("to"sv); + m_root_actor->send_missing_parameter_error({}, "to"sv); return; } auto actor = m_actor_registry.find(*to); if (actor == m_actor_registry.end()) { - m_root_actor->send_unknown_actor_error(*to); + m_root_actor->send_unknown_actor_error({}, *to); return; } auto type = message.get_string("type"sv); if (!type.has_value()) { - actor->value->send_missing_parameter_error("type"sv); + actor->value->send_missing_parameter_error({}, "type"sv); return; }