Skip to content

Commit

Permalink
feat(Documents): Add JSON-RPC methods for obtaining document `kernels…
Browse files Browse the repository at this point in the history
…` and `symbols`
  • Loading branch information
nokome committed Jan 25, 2022
1 parent a861810 commit 9c706d0
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 17 deletions.
53 changes: 38 additions & 15 deletions rust/kernels/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,12 +272,9 @@ impl KernelMap {
)
}

/// Get a list of kernels in the kernel space
#[cfg(feature = "cli")]
pub async fn display(&self) -> cli_utils::Result {
use cli_utils::result;

let mut list = Vec::new();
/// Get a list of kernels (including their details and status)
pub async fn list(&self) -> KernelInfos {
let mut list = KernelInfos::new();
for (id, kernel) in self.iter() {
let id = id.to_string();
let spec = kernel.spec().await;
Expand All @@ -290,20 +287,32 @@ impl KernelMap {
};
let interruptable = kernel.is_interruptable().await;
let forkable = kernel.is_forkable().await;
list.push(KernelInfo {
id,
status,
spec,
interruptable,
forkable,
})
list.insert(
id.to_string(),
KernelInfo {
id,
status,
spec,
interruptable,
forkable,
},
);
}
list
}

/// Display a list of kernels in the kernel space
#[cfg(feature = "cli")]
pub async fn display(&self) -> cli_utils::Result {
use cli_utils::result;

let list = self.list().await;

let cols = "|--|------|----|----|---------|-------------|--------|";
let head = "|Id|Status|Type|Name|Languages|Interruptable|Forkable|";
let body = list
.iter()
.map(|info| {
.map(|(_, info)| {
format!(
"|{}|{}|{}|{}|{}|{}|{}|",
info.id,
Expand Down Expand Up @@ -370,7 +379,7 @@ impl SymbolInfo {
}
}

type KernelSymbols = HashMap<String, SymbolInfo>;
pub type KernelSymbols = HashMap<String, SymbolInfo>;

/// Disassociates a kernel with a symbol. If a symbol is mirrored in other kernels
/// then the last kernel that is was mirrored to will become it's home.
Expand Down Expand Up @@ -801,6 +810,8 @@ impl Drop for KernelSpace {
}
}

pub type KernelInfos = HashMap<KernelId, KernelInfo>;

impl KernelSpace {
/// Create a new kernel space and start its monitoring task
pub fn new() -> Self {
Expand Down Expand Up @@ -836,6 +847,18 @@ impl KernelSpace {
}
}

/// Get the list of kernels in the kernel space
pub async fn kernels(&self) -> KernelInfos {
let kernels = &*self.kernels.lock().await;
kernels.list().await
}

/// Get the list of symbols in the kernel space
pub async fn symbols(&self) -> KernelSymbols {
let symbols = &*self.symbols.lock().await;
symbols.clone()
}

/// Start a kernel
pub async fn start(&self, selector: &KernelSelector) -> Result<KernelId> {
let kernels = &mut *self.kernels.lock().await;
Expand Down
16 changes: 14 additions & 2 deletions rust/stencila/src/documents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use eyre::{bail, Result};
use formats::FormatSpec;
use graph::{Graph, Plan, PlanOptions, PlanOrdering, PlanScope};
use graph_triples::{resources, Relations};
use kernels::KernelSpace;
use kernels::{KernelInfos, KernelSpace, KernelSymbols};
use maplit::hashset;
use node_address::AddressMap;
use node_execute::{
Expand Down Expand Up @@ -1240,7 +1240,7 @@ impl Document {
Ok(request_id)
}

/// Restart a kernel (or all kernels) in a document's kernel space
/// Restart a kernel (or all kernels) in the document's kernel space
///
/// Cancels any execution plan that is running, destroy the document's
/// existing kernel, and create's a new one
Expand All @@ -1256,6 +1256,18 @@ impl Document {
Ok(())
}

/// Get the list of kernels in the document's kernel space
pub async fn kernels(&self) -> KernelInfos {
let kernel_space = &*self.kernels.read().await;
kernel_space.kernels().await
}

/// Get the list of symbols in the document's kernel space
pub async fn symbols(&self) -> KernelSymbols {
let kernel_space = &*self.kernels.read().await;
kernel_space.symbols().await
}

/// Update the `root` (and associated properties) of the document and publish updated encodings
///
/// Publishes `encoded:` events for each of the formats subscribed to.
Expand Down
16 changes: 16 additions & 0 deletions rust/stencila/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ impl Request {
"documents.execute" => documents_execute(&self.params).await,
"documents.cancel" => documents_cancel(&self.params).await,
"documents.restart" => documents_restart(&self.params).await,
"documents.kernels" => documents_kernels(&self.params).await,
"documents.symbols" => documents_symbols(&self.params).await,
"documents.subscribe" => documents_subscribe(&self.params, client).await,
"documents.unsubscribe" => documents_unsubscribe(&self.params, client).await,
_ => {
Expand Down Expand Up @@ -384,6 +386,20 @@ async fn documents_restart(params: &Params) -> Result<(serde_json::Value, Subscr
Ok((serde_json::Value::Null, Subscription::None))
}

async fn documents_kernels(params: &Params) -> Result<(serde_json::Value, Subscription)> {
let id = required_string(params, "documentId")?;

let kernels = DOCUMENTS.get(&id).await?.lock().await.kernels().await;
Ok((json!(kernels), Subscription::None))
}

async fn documents_symbols(params: &Params) -> Result<(serde_json::Value, Subscription)> {
let id = required_string(params, "documentId")?;

let symbols = DOCUMENTS.get(&id).await?.lock().await.symbols().await;
Ok((json!(symbols), Subscription::None))
}

// Helper functions for getting JSON-RPC parameters and raising appropriate errors
// if they are not present or of wrong type

Expand Down
24 changes: 24 additions & 0 deletions web/src/documents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,30 @@ export async function restart(
}) as Promise<void>
}

/**
* Get a list of kernels in a document's kernel space
*/
export async function kernels(
client: Client,
documentId: DocumentId
): Promise<void> {
return client.call('documents.kernels', {
documentId,
}) as Promise<void>
}

/**
* Get a list of symbols in a document's kernel space
*/
export async function symbols(
client: Client,
documentId: DocumentId
): Promise<void> {
return client.call('documents.symbols', {
documentId,
}) as Promise<void>
}

/**
* Listen to browser window events that require passing on to server
*/
Expand Down

0 comments on commit 9c706d0

Please sign in to comment.