Skip to content

Commit

Permalink
refactor(jupyter): use runtimelib for Jupyter structures and director…
Browse files Browse the repository at this point in the history
…y paths (#23826)

This brings in [`runtimelib`](https://github.com/runtimed/runtimed) to
use:

## Fully typed structs for Jupyter Messages

```rust
let msg = connection.read().await?;

self
  .send_iopub(
    runtimelib::Status::busy().as_child_of(msg),
  )
  .await?;
```

## Jupyter paths

Jupyter paths are implemented in Rust, allowing the Deno kernel to be
installed completely via Deno without a requirement on Python or
Jupyter. Deno users will be able to install and use the kernel with just
VS Code or other editors that support Jupyter.

```rust
pub fn status() -> Result<(), AnyError> {
  let user_data_dir = user_data_dir()?;

  let kernel_spec_dir_path = user_data_dir.join("kernels").join("deno");
  let kernel_spec_path = kernel_spec_dir_path.join("kernel.json");

  if kernel_spec_path.exists() {
    log::info!("✅ Deno kernel already installed");
    Ok(())
  } else {
    log::warn!("ℹ️ Deno kernel is not yet installed, run `deno jupyter --install` to set it up");
    Ok(())
  }
}
```

Closes #21619
  • Loading branch information
rgbkrk authored and bartlomieju committed May 21, 2024
1 parent 4e8c1fd commit 93d7b37
Show file tree
Hide file tree
Showing 11 changed files with 460 additions and 599 deletions.
120 changes: 107 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ rand = { workspace = true, features = ["small_rng"] }
regex.workspace = true
reqwest.workspace = true
ring.workspace = true
runtimelib = "=0.9.0"
rustyline.workspace = true
rustyline-derive = "=0.7.0"
serde.workspace = true
Expand Down
54 changes: 34 additions & 20 deletions cli/ops/jupyter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ use std::cell::RefCell;
use std::rc::Rc;
use std::sync::Arc;

use crate::tools::jupyter::jupyter_msg::Connection;
use crate::tools::jupyter::jupyter_msg::JupyterMessage;
use crate::tools::jupyter::server::StdioMsg;
use runtimelib::JupyterMessage;
use runtimelib::JupyterMessageContent;
use runtimelib::KernelIoPubConnection;
use runtimelib::StreamContent;

use deno_core::error::AnyError;
use deno_core::op2;
use deno_core::serde_json;
Expand All @@ -19,7 +21,7 @@ deno_core::extension!(deno_jupyter,
op_jupyter_broadcast,
],
options = {
sender: mpsc::UnboundedSender<StdioMsg>,
sender: mpsc::UnboundedSender<StreamContent>,
},
middleware = |op| match op.name {
"op_print" => op_print(),
Expand All @@ -38,28 +40,40 @@ pub async fn op_jupyter_broadcast(
#[serde] metadata: serde_json::Value,
#[serde] buffers: Vec<deno_core::JsBuffer>,
) -> Result<(), AnyError> {
let (iopub_socket, last_execution_request) = {
let (iopub_connection, last_execution_request) = {
let s = state.borrow();

(
s.borrow::<Arc<Mutex<Connection<zeromq::PubSocket>>>>()
.clone(),
s.borrow::<Arc<Mutex<KernelIoPubConnection>>>().clone(),
s.borrow::<Rc<RefCell<Option<JupyterMessage>>>>().clone(),
)
};

let maybe_last_request = last_execution_request.borrow().clone();
if let Some(last_request) = maybe_last_request {
(*iopub_socket.lock().await)
.send(
&last_request
.new_message(&message_type)
.with_content(content)
.with_metadata(metadata)
.with_buffers(
buffers.into_iter().map(|b| b.to_vec().into()).collect(),
),
)
let content = JupyterMessageContent::from_type_and_content(
&message_type,
content.clone(),
)
.map_err(|err| {
log::error!(
"Error deserializing content from jupyter.broadcast, message_type: {}:\n\n{}\n\n{}",
&message_type,
content,
err
);
err
})?;

let mut jupyter_message = JupyterMessage::new(content, Some(&last_request));

jupyter_message.metadata = metadata;
jupyter_message.buffers =
buffers.into_iter().map(|b| b.to_vec().into()).collect();
jupyter_message.set_parent(last_request);

(iopub_connection.lock().await)
.send(jupyter_message)
.await?;
}

Expand All @@ -72,16 +86,16 @@ pub fn op_print(
#[string] msg: &str,
is_err: bool,
) -> Result<(), AnyError> {
let sender = state.borrow_mut::<mpsc::UnboundedSender<StdioMsg>>();
let sender = state.borrow_mut::<mpsc::UnboundedSender<StreamContent>>();

if is_err {
if let Err(err) = sender.send(StdioMsg::Stderr(msg.into())) {
if let Err(err) = sender.send(StreamContent::stderr(msg.into())) {
log::error!("Failed to send stderr message: {}", err);
}
return Ok(());
}

if let Err(err) = sender.send(StdioMsg::Stdout(msg.into())) {
if let Err(err) = sender.send(StreamContent::stdout(msg.into())) {
log::error!("Failed to send stdout message: {}", err);
}
Ok(())
Expand Down
Loading

0 comments on commit 93d7b37

Please sign in to comment.