Skip to content
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

refactor(cli/inspector): make server optional #7656

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 9 additions & 0 deletions cli/global_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::file_fetcher::SourceFileFetcher;
use crate::flags;
use crate::http_cache;
use crate::import_map::ImportMap;
use crate::inspector::InspectorServer;
use crate::lockfile::Lockfile;
use crate::media_type::MediaType;
use crate::module_graph::ModuleGraphFile;
Expand Down Expand Up @@ -42,6 +43,7 @@ pub struct GlobalState {
pub lockfile: Option<Mutex<Lockfile>>,
pub compiler_starts: AtomicUsize,
pub maybe_import_map: Option<ImportMap>,
pub maybe_inspector_server: Option<Arc<InspectorServer>>,
}

impl GlobalState {
Expand Down Expand Up @@ -85,6 +87,12 @@ impl GlobalState {
}
};

let maybe_inspect_host = flags.inspect.or(flags.inspect_brk);
let maybe_inspector_server = match maybe_inspect_host {
Some(host) => Some(Arc::new(InspectorServer::new(host))),
None => None,
};

let global_state = GlobalState {
dir,
permissions: Permissions::from_flags(&flags),
Expand All @@ -93,6 +101,7 @@ impl GlobalState {
ts_compiler,
lockfile,
maybe_import_map,
maybe_inspector_server,
compiler_starts: AtomicUsize::new(0),
};
Ok(Arc::new(global_state))
Expand Down
71 changes: 29 additions & 42 deletions cli/inspector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,55 +35,35 @@ use std::ptr;
use std::ptr::NonNull;
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::Once;
use std::thread;
use uuid::Uuid;
use warp::filters::ws;
use warp::Filter;

struct InspectorServer {
host: SocketAddr,
pub struct InspectorServer {
pub host: SocketAddr,
register_inspector_tx: UnboundedSender<InspectorInfo>,
_thread_handle: thread::JoinHandle<()>,
}

impl InspectorServer {
/// Registers an Inspector instance with the inspector server. If the server
/// is not running yet, it'll be started first.
pub fn register_inspector(info: InspectorInfo) {
let self_ = Self::global(&info.host);
self_.register_inspector_tx.unbounded_send(info).unwrap();
}

/// Returns the global InspectorServer instance. If the server is not yet
/// running, this function starts it.
fn global(host: &SocketAddr) -> &'static InspectorServer {
let instance = unsafe {
static mut INSTANCE: Option<InspectorServer> = None;
static INIT: Once = Once::new();
INIT.call_once(|| {
INSTANCE.replace(Self::new(*host));
});
INSTANCE.as_ref().unwrap()
};
// We only start a single server, so all inspectors must bind to the same
// host:port combination.
assert_eq!(host, &instance.host);
instance
}

fn new(host: SocketAddr) -> Self {
pub fn new(host: SocketAddr) -> Self {
let (register_inspector_tx, register_inspector_rx) =
mpsc::unbounded::<InspectorInfo>();
let thread_handle = thread::spawn(move || {
crate::tokio_util::run_basic(server(host, register_inspector_rx))
});

Self {
host,
register_inspector_tx,
_thread_handle: thread_handle,
}
}

fn register_inspector(&self, info: InspectorInfo) {
self.register_inspector_tx.unbounded_send(info).unwrap();
}
}

/// Inspector information that is sent from the isolate thread to the server
Expand Down Expand Up @@ -323,7 +303,8 @@ pub struct DenoInspector {
flags: RefCell<InspectorFlags>,
waker: Arc<InspectorWaker>,
_canary_tx: oneshot::Sender<Never>,
pub debugger_url: String,
pub server: Option<Arc<InspectorServer>>,
pub debugger_url: Option<String>,
}

impl Deref for DenoInspector {
Expand Down Expand Up @@ -393,7 +374,7 @@ impl DenoInspector {

pub fn new(
isolate: &mut deno_core::JsRuntime,
host: SocketAddr,
server: Option<Arc<InspectorServer>>,
) -> Box<Self> {
let context = isolate.global_context();
let scope = &mut v8::HandleScope::new(&mut **isolate);
Expand All @@ -402,14 +383,6 @@ impl DenoInspector {
mpsc::unbounded::<WebSocketProxy>();
let (canary_tx, canary_rx) = oneshot::channel::<Never>();

let info = InspectorInfo {
host,
uuid: Uuid::new_v4(),
thread_name: thread::current().name().map(|n| n.to_owned()),
new_websocket_tx,
canary_rx,
};

// Create DenoInspector instance.
let mut self_ = new_box_with(|self_ptr| {
let v8_inspector_client =
Expand All @@ -421,14 +394,31 @@ impl DenoInspector {
let flags = InspectorFlags::new();
let waker = InspectorWaker::new(scope.thread_safe_handle());

let debugger_url = if let Some(server) = server.clone() {
let info = InspectorInfo {
host: server.host,
uuid: Uuid::new_v4(),
thread_name: thread::current().name().map(|n| n.to_owned()),
new_websocket_tx,
canary_rx,
};

let debugger_url = info.get_websocket_debugger_url();
server.register_inspector(info);
Some(debugger_url)
} else {
None
};

Self {
v8_inspector_client,
v8_inspector,
sessions,
flags,
waker,
_canary_tx: canary_tx,
debugger_url: info.get_websocket_debugger_url(),
server,
debugger_url,
}
});

Expand All @@ -437,9 +427,6 @@ impl DenoInspector {
let context_name = v8::inspector::StringView::from(&b"global context"[..]);
self_.context_created(context, Self::CONTEXT_GROUP_ID, context_name);

// Register this inspector with the server thread.
InspectorServer::register_inspector(info);

// Poll the session handler so we will get notified whenever there is
// new_incoming debugger activity.
let _ = self_.poll_sessions(None).unwrap();
Expand Down
18 changes: 11 additions & 7 deletions cli/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,13 +155,17 @@ impl Worker {
op_state.put(main_module);
op_state.put(global_state.clone());
}
let inspector = {
global_state
.flags
.inspect
.or(global_state.flags.inspect_brk)
.filter(|_| !is_internal)
.map(|inspector_host| DenoInspector::new(&mut isolate, inspector_host))

let inspector = if is_internal {
None
} else if let Some(inspector_server) = &global_state.maybe_inspector_server
{
Some(DenoInspector::new(
&mut isolate,
Some(inspector_server.clone()),
))
} else {
None
};

let should_break_on_first_statement = inspector.is_some()
Expand Down