DevTools: Improve resource_available to handle multiple connections (#36933)

This patch improves the `resource_available` trait to handle multiple
connections. In this patch we also remove the redundant
`resource_available` from worker actor

Testing: Existing tests in DevTools already tests for this. We do not
need to add new test
Fixes: part of #36027

Signed-off-by: atbrakhi <atbrakhi@igalia.com>
Co-authored-by: Delan Azabani <dazabani@igalia.com>
This commit is contained in:
atbrakhi 2025-05-09 14:06:33 +02:00 committed by GitHub
parent e5347eceac
commit 2aaf9695df
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 51 additions and 62 deletions

View file

@ -149,10 +149,6 @@ impl ResourceAvailable for BrowsingContextActor {
fn actor_name(&self) -> String { fn actor_name(&self) -> String {
self.name.clone() self.name.clone()
} }
fn get_streams(&self) -> &RefCell<HashMap<StreamId, TcpStream>> {
&self.streams
}
} }
impl Actor for BrowsingContextActor { impl Actor for BrowsingContextActor {

View file

@ -252,6 +252,7 @@ impl ConsoleActor {
page_error: PageError, page_error: PageError,
id: UniqueId, id: UniqueId,
registry: &ActorRegistry, registry: &ActorRegistry,
stream: &mut TcpStream,
) { ) {
self.cached_events self.cached_events
.borrow_mut() .borrow_mut()
@ -262,7 +263,11 @@ impl ConsoleActor {
if let Root::BrowsingContext(bc) = &self.root { if let Root::BrowsingContext(bc) = &self.root {
registry registry
.find::<BrowsingContextActor>(bc) .find::<BrowsingContextActor>(bc)
.resource_available(PageErrorWrapper { page_error }, "error-message".into()) .resource_available(
PageErrorWrapper { page_error },
"error-message".into(),
stream,
)
}; };
} }
} }
@ -272,6 +277,7 @@ impl ConsoleActor {
console_message: ConsoleMessage, console_message: ConsoleMessage,
id: UniqueId, id: UniqueId,
registry: &ActorRegistry, registry: &ActorRegistry,
stream: &mut TcpStream,
) { ) {
let log_message: ConsoleLog = console_message.into(); let log_message: ConsoleLog = console_message.into();
self.cached_events self.cached_events
@ -283,7 +289,7 @@ impl ConsoleActor {
if let Root::BrowsingContext(bc) = &self.root { if let Root::BrowsingContext(bc) = &self.root {
registry registry
.find::<BrowsingContextActor>(bc) .find::<BrowsingContextActor>(bc)
.resource_available(log_message, "console-message".into()) .resource_available(log_message, "console-message".into(), stream)
}; };
} }
} }

View file

@ -31,7 +31,7 @@ use crate::actors::watcher::thread_configuration::{
ThreadConfigurationActor, ThreadConfigurationActorMsg, ThreadConfigurationActor, ThreadConfigurationActorMsg,
}; };
use crate::protocol::JsonPacketStream; use crate::protocol::JsonPacketStream;
use crate::resource::{ResourceAvailable, ResourceAvailableReply}; use crate::resource::ResourceAvailable;
use crate::{EmptyReplyMsg, StreamId, WorkerActor}; use crate::{EmptyReplyMsg, StreamId, WorkerActor};
pub mod network_parent; pub mod network_parent;
@ -291,28 +291,28 @@ impl Actor for WatcherActor {
title: Some(target.title.borrow().clone()), title: Some(target.title.borrow().clone()),
url: Some(target.url.borrow().clone()), url: Some(target.url.borrow().clone()),
}; };
target.resource_available(event, "document-event".into()); target.resource_available(event, "document-event".into(), stream);
} }
}, },
"source" => { "source" => {
let thread_actor = registry.find::<ThreadActor>(&target.thread); let thread_actor = registry.find::<ThreadActor>(&target.thread);
let sources = thread_actor.source_manager.sources(); let sources = thread_actor.source_manager.sources();
target.resources_available(sources.iter().collect(), "source".into()); target.resources_available(
sources.iter().collect(),
"source".into(),
stream,
);
for worker_name in &root.workers { for worker_name in &root.workers {
let worker = registry.find::<WorkerActor>(worker_name); let worker = registry.find::<WorkerActor>(worker_name);
let thread = registry.find::<ThreadActor>(&worker.thread); let thread = registry.find::<ThreadActor>(&worker.thread);
let worker_sources = thread.source_manager.sources(); let worker_sources = thread.source_manager.sources();
let msg = ResourceAvailableReply { worker.resources_available(
from: worker.name(), worker_sources.iter().collect(),
type_: "resources-available-array".into(), "source".into(),
array: vec![( stream,
"source".to_string(), );
worker_sources.iter().cloned().collect(),
)],
};
let _ = stream.write_json_packet(&msg);
} }
}, },
"console-message" | "error-message" => {}, "console-message" | "error-message" => {},

View file

@ -17,7 +17,7 @@ use servo_url::ServoUrl;
use crate::StreamId; use crate::StreamId;
use crate::actor::{Actor, ActorMessageStatus, ActorRegistry}; use crate::actor::{Actor, ActorMessageStatus, ActorRegistry};
use crate::protocol::JsonPacketStream; use crate::protocol::JsonPacketStream;
use crate::resource::{ResourceAvailable, ResourceAvailableReply}; use crate::resource::ResourceAvailable;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
#[allow(dead_code)] #[allow(dead_code)]
@ -60,10 +60,6 @@ impl ResourceAvailable for WorkerActor {
fn actor_name(&self) -> String { fn actor_name(&self) -> String {
self.name.clone() self.name.clone()
} }
fn get_streams(&self) -> &RefCell<HashMap<StreamId, TcpStream>> {
&self.streams
}
} }
impl Actor for WorkerActor { impl Actor for WorkerActor {
@ -133,28 +129,6 @@ impl Actor for WorkerActor {
} }
} }
impl WorkerActor {
pub(crate) fn resource_available<T: Serialize>(&self, resource: T, resource_type: String) {
self.resources_available(vec![resource], resource_type);
}
pub(crate) fn resources_available<T: Serialize>(
&self,
resources: Vec<T>,
resource_type: String,
) {
let msg = ResourceAvailableReply::<T> {
from: self.name(),
type_: "resources-available-array".into(),
array: vec![(resource_type, resources)],
};
for stream in self.streams.borrow_mut().values_mut() {
let _ = stream.write_json_packet(&msg);
}
}
}
#[derive(Serialize)] #[derive(Serialize)]
struct DetachedReply { struct DetachedReply {
from: String, from: String,

View file

@ -414,7 +414,7 @@ impl DevtoolsInstance {
} }
fn handle_page_error( fn handle_page_error(
&self, &mut self,
pipeline_id: PipelineId, pipeline_id: PipelineId,
worker_id: Option<WorkerId>, worker_id: Option<WorkerId>,
page_error: PageError, page_error: PageError,
@ -426,11 +426,13 @@ impl DevtoolsInstance {
let actors = self.actors.lock().unwrap(); let actors = self.actors.lock().unwrap();
let console_actor = actors.find::<ConsoleActor>(&console_actor_name); let console_actor = actors.find::<ConsoleActor>(&console_actor_name);
let id = worker_id.map_or(UniqueId::Pipeline(pipeline_id), UniqueId::Worker); let id = worker_id.map_or(UniqueId::Pipeline(pipeline_id), UniqueId::Worker);
console_actor.handle_page_error(page_error, id, &actors); for stream in self.connections.values_mut() {
console_actor.handle_page_error(page_error.clone(), id.clone(), &actors, stream);
}
} }
fn handle_console_message( fn handle_console_message(
&self, &mut self,
pipeline_id: PipelineId, pipeline_id: PipelineId,
worker_id: Option<WorkerId>, worker_id: Option<WorkerId>,
console_message: ConsoleMessage, console_message: ConsoleMessage,
@ -442,7 +444,9 @@ impl DevtoolsInstance {
let actors = self.actors.lock().unwrap(); let actors = self.actors.lock().unwrap();
let console_actor = actors.find::<ConsoleActor>(&console_actor_name); let console_actor = actors.find::<ConsoleActor>(&console_actor_name);
let id = worker_id.map_or(UniqueId::Pipeline(pipeline_id), UniqueId::Worker); let id = worker_id.map_or(UniqueId::Pipeline(pipeline_id), UniqueId::Worker);
console_actor.handle_console_api(console_message, id, &actors); for stream in self.connections.values_mut() {
console_actor.handle_console_api(console_message.clone(), id.clone(), &actors, stream);
}
} }
fn find_console_actor( fn find_console_actor(
@ -529,7 +533,10 @@ impl DevtoolsInstance {
}; };
let worker_actor = actors.find::<WorkerActor>(worker_actor_name); let worker_actor = actors.find::<WorkerActor>(worker_actor_name);
worker_actor.resource_available(source, "source".into());
for stream in self.connections.values_mut() {
worker_actor.resource_available(&source, "source".into(), stream);
}
} else { } else {
let Some(browsing_context_id) = self.pipelines.get(&pipeline_id) else { let Some(browsing_context_id) = self.pipelines.get(&pipeline_id) else {
return; return;
@ -556,7 +563,10 @@ impl DevtoolsInstance {
// Notify browsing context about the new source // Notify browsing context about the new source
let browsing_context = actors.find::<BrowsingContextActor>(actor_name); let browsing_context = actors.find::<BrowsingContextActor>(actor_name);
browsing_context.resource_available(source, "source".into());
for stream in self.connections.values_mut() {
browsing_context.resource_available(&source, "source".into(), stream);
}
} }
} }
} }

View file

@ -2,13 +2,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::cell::RefCell;
use std::collections::HashMap;
use std::net::TcpStream; use std::net::TcpStream;
use serde::Serialize; use serde::Serialize;
use crate::StreamId;
use crate::protocol::JsonPacketStream; use crate::protocol::JsonPacketStream;
#[derive(Serialize)] #[derive(Serialize)]
@ -22,21 +19,27 @@ pub(crate) struct ResourceAvailableReply<T: Serialize> {
pub(crate) trait ResourceAvailable { pub(crate) trait ResourceAvailable {
fn actor_name(&self) -> String; fn actor_name(&self) -> String;
fn get_streams(&self) -> &RefCell<HashMap<StreamId, TcpStream>>; fn resource_available<T: Serialize>(
&self,
fn resource_available<T: Serialize>(&self, resource: T, resource_type: String) { resource: T,
self.resources_available(vec![resource], resource_type); resource_type: String,
stream: &mut TcpStream,
) {
self.resources_available(vec![resource], resource_type, stream);
} }
fn resources_available<T: Serialize>(&self, resources: Vec<T>, resource_type: String) { fn resources_available<T: Serialize>(
&self,
resources: Vec<T>,
resource_type: String,
stream: &mut TcpStream,
) {
let msg = ResourceAvailableReply::<T> { let msg = ResourceAvailableReply::<T> {
from: self.actor_name(), from: self.actor_name(),
type_: "resources-available-array".into(), type_: "resources-available-array".into(),
array: vec![(resource_type, resources)], array: vec![(resource_type, resources)],
}; };
for stream in self.get_streams().borrow_mut().values_mut() { let _ = stream.write_json_packet(&msg);
let _ = stream.write_json_packet(&msg);
}
} }
} }