1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-21 23:04:45 -05:00

fix(jupyter): keep running event loop when waiting for messages (#26049)

Closes https://github.com/denoland/deno/issues/24421
This commit is contained in:
Bartek Iwańczuk 2024-10-09 09:04:15 +01:00 committed by GitHub
parent a62c7e036a
commit 0dfd333649
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 97 additions and 45 deletions

View file

@ -357,56 +357,74 @@ pub struct JupyterReplSession {
impl JupyterReplSession {
pub async fn start(&mut self) {
let mut poll_worker = true;
loop {
let Some(msg) = self.rx.recv().await else {
break;
};
let resp = match msg {
JupyterReplRequest::LspCompletions {
line_text,
position,
} => JupyterReplResponse::LspCompletions(
self.lsp_completions(&line_text, position).await,
),
JupyterReplRequest::JsGetProperties { object_id } => {
JupyterReplResponse::JsGetProperties(
self.get_properties(object_id).await,
)
}
JupyterReplRequest::JsEvaluate { expr } => {
JupyterReplResponse::JsEvaluate(self.evaluate(expr).await)
}
JupyterReplRequest::JsGlobalLexicalScopeNames => {
JupyterReplResponse::JsGlobalLexicalScopeNames(
self.global_lexical_scope_names().await,
)
}
JupyterReplRequest::JsEvaluateLineWithObjectWrapping { line } => {
JupyterReplResponse::JsEvaluateLineWithObjectWrapping(
self.evaluate_line_with_object_wrapping(&line).await,
)
}
JupyterReplRequest::JsCallFunctionOnArgs {
function_declaration,
args,
} => JupyterReplResponse::JsCallFunctionOnArgs(
self
.call_function_on_args(function_declaration, &args)
.await,
),
JupyterReplRequest::JsCallFunctionOn { arg0, arg1 } => {
JupyterReplResponse::JsCallFunctionOn(
self.call_function_on(arg0, arg1).await,
)
}
};
tokio::select! {
biased;
let Ok(()) = self.tx.send(resp) else {
break;
};
maybe_message = self.rx.recv() => {
let Some(msg) = maybe_message else {
break;
};
if self.handle_message(msg).await.is_err() {
break;
}
poll_worker = true;
},
_ = self.repl_session.run_event_loop(), if poll_worker => {
poll_worker = false;
}
}
}
}
async fn handle_message(
&mut self,
msg: JupyterReplRequest,
) -> Result<(), AnyError> {
let resp = match msg {
JupyterReplRequest::LspCompletions {
line_text,
position,
} => JupyterReplResponse::LspCompletions(
self.lsp_completions(&line_text, position).await,
),
JupyterReplRequest::JsGetProperties { object_id } => {
JupyterReplResponse::JsGetProperties(
self.get_properties(object_id).await,
)
}
JupyterReplRequest::JsEvaluate { expr } => {
JupyterReplResponse::JsEvaluate(self.evaluate(expr).await)
}
JupyterReplRequest::JsGlobalLexicalScopeNames => {
JupyterReplResponse::JsGlobalLexicalScopeNames(
self.global_lexical_scope_names().await,
)
}
JupyterReplRequest::JsEvaluateLineWithObjectWrapping { line } => {
JupyterReplResponse::JsEvaluateLineWithObjectWrapping(
self.evaluate_line_with_object_wrapping(&line).await,
)
}
JupyterReplRequest::JsCallFunctionOnArgs {
function_declaration,
args,
} => JupyterReplResponse::JsCallFunctionOnArgs(
self
.call_function_on_args(function_declaration, &args)
.await,
),
JupyterReplRequest::JsCallFunctionOn { arg0, arg1 } => {
JupyterReplResponse::JsCallFunctionOn(
self.call_function_on(arg0, arg1).await,
)
}
};
self.tx.send(resp).map_err(|e| e.into())
}
pub async fn lsp_completions(
&mut self,
line_text: &str,

View file

@ -628,3 +628,37 @@ async fn jupyter_store_history_false() -> Result<()> {
Ok(())
}
#[tokio::test]
async fn jupyter_http_server() -> Result<()> {
let (_ctx, client, _process) = setup().await;
client
.send(
Shell,
"execute_request",
json!({
"silent": false,
"store_history": false,
"code": r#"Deno.serve({ port: 10234 }, (req) => Response.json({ hello: "world" }))"#,
}),
)
.await?;
let reply = client.recv(Shell).await?;
assert_eq!(reply.header.msg_type, "execute_reply");
assert_json_subset(
reply.content,
json!({
"status": "ok",
"execution_count": 0,
}),
);
for _ in 0..3 {
let resp = reqwest::get("http://localhost:10234").await.unwrap();
let text: serde_json::Value = resp.json().await.unwrap();
assert_eq!(text, json!({ "hello": "world" }));
}
Ok(())
}