Skip to content

Commit a8a7023

Browse files
more commentary
1 parent 5fe27d7 commit a8a7023

2 files changed

Lines changed: 27 additions & 22 deletions

File tree

crates/core/src/host/module_host.rs

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ impl CreateInstanceTimeMetric {
815815
}
816816

817817
impl<M: GenericModule> ModuleInstanceManager<M> {
818-
fn new(module: M, init_inst: M::Instance, database_identity: Identity) -> Self {
818+
fn new(module: M, init_inst: Option<M::Instance>, database_identity: Identity) -> Self {
819819
let host_type = module.host_type();
820820
let module_instances_metric = ModuleInstancesMetric {
821821
metric: WORKER_METRICS
@@ -834,9 +834,8 @@ impl<M: GenericModule> ModuleInstanceManager<M> {
834834
database_identity,
835835
};
836836

837-
// Add the first instance.
838837
let mut instances = VecDeque::new();
839-
instances.push_front(init_inst);
838+
instances.extend(init_inst);
840839

841840
Self {
842841
instances: Mutex::new(instances),
@@ -846,23 +845,6 @@ impl<M: GenericModule> ModuleInstanceManager<M> {
846845
}
847846
}
848847

849-
fn new_empty(module: M, database_identity: Identity) -> Self {
850-
let host_type = module.host_type();
851-
let create_instance_time_metric = CreateInstanceTimeMetric {
852-
metric: WORKER_METRICS
853-
.module_create_instance_time_seconds
854-
.with_label_values(&database_identity, &host_type),
855-
host_type,
856-
database_identity,
857-
};
858-
859-
Self {
860-
instances: Mutex::new(VecDeque::new()),
861-
module,
862-
create_instance_time_metric,
863-
}
864-
}
865-
866848
async fn with_instance<R>(&self, f: impl AsyncFnOnce(M::Instance) -> (R, M::Instance)) -> R {
867849
let inst = self.get_instance().await;
868850
let (res, inst) = f(inst).await;
@@ -1087,7 +1069,7 @@ impl ModuleHost {
10871069
init_inst,
10881070
} => {
10891071
info = module.info();
1090-
let instance_manager = ModuleInstanceManager::new(module, init_inst, database_identity);
1072+
let instance_manager = ModuleInstanceManager::new(module, Some(init_inst), database_identity);
10911073
Arc::new(ModuleHostInner::Wasm(WasmtimeModuleHost {
10921074
executor,
10931075
instance_manager,
@@ -1096,7 +1078,7 @@ impl ModuleHost {
10961078
ModuleWithInstance::Js { module, init_inst } => {
10971079
info = module.info();
10981080
let instance_lane = super::v8::JsInstanceLane::new(module.clone(), init_inst);
1099-
let procedure_instances = ModuleInstanceManager::new_empty(module.clone(), database_identity);
1081+
let procedure_instances = ModuleInstanceManager::new(module.clone(), None, database_identity);
11001082
Arc::new(ModuleHostInner::Js(V8ModuleHost {
11011083
module,
11021084
instance_lane,

crates/core/src/host/v8/mod.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,11 @@ impl JsInstanceEnv {
349349
/// and friends.
350350
#[derive(Clone)]
351351
pub struct JsInstance {
352+
/// Stable identifier for the underlying worker generation.
353+
///
354+
/// All clones of the same handle share the same `id`. The instance lane uses
355+
/// it to tell whether the currently active worker has already been replaced
356+
/// after a trap or disconnect.
352357
id: u64,
353358
request_tx: flume::Sender<JsWorkerRequest>,
354359
trapped: Arc<AtomicBool>,
@@ -519,44 +524,57 @@ type JsReplyTx<T> = oneshot::Sender<JsWorkerReply<T>>;
519524
/// executes the request there, and then has to send both the typed result and
520525
/// the worker's trapped-bit back to the async caller.
521526
enum JsWorkerRequest {
527+
/// See [`JsInstance::run_on_thread`].
528+
///
529+
/// This variant does not expect a [`JsWorkerReply`].
522530
RunFunction(Box<dyn FnOnce() -> LocalBoxFuture<'static, ()> + Send>),
531+
/// See [`JsInstance::update_database`].
523532
UpdateDatabase {
524533
reply_tx: JsReplyTx<anyhow::Result<UpdateDatabaseResult>>,
525534
program: Program,
526535
old_module_info: Arc<ModuleInfo>,
527536
policy: MigrationPolicy,
528537
},
538+
/// See [`JsInstance::call_reducer`].
529539
CallReducer {
530540
reply_tx: JsReplyTx<ReducerCallResult>,
531541
params: CallReducerParams,
532542
},
543+
/// See [`JsInstance::call_view`].
533544
CallView {
534545
reply_tx: JsReplyTx<ViewCommandResult>,
535546
cmd: ViewCommand,
536547
},
548+
/// See [`JsInstance::call_procedure`].
537549
CallProcedure {
538550
reply_tx: JsReplyTx<CallProcedureReturn>,
539551
params: CallProcedureParams,
540552
},
553+
/// See [`JsInstance::clear_all_clients`].
541554
ClearAllClients(JsReplyTx<anyhow::Result<()>>),
555+
/// See [`JsInstance::call_identity_connected`].
542556
CallIdentityConnected {
543557
reply_tx: JsReplyTx<Result<(), ClientConnectedError>>,
544558
caller_auth: ConnectionAuthCtx,
545559
caller_connection_id: ConnectionId,
546560
},
561+
/// See [`JsInstance::call_identity_disconnected`].
547562
CallIdentityDisconnected {
548563
reply_tx: JsReplyTx<Result<(), ReducerCallError>>,
549564
caller_identity: Identity,
550565
caller_connection_id: ConnectionId,
551566
},
567+
/// See [`JsInstance::disconnect_client`].
552568
DisconnectClient {
553569
reply_tx: JsReplyTx<Result<(), ReducerCallError>>,
554570
client_id: ClientActorId,
555571
},
572+
/// See [`JsInstance::init_database`].
556573
InitDatabase {
557574
reply_tx: JsReplyTx<anyhow::Result<Option<ReducerCallResult>>>,
558575
program: Program,
559576
},
577+
/// See [`JsInstance::call_scheduled_function`].
560578
CallScheduledFunction {
561579
reply_tx: JsReplyTx<CallScheduledFunctionResult>,
562580
params: ScheduledFunctionParams,
@@ -592,6 +610,11 @@ struct JsInstanceLaneState {
592610
}
593611

594612
#[derive(Clone)]
613+
/// A single serialized execution lane for JS module work.
614+
///
615+
/// Callers share one active [`JsInstance`] so hot requests stay on the same
616+
/// worker thread for locality. The lane only steps in on the rare path, where
617+
/// a trap or disconnect forces that active worker to be replaced.
595618
pub struct JsInstanceLane {
596619
module: JsModule,
597620
state: Arc<JsInstanceLaneState>,

0 commit comments

Comments
 (0)