Skip to content
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
3 changes: 3 additions & 0 deletions crates/core/src/db/datastore/system_tables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -816,12 +816,15 @@ pub struct ModuleKind(u8);
impl ModuleKind {
/// The [`ModuleKind`] of WASM-based modules.
pub const WASM: ModuleKind = ModuleKind(0);
/// The [`ModuleKind`] of JS modules.
pub const JS: ModuleKind = ModuleKind(1);
}

impl From<crate::messages::control_db::HostType> for ModuleKind {
fn from(host_type: crate::messages::control_db::HostType) -> Self {
match host_type {
crate::messages::control_db::HostType::Wasm => Self::WASM,
crate::messages::control_db::HostType::Js => Self::JS,
}
}
}
Expand Down
26 changes: 18 additions & 8 deletions crates/core/src/host/host_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use crate::db::db_metrics::DB_METRICS;
use crate::db::relational_db::{self, DiskSizeFn, RelationalDB, Txdata};
use crate::db::{self, spawn_tx_metrics_recorder};
use crate::energy::{EnergyMonitor, EnergyQuanta, NullEnergyMonitor};
use crate::host::module_host::ModuleRuntime as _;
use crate::host::v8::V8Runtime;
use crate::messages::control_db::{Database, HostType};
use crate::module_host_context::ModuleCreationContext;
use crate::replica_context::ReplicaContext;
Expand Down Expand Up @@ -106,12 +108,14 @@ pub struct HostController {

struct HostRuntimes {
wasmtime: WasmtimeRuntime,
v8: V8Runtime,
}

impl HostRuntimes {
fn new(data_dir: Option<&ServerDataDir>) -> Arc<Self> {
let wasmtime = WasmtimeRuntime::new(data_dir);
Arc::new(Self { wasmtime })
let v8 = V8Runtime::default();
Arc::new(Self { wasmtime, v8 })
}
}

Expand Down Expand Up @@ -671,19 +675,25 @@ async fn make_module_host(
// threads, but those aren't for computation. Also, wasmtime uses rayon
// to run compilation in parallel, so it'll need to run stuff in rayon anyway.
asyncify(move || {
let mcc = ModuleCreationContext {
replica_ctx,
scheduler,
program: &program,
energy_monitor,
};

let start = Instant::now();
let module_host = match host_type {
HostType::Wasm => {
let mcc = ModuleCreationContext {
replica_ctx,
scheduler,
program: &program,
energy_monitor,
};
let start = Instant::now();
let actor = runtimes.wasmtime.make_actor(mcc)?;
trace!("wasmtime::make_actor blocked for {:?}", start.elapsed());
ModuleHost::new(actor, unregister, core)
}
HostType::Js => {
let actor = runtimes.v8.make_actor(mcc)?;
trace!("v8::make_actor blocked for {:?}", start.elapsed());
ModuleHost::new(actor, unregister, core)
}
};
Ok((program, module_host))
})
Expand Down
2 changes: 2 additions & 0 deletions crates/core/src/host/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ mod host_controller;
pub mod module_host;
pub mod scheduler;
pub mod wasmtime;

// Visible for integration testing.
pub mod instance_env;
pub mod v8; // only pub for testing
mod wasm_common;

pub use disk_storage::DiskStorage;
Expand Down
7 changes: 7 additions & 0 deletions crates/core/src/host/module_host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::execution_context::{ExecutionContext, ReducerContext, Workload, Workl
use crate::hash::Hash;
use crate::identity::Identity;
use crate::messages::control_db::Database;
use crate::module_host_context::ModuleCreationContext;
use crate::replica_context::ReplicaContext;
use crate::sql::ast::SchemaViewer;
use crate::sql::parser::RowLevelExpr;
Expand Down Expand Up @@ -306,6 +307,12 @@ impl ReducersMap {
}
}

/// A runtime that can create modules.
pub trait ModuleRuntime {
/// Creates a module based on the context `mcc`.
fn make_actor(&self, mcc: ModuleCreationContext<'_>) -> anyhow::Result<impl Module>;
}

pub trait DynModule: Send + Sync + 'static {
fn replica_ctx(&self) -> &Arc<ReplicaContext>;
fn scheduler(&self) -> &Scheduler;
Expand Down
96 changes: 96 additions & 0 deletions crates/core/src/host/v8/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
use crate::{
db::datastore::locking_tx_datastore::MutTxId,
host::{
module_host::{DynModule, Module, ModuleInfo, ModuleInstance, ModuleRuntime},
Scheduler,
},
module_host_context::ModuleCreationContext,
replica_context::ReplicaContext,
};
use anyhow::anyhow;
use std::sync::{Arc, LazyLock};

use super::module_host::CallReducerParams;

/// The V8 runtime, for modules written in e.g., JS or TypeScript.
#[derive(Default)]
pub struct V8Runtime {
_priv: (),
}

impl ModuleRuntime for V8Runtime {
fn make_actor(&self, mcc: ModuleCreationContext<'_>) -> anyhow::Result<impl Module> {
V8_RUNTIME_GLOBAL.make_actor(mcc)
}
}

static V8_RUNTIME_GLOBAL: LazyLock<V8RuntimeInner> = LazyLock::new(V8RuntimeInner::new);

/// The actual V8 runtime, with initialization of V8.
struct V8RuntimeInner {
_priv: (),
}

impl V8RuntimeInner {
#[allow(clippy::new_without_default)]
const fn new() -> Self {
// TODO: actually setup V8.

Self { _priv: () }
}

fn make_actor(&self, _: ModuleCreationContext<'_>) -> anyhow::Result<impl Module> {
Err::<JsModule, _>(anyhow!("v8_todo"))
}
}

#[derive(Clone)]
struct JsModule;

impl DynModule for JsModule {
fn replica_ctx(&self) -> &Arc<ReplicaContext> {
todo!()
}

fn scheduler(&self) -> &Scheduler {
todo!()
}
}

impl Module for JsModule {
type Instance = JsInstance;

type InitialInstances<'a> = std::iter::Empty<JsInstance>;

fn initial_instances(&mut self) -> Self::InitialInstances<'_> {
std::iter::empty()
}

fn info(&self) -> Arc<ModuleInfo> {
todo!()
}

fn create_instance(&self) -> Self::Instance {
todo!()
}
}

struct JsInstance;

impl ModuleInstance for JsInstance {
fn trapped(&self) -> bool {
todo!()
}

fn update_database(
&mut self,
_program: crate::db::datastore::traits::Program,
_old_module_info: Arc<ModuleInfo>,
) -> anyhow::Result<super::UpdateDatabaseResult> {
todo!()
}

fn call_reducer(&mut self, _tx: Option<MutTxId>, _params: CallReducerParams) -> super::ReducerCallResult {
todo!()
}
}
2 changes: 0 additions & 2 deletions crates/core/src/host/wasm_common/module_host_actor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,6 @@ pub enum DescribeError {
Decode(#[from] DecodeError),
#[error(transparent)]
RuntimeError(anyhow::Error),
#[error("unimplemented RawModuleDef version")]
UnimplementedRawModuleDefVersion,
}

impl<T: WasmModule> WasmModuleHostActor<T> {
Expand Down
8 changes: 4 additions & 4 deletions crates/core/src/host/wasmtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use wasmtime::{Engine, Linker, Module, StoreContext, StoreContextMut};

use crate::energy::{EnergyQuanta, ReducerBudget};
use crate::error::NodesError;
use crate::host::module_host::ModuleRuntime;
use crate::module_host_context::ModuleCreationContext;

mod wasm_instance_env;
Expand Down Expand Up @@ -80,11 +81,10 @@ impl WasmtimeRuntime {
config.cache_config_load(tmpfile.path())?;
Ok(())
}
}

pub fn make_actor(
&self,
mcc: ModuleCreationContext,
) -> Result<impl super::module_host::Module, ModuleCreationError> {
impl ModuleRuntime for WasmtimeRuntime {
fn make_actor(&self, mcc: ModuleCreationContext) -> anyhow::Result<impl super::module_host::Module> {
let module = Module::new(&self.engine, &mcc.program.bytes).map_err(ModuleCreationError::WasmCompileError)?;

let func_imports = module
Expand Down
1 change: 1 addition & 0 deletions crates/core/src/messages/control_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,5 @@ pub struct NodeStatus {
#[repr(i32)]
pub enum HostType {
Wasm = 0,
Js,
}
2 changes: 2 additions & 0 deletions crates/standalone/src/subcommands/extract_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ struct Args {
#[derive(clap::ValueEnum, Copy, Clone)]
enum HostType {
Wasm,
Js,
}

impl From<HostType> for control_db::HostType {
fn from(x: HostType) -> Self {
match x {
HostType::Wasm => control_db::HostType::Wasm,
HostType::Js => control_db::HostType::Js,
}
}
}
Expand Down
Loading