core: seams for parallel work: services.rs (boot), graph.rs (documents for /proc), activation.rs

This commit is contained in:
2026-10-23 00:34:34 +01:00
parent 8542b9fcb8
commit ae1cb4cc99
6 changed files with 82 additions and 17 deletions
+15
View File
@@ -0,0 +1,15 @@
//! Activation and revert of plugin versions (PROTOCOL.md section 10.3).
use crate::{Host, RpcResult, error};
use serde_json::Value;
impl Host {
/// `core.activate` and `core.revert`.
pub(crate) async fn activation(
&self,
_caller: &str,
_method: &str,
_params: Value,
) -> RpcResult {
Err(error(-32601, "method not found"))
}
}
+1
View File
@@ -49,6 +49,7 @@ impl Host {
Ok(Value::Null) Ok(Value::Null)
} }
"log" => Ok(self.0.journal.query(p).await), "log" => Ok(self.0.journal.query(p).await),
"activate" | "revert" => self.activation(caller, method, p).await,
"exit" => { "exit" => {
self.0.exit.send_replace(true); self.0.exit.send_replace(true);
Ok(json!({})) Ok(json!({}))
+31
View File
@@ -0,0 +1,31 @@
//! The interface graph (PROTOCOL.md section 10.4): the `rpc.discover`
//! documents of all plugins, their imports, and the result of each check.
//!
//! The `/proc` layer reads the files of `/proc/core/` through these
//! functions. They must be cheap and must not block: they return cached data.
use crate::Host;
use serde_json::Value;
// The /proc layer (T6) uses these functions. Remove this when it does.
#[allow(dead_code)]
impl Host {
/// The content of `/proc/core/graph.json`.
pub(crate) fn graph_json(&self) -> Vec<u8> {
b"{}\n".to_vec()
}
/// The content of `/proc/core/graph.dot`.
pub(crate) fn graph_dot(&self) -> Vec<u8> {
b"digraph plugins {}\n".to_vec()
}
/// The plugins that have an `rpc.discover` document, for `/proc/core/plugins/`.
pub(crate) fn discovered_plugins(&self) -> Vec<String> {
Vec::new()
}
/// The `rpc.discover` document of the current `plugin.wasm` of `plugin`.
pub(crate) fn discover_document(&self, _plugin: &str) -> Option<Value> {
None
}
}
+1 -17
View File
@@ -65,23 +65,7 @@ impl Host {
exit: watch::channel(false).0, exit: watch::channel(false).0,
components: components::Components::default(), components: components::Components::default(),
})); }));
let boot: Vec<Value> = serde_json::from_slice( host.boot().await?;
&tokio::fs::read(host.0.world.root.join("config/boot.json")).await?,
)?;
for service in boot {
let result = host
.route(
"core".into(),
Some(json!(Uuid::now_v7().to_string())),
service["method"].as_str().unwrap_or("").into(),
service["params"].clone(),
true,
)
.await;
if let Err(e) = result {
host.0.journal.write("core", "core", "core", &e.to_string());
}
}
Ok(host) Ok(host)
} }
/// Register a native plugin for subsequent calls. /// Register a native plugin for subsequent calls.
+3
View File
@@ -1,9 +1,11 @@
//! A host for worlds of JSON-RPC plugins. //! A host for worlds of JSON-RPC plugins.
mod activation;
pub mod cargo; pub mod cargo;
mod components; mod components;
pub mod console; pub mod console;
mod core; mod core;
mod execution; mod execution;
mod graph;
mod host; mod host;
mod journal; mod journal;
mod locks; mod locks;
@@ -11,6 +13,7 @@ mod native;
mod process; mod process;
mod routing; mod routing;
pub mod runtime; pub mod runtime;
mod services;
pub mod world; pub mod world;
pub use host::Host; pub use host::Host;
pub use native::{NativeContext, NativeFuture, NativePlugin}; pub use native::{NativeContext, NativeFuture, NativePlugin};
+31
View File
@@ -0,0 +1,31 @@
//! Services: the calls in `/config/boot.json` (PROTOCOL.md section 8). The
//! core starts them in order at boot.
use crate::Host;
use serde_json::{Value, json};
use uuid::Uuid;
impl Host {
/// Start each service of `/config/boot.json` as a detached call with the
/// parent `core`, in order. A failure goes to the journal, and boot
/// continues.
pub(crate) async fn boot(&self) -> anyhow::Result<()> {
let boot: Vec<Value> = serde_json::from_slice(
&tokio::fs::read(self.0.world.root.join("config/boot.json")).await?,
)?;
for service in boot {
let result = self
.route(
"core".into(),
Some(json!(Uuid::now_v7().to_string())),
service["method"].as_str().unwrap_or("").into(),
service["params"].clone(),
true,
)
.await;
if let Err(e) = result {
self.0.journal.write("core", "core", "core", &e.to_string());
}
}
Ok(())
}
}