Skip to content

Commit cb9dcea

Browse files
committed
feat: introduce EdgeRuntime.getRuntimeMetrics
1 parent ee38bb8 commit cb9dcea

File tree

14 files changed

+223
-105
lines changed

14 files changed

+223
-105
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/base/src/deno_runtime.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ impl DenoRuntime {
421421
// the task from the other threads.
422422
// let mut current_thread_id = std::thread::current().id();
423423

424-
let result = match poll_fn(|cx| {
424+
let poll_result = poll_fn(|cx| {
425425
// INVARIANT: Only can steal current task by other threads when LIFO
426426
// task scheduler heuristic disabled. Turning off the heuristic is
427427
// unstable now, so it's not considered.
@@ -487,8 +487,9 @@ impl DenoRuntime {
487487

488488
poll_result
489489
})
490-
.await
491-
{
490+
.await;
491+
492+
let result = match poll_result {
492493
Err(err) => Err(anyhow!("event loop error: {}", err)),
493494
Ok(_) => match mod_result_rx.await {
494495
Err(e) => {
@@ -576,6 +577,7 @@ mod test {
576577
conf: {
577578
WorkerRuntimeOpts::MainWorker(MainWorkerRuntimeOpts {
578579
worker_pool_tx,
580+
shared_metric_src: None,
579581
event_worker_metric_src: None,
580582
})
581583
},
@@ -620,6 +622,7 @@ mod test {
620622
conf: {
621623
WorkerRuntimeOpts::MainWorker(MainWorkerRuntimeOpts {
622624
worker_pool_tx,
625+
shared_metric_src: None,
623626
event_worker_metric_src: None,
624627
})
625628
},
@@ -686,6 +689,7 @@ mod test {
686689
conf: {
687690
WorkerRuntimeOpts::MainWorker(MainWorkerRuntimeOpts {
688691
worker_pool_tx,
692+
shared_metric_src: None,
689693
event_worker_metric_src: None,
690694
})
691695
},
@@ -748,6 +752,7 @@ mod test {
748752
} else {
749753
WorkerRuntimeOpts::MainWorker(MainWorkerRuntimeOpts {
750754
worker_pool_tx,
755+
shared_metric_src: None,
751756
event_worker_metric_src: None,
752757
})
753758
}

crates/base/src/rt_worker/worker.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use event_worker::events::{
1111
use futures_util::FutureExt;
1212
use log::{debug, error};
1313
use sb_core::conn_sync::ConnSync;
14-
use sb_core::{RuntimeMetricSource, WorkerMetricSource};
14+
use sb_core::{MetricSource, RuntimeMetricSource, WorkerMetricSource};
1515
use sb_workers::context::{UserWorkerMsgs, WorkerContextInitOpts};
1616
use std::any::Any;
1717
use std::future::{pending, Future};
@@ -88,7 +88,7 @@ impl Worker {
8888
UnboundedSender<UnixStreamEntry>,
8989
UnboundedReceiver<UnixStreamEntry>,
9090
),
91-
booter_signal: Sender<Result<WorkerMetricSource, Error>>,
91+
booter_signal: Sender<Result<MetricSource, Error>>,
9292
termination_token: Option<TerminationToken>,
9393
) {
9494
let worker_name = self.worker_name.clone();
@@ -103,11 +103,7 @@ impl Worker {
103103
let method_cloner = self.clone();
104104
let timing = opts.timing.take();
105105
let worker_kind = opts.conf.to_worker_kind();
106-
let maybe_event_worker_metric_src = opts
107-
.conf
108-
.as_main_worker()
109-
.as_ref()
110-
.and_then(|it| it.event_worker_metric_src.clone());
106+
let maybe_main_worker_opts = opts.conf.as_main_worker().cloned();
111107

112108
let cancel = self.cancel.clone();
113109
let rt = if worker_kind.is_user_worker() {
@@ -125,24 +121,29 @@ impl Worker {
125121

126122
let result = match DenoRuntime::new(opts).await {
127123
Ok(mut new_runtime) => {
128-
let metric = {
124+
let metric_src = {
129125
let js_runtime = &mut new_runtime.js_runtime;
130-
let metric = WorkerMetricSource::from_js_runtime(js_runtime);
126+
let metric_src = WorkerMetricSource::from_js_runtime(js_runtime);
131127

132128
if worker_kind.is_main_worker() {
129+
let opts = maybe_main_worker_opts.unwrap();
133130
let state = js_runtime.op_state();
134131
let mut state_mut = state.borrow_mut();
135-
136-
state_mut.put(RuntimeMetricSource::new(
137-
metric.clone(),
138-
maybe_event_worker_metric_src,
139-
));
132+
let metric_src = RuntimeMetricSource::new(
133+
metric_src.clone(),
134+
opts.event_worker_metric_src
135+
.and_then(|it| it.into_worker().ok()),
136+
opts.shared_metric_src,
137+
);
138+
139+
state_mut.put(metric_src.clone());
140+
MetricSource::Runtime(metric_src)
141+
} else {
142+
MetricSource::Worker(metric_src)
140143
}
141-
142-
metric
143144
};
144145

145-
let _ = booter_signal.send(Ok(metric));
146+
let _ = booter_signal.send(Ok(metric_src));
146147

147148
// CPU TIMER
148149
let (termination_event_tx, termination_event_rx) =

crates/base/src/rt_worker/worker_ctx.rs

Lines changed: 59 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use event_worker::events::{
1212
use hyper::{Body, Request, Response};
1313
use log::{debug, error};
1414
use sb_core::conn_sync::ConnSync;
15-
use sb_core::WorkerMetricSource;
15+
use sb_core::{MetricSource, SharedMetricSource};
1616
use sb_graph::EszipPayloadKind;
1717
use sb_workers::context::{
1818
EventWorkerRuntimeOpts, MainWorkerRuntimeOpts, Timing, UserWorkerMsgs, WorkerContextInitOpts,
@@ -310,10 +310,10 @@ impl CreateWorkerArgs {
310310

311311
pub async fn create_worker<Opt: Into<CreateWorkerArgs>>(
312312
init_opts: Opt,
313-
) -> Result<(WorkerMetricSource, mpsc::UnboundedSender<WorkerRequestMsg>), Error> {
313+
) -> Result<(MetricSource, mpsc::UnboundedSender<WorkerRequestMsg>), Error> {
314314
let (unix_stream_tx, unix_stream_rx) = mpsc::unbounded_channel::<UnixStreamEntry>();
315315
let (worker_boot_result_tx, worker_boot_result_rx) =
316-
oneshot::channel::<Result<WorkerMetricSource, Error>>();
316+
oneshot::channel::<Result<MetricSource, Error>>();
317317

318318
let CreateWorkerArgs(init_opts, maybe_supervisor_policy, maybe_termination_token) =
319319
init_opts.into();
@@ -464,13 +464,7 @@ pub async fn create_events_worker(
464464
no_module_cache: bool,
465465
maybe_entrypoint: Option<String>,
466466
termination_token: Option<TerminationToken>,
467-
) -> Result<
468-
(
469-
WorkerMetricSource,
470-
mpsc::UnboundedSender<WorkerEventWithMetadata>,
471-
),
472-
Error,
473-
> {
467+
) -> Result<(MetricSource, mpsc::UnboundedSender<WorkerEventWithMetadata>), Error> {
474468
let (events_tx, events_rx) = mpsc::unbounded_channel::<WorkerEventWithMetadata>();
475469

476470
let mut service_path = events_worker_path.clone();
@@ -509,71 +503,79 @@ pub async fn create_user_worker_pool(
509503
policy: WorkerPoolPolicy,
510504
worker_event_sender: Option<mpsc::UnboundedSender<WorkerEventWithMetadata>>,
511505
termination_token: Option<TerminationToken>,
512-
) -> Result<mpsc::UnboundedSender<UserWorkerMsgs>, Error> {
506+
) -> Result<(SharedMetricSource, mpsc::UnboundedSender<UserWorkerMsgs>), Error> {
507+
let metric_src = SharedMetricSource::default();
513508
let (user_worker_msgs_tx, mut user_worker_msgs_rx) =
514509
mpsc::unbounded_channel::<UserWorkerMsgs>();
515510

516511
let user_worker_msgs_tx_clone = user_worker_msgs_tx.clone();
517512

518-
let _handle: tokio::task::JoinHandle<Result<(), Error>> = tokio::spawn(async move {
519-
let token = termination_token.as_ref();
520-
let mut termination_requested = false;
521-
let mut worker_pool =
522-
WorkerPool::new(policy, worker_event_sender, user_worker_msgs_tx_clone);
523-
524-
// Note: Keep this loop non-blocking. Spawn a task to run blocking calls.
525-
// Handle errors within tasks and log them - do not bubble up errors.
526-
loop {
527-
tokio::select! {
528-
_ = async {
529-
if let Some(token) = token {
530-
token.inbound.cancelled().await;
531-
} else {
532-
pending::<()>().await;
533-
}
534-
}, if !termination_requested => {
535-
termination_requested = true;
536-
537-
if worker_pool.user_workers.is_empty() {
513+
let _handle: tokio::task::JoinHandle<Result<(), Error>> = tokio::spawn({
514+
let metric_src_inner = metric_src.clone();
515+
async move {
516+
let token = termination_token.as_ref();
517+
let mut termination_requested = false;
518+
let mut worker_pool = WorkerPool::new(
519+
policy,
520+
metric_src_inner,
521+
worker_event_sender,
522+
user_worker_msgs_tx_clone,
523+
);
524+
525+
// Note: Keep this loop non-blocking. Spawn a task to run blocking calls.
526+
// Handle errors within tasks and log them - do not bubble up errors.
527+
loop {
528+
tokio::select! {
529+
_ = async {
538530
if let Some(token) = token {
539-
token.outbound.cancel();
531+
token.inbound.cancelled().await;
532+
} else {
533+
pending::<()>().await;
540534
}
535+
}, if !termination_requested => {
536+
termination_requested = true;
541537

542-
break;
543-
}
544-
}
538+
if worker_pool.user_workers.is_empty() {
539+
if let Some(token) = token {
540+
token.outbound.cancel();
541+
}
545542

546-
msg = user_worker_msgs_rx.recv() => {
547-
match msg {
548-
None => break,
549-
Some(UserWorkerMsgs::Create(worker_options, tx)) => {
550-
worker_pool.create_user_worker(worker_options, tx, termination_token.as_ref().map(|it| it.child_token()));
551-
}
552-
Some(UserWorkerMsgs::Created(key, profile)) => {
553-
worker_pool.add_user_worker(key, profile);
554-
}
555-
Some(UserWorkerMsgs::SendRequest(key, req, res_tx, conn_watch)) => {
556-
worker_pool.send_request(&key, req, res_tx, conn_watch);
557-
}
558-
Some(UserWorkerMsgs::Idle(key)) => {
559-
worker_pool.idle(&key);
543+
break;
560544
}
561-
Some(UserWorkerMsgs::Shutdown(key)) => {
562-
worker_pool.shutdown(&key);
545+
}
563546

564-
if let Some(token) = token {
565-
if token.inbound.is_cancelled() && worker_pool.user_workers.is_empty() {
566-
token.outbound.cancel();
547+
msg = user_worker_msgs_rx.recv() => {
548+
match msg {
549+
None => break,
550+
Some(UserWorkerMsgs::Create(worker_options, tx)) => {
551+
worker_pool.create_user_worker(worker_options, tx, termination_token.as_ref().map(|it| it.child_token()));
552+
}
553+
Some(UserWorkerMsgs::Created(key, profile)) => {
554+
worker_pool.add_user_worker(key, profile);
555+
}
556+
Some(UserWorkerMsgs::SendRequest(key, req, res_tx, conn_watch)) => {
557+
worker_pool.send_request(&key, req, res_tx, conn_watch);
558+
}
559+
Some(UserWorkerMsgs::Idle(key)) => {
560+
worker_pool.idle(&key);
561+
}
562+
Some(UserWorkerMsgs::Shutdown(key)) => {
563+
worker_pool.shutdown(&key);
564+
565+
if let Some(token) = token {
566+
if token.inbound.is_cancelled() && worker_pool.user_workers.is_empty() {
567+
token.outbound.cancel();
568+
}
567569
}
568570
}
569571
}
570572
}
571573
}
572574
}
573-
}
574575

575-
Ok(())
576+
Ok(())
577+
}
576578
});
577579

578-
Ok(user_worker_msgs_tx)
580+
Ok((metric_src, user_worker_msgs_tx))
579581
}

crates/base/src/rt_worker/worker_pool.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use hyper::Body;
77
use log::error;
88
use sb_core::conn_sync::ConnSync;
99
use sb_core::util::sync::AtomicFlag;
10+
use sb_core::SharedMetricSource;
1011
use sb_workers::context::{
1112
CreateUserWorkerResult, SendRequestResult, Timing, TimingStatus, UserWorkerMsgs,
1213
UserWorkerProfile, WorkerContextInitOpts, WorkerRuntimeOpts,
@@ -203,6 +204,7 @@ impl ActiveWorkerRegistry {
203204
// send_request is called with UUID
204205
pub struct WorkerPool {
205206
pub policy: WorkerPoolPolicy,
207+
pub metric_src: SharedMetricSource,
206208
pub user_workers: HashMap<Uuid, UserWorkerProfile>,
207209
pub active_workers: HashMap<String, ActiveWorkerRegistry>,
208210
pub worker_pool_msgs_tx: mpsc::UnboundedSender<UserWorkerMsgs>,
@@ -214,11 +216,13 @@ pub struct WorkerPool {
214216
impl WorkerPool {
215217
pub(crate) fn new(
216218
policy: WorkerPoolPolicy,
219+
metric_src: SharedMetricSource,
217220
worker_event_sender: Option<UnboundedSender<WorkerEventWithMetadata>>,
218221
worker_pool_msgs_tx: mpsc::UnboundedSender<UserWorkerMsgs>,
219222
) -> Self {
220223
Self {
221224
policy,
225+
metric_src,
222226
worker_event_sender,
223227
user_workers: HashMap::new(),
224228
active_workers: HashMap::new(),
@@ -447,6 +451,7 @@ impl WorkerPool {
447451
.insert(WorkerId(key, self.policy.supervisor_policy.is_per_worker()));
448452

449453
self.user_workers.insert(key, profile);
454+
self.metric_src.incl_active_user_workers();
450455
}
451456

452457
pub fn send_request(
@@ -552,6 +557,8 @@ impl WorkerPool {
552557
};
553558

554559
let _ = notify_tx.send(None);
560+
561+
self.metric_src.decl_active_user_workers();
555562
}
556563

557564
fn retire(&mut self, key: &Uuid) {
@@ -570,6 +577,7 @@ impl WorkerPool {
570577

571578
if registry.workers.contains(key) {
572579
registry.workers.remove(key);
580+
self.metric_src.incl_retired_user_worker();
573581
}
574582
}
575583
}

0 commit comments

Comments
 (0)