Skip to content

Commit 18d8f69

Browse files
fix: polishing the worker bootstrap phase and ridding annoying cache adaptor errors emitted from transformers.js (#453)
* fix: november cleanup * stamp(sb_ai): ignore `cache_adapter` errors when is `debug` - not throwing Cache Adapter errors when is `debug` (cherry picked from commit 1396d42) --------- Co-authored-by: kallebysantos <[email protected]>
1 parent 954ab6d commit 18d8f69

File tree

3 files changed

+186
-106
lines changed

3 files changed

+186
-106
lines changed

crates/base/src/deno_runtime.rs

Lines changed: 103 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::utils::json;
66
use crate::utils::path::find_up;
77
use crate::utils::units::{bytes_to_display, mib_to_bytes, percentage_value};
88

9-
use anyhow::{anyhow, bail, Error};
9+
use anyhow::{anyhow, bail, Context, Error};
1010
use arc_swap::ArcSwapOption;
1111
use base_mem_check::{MemCheckState, WorkerHeapStatistics};
1212
use base_rt::DenoRuntimeDropToken;
@@ -18,15 +18,16 @@ use deno_core::error::{AnyError, JsError};
1818
use deno_core::url::Url;
1919
use deno_core::v8::{self, GCCallbackFlags, GCType, HeapStatistics, Isolate};
2020
use deno_core::{
21-
located_script_name, serde_json, JsRuntime, ModuleCodeString, ModuleId, ModuleLoader,
22-
ModuleSpecifier, OpState, PollEventLoopOptions, ResolutionKind, RuntimeOptions,
21+
serde_json, JsRuntime, ModuleId, ModuleLoader, ModuleSpecifier, OpState, PollEventLoopOptions,
22+
ResolutionKind, RuntimeOptions,
2323
};
2424
use deno_http::DefaultHttpPropertyExtractor;
2525
use deno_tls::deno_native_certs::load_native_certs;
2626
use deno_tls::rustls::RootCertStore;
2727
use deno_tls::RootCertStoreProvider;
2828
use futures_util::future::poll_fn;
2929
use futures_util::task::AtomicWaker;
30+
use futures_util::FutureExt;
3031
use log::error;
3132
use once_cell::sync::{Lazy, OnceCell};
3233
use sb_core::http::sb_core_http;
@@ -205,15 +206,45 @@ impl MemCheck {
205206
}
206207

207208
pub trait GetRuntimeContext {
208-
fn get_runtime_context() -> impl Serialize;
209-
}
209+
fn get_runtime_context(
210+
conf: &WorkerRuntimeOpts,
211+
use_inspector: bool,
212+
version: Option<&str>,
213+
) -> impl Serialize {
214+
serde_json::json!({
215+
"target": env!("TARGET"),
216+
"kind": conf.to_worker_kind().to_string(),
217+
"debug": cfg!(debug_assertions),
218+
"inspector": use_inspector,
219+
"version": {
220+
"runtime": version.unwrap_or("0.1.0"),
221+
"deno": MAYBE_DENO_VERSION
222+
.get()
223+
.map(|it| &**it)
224+
.unwrap_or("UNKNOWN"),
225+
},
226+
"flags": {
227+
"SHOULD_DISABLE_DEPRECATED_API_WARNING": SHOULD_DISABLE_DEPRECATED_API_WARNING
228+
.get()
229+
.copied()
230+
.unwrap_or_default(),
231+
"SHOULD_USE_VERBOSE_DEPRECATED_API_WARNING": SHOULD_USE_VERBOSE_DEPRECATED_API_WARNING
232+
.get()
233+
.copied()
234+
.unwrap_or_default()
235+
}
236+
})
237+
}
210238

211-
impl GetRuntimeContext for () {
212-
fn get_runtime_context() -> impl Serialize {
213-
serde_json::json!(null)
239+
fn get_extra_context() -> impl Serialize {
240+
serde_json::json!({})
214241
}
215242
}
216243

244+
type DefaultRuntimeContext = ();
245+
246+
impl GetRuntimeContext for DefaultRuntimeContext {}
247+
217248
#[derive(Debug, Clone)]
218249
struct GlobalMainContext(v8::Global<v8::Context>);
219250

@@ -240,7 +271,7 @@ pub enum WillTerminateReason {
240271
WallClock,
241272
}
242273

243-
pub struct DenoRuntime<RuntimeContext = ()> {
274+
pub struct DenoRuntime<RuntimeContext = DefaultRuntimeContext> {
244275
pub js_runtime: ManuallyDrop<JsRuntime>,
245276
pub drop_token: CancellationToken,
246277
pub env_vars: HashMap<String, String>, // TODO: does this need to be pub?
@@ -282,7 +313,7 @@ impl<RuntimeContext> Drop for DenoRuntime<RuntimeContext> {
282313
}
283314
}
284315

285-
impl DenoRuntime<()> {
316+
impl DenoRuntime<DefaultRuntimeContext> {
286317
pub async fn acquire() -> OwnedSemaphorePermit {
287318
RUNTIME_CREATION_SEM
288319
.with(|v| v.clone())
@@ -668,10 +699,10 @@ where
668699
let global_obj = context_local.global(scope);
669700
let bootstrap_str =
670701
v8::String::new_external_onebyte_static(scope, b"bootstrap").unwrap();
671-
let bootstrap_ns: v8::Local<v8::Object> = global_obj
702+
let bootstrap_ns = global_obj
672703
.get(scope, bootstrap_str.into())
673704
.unwrap()
674-
.try_into()
705+
.to_object(scope)
675706
.unwrap();
676707

677708
let dispatch_load_event_fn_str =
@@ -717,56 +748,17 @@ where
717748
op_state.put(dispatch_fns);
718749
op_state.put(promise_metrics.clone());
719750
op_state.put(GlobalMainContext(main_context));
751+
}
752+
753+
{
754+
let op_state_rc = js_runtime.op_state();
755+
let mut op_state = op_state_rc.borrow_mut();
720756

721757
// NOTE(Andreespirela): We do this because "NODE_DEBUG" is trying to be read during
722758
// initialization, But we need the gotham state to be up-to-date.
723759
op_state.put(sb_env::EnvVars::default());
724760
}
725761

726-
// Bootstrapping stage
727-
let script = format!(
728-
"globalThis.bootstrapSBEdge({}, {})",
729-
serde_json::json!([
730-
// 0: target
731-
env!("TARGET"),
732-
// 1: isUserWorker
733-
conf.is_user_worker(),
734-
// 2: isEventsWorker
735-
conf.is_events_worker(),
736-
// 3: edgeRuntimeVersion
737-
option_env!("GIT_V_TAG").unwrap_or("0.1.0"),
738-
// 4: denoVersion
739-
MAYBE_DENO_VERSION
740-
.get()
741-
.map(|it| &**it)
742-
.unwrap_or("UNKNOWN"),
743-
// 5: shouldDisableDeprecatedApiWarning
744-
SHOULD_DISABLE_DEPRECATED_API_WARNING
745-
.get()
746-
.copied()
747-
.unwrap_or_default(),
748-
// 6: shouldUseVerboseDeprecatedApiWarning
749-
SHOULD_USE_VERBOSE_DEPRECATED_API_WARNING
750-
.get()
751-
.copied()
752-
.unwrap_or_default(),
753-
]),
754-
{
755-
let mut runtime_context = serde_json::json!(RuntimeContext::get_runtime_context());
756-
757-
json::merge_object(
758-
&mut runtime_context,
759-
&conf
760-
.as_user_worker()
761-
.and_then(|it| it.context.clone())
762-
.map(serde_json::Value::Object)
763-
.unwrap_or_else(|| serde_json::json!({})),
764-
);
765-
766-
runtime_context
767-
}
768-
);
769-
770762
if let Some(inspector) = maybe_inspector.clone() {
771763
inspector.server.register_inspector(
772764
main_module_url.to_string(),
@@ -788,9 +780,60 @@ where
788780
.put(MemCheckWaker::from(mem_check.waker.clone()));
789781
}
790782

783+
// Bootstrapping stage
784+
let (runtime_context, extra_context, bootstrap_fn) = {
785+
let runtime_context = serde_json::json!(RuntimeContext::get_runtime_context(
786+
&conf,
787+
has_inspector,
788+
option_env!("GIT_V_TAG"),
789+
));
790+
791+
let extra_context = {
792+
let mut context = serde_json::json!(RuntimeContext::get_extra_context());
793+
794+
json::merge_object(
795+
&mut context,
796+
&conf
797+
.as_user_worker()
798+
.and_then(|it| it.context.clone())
799+
.map(serde_json::Value::Object)
800+
.unwrap_or_else(|| serde_json::json!({})),
801+
);
802+
803+
context
804+
};
805+
806+
let context = js_runtime.main_context();
807+
let scope = &mut js_runtime.handle_scope();
808+
let context_local = v8::Local::new(scope, context);
809+
let global_obj = context_local.global(scope);
810+
let bootstrap_str =
811+
v8::String::new_external_onebyte_static(scope, b"bootstrapSBEdge").unwrap();
812+
let bootstrap_fn = v8::Local::<v8::Function>::try_from(
813+
global_obj.get(scope, bootstrap_str.into()).unwrap(),
814+
)
815+
.unwrap();
816+
817+
let runtime_context_local = deno_core::serde_v8::to_v8(scope, runtime_context)
818+
.context("failed to convert to v8 value")?;
819+
let runtime_context_global = v8::Global::new(scope, runtime_context_local);
820+
let extra_context_local = deno_core::serde_v8::to_v8(scope, extra_context)
821+
.context("failed to convert to v8 value")?;
822+
let extra_context_global = v8::Global::new(scope, extra_context_local);
823+
let bootstrap_fn_global = v8::Global::new(scope, bootstrap_fn);
824+
825+
(
826+
runtime_context_global,
827+
extra_context_global,
828+
bootstrap_fn_global,
829+
)
830+
};
831+
791832
js_runtime
792-
.execute_script(located_script_name!(), ModuleCodeString::from(script))
793-
.expect("Failed to execute bootstrap script");
833+
.call_with_args(&bootstrap_fn, &[runtime_context, extra_context])
834+
.now_or_never()
835+
.transpose()
836+
.context("failed to execute bootstrap script")?;
794837

795838
{
796839
// run inside a closure, so op_state_rc is released
@@ -1813,7 +1856,7 @@ mod test {
18131856
struct WithSyncFileAPI;
18141857

18151858
impl GetRuntimeContext for WithSyncFileAPI {
1816-
fn get_runtime_context() -> impl Serialize {
1859+
fn get_extra_context() -> impl Serialize {
18171860
serde_json::json!({
18181861
"useReadSyncFileAPI": true,
18191862
})
@@ -2559,7 +2602,7 @@ mod test {
25592602
struct Ctx;
25602603

25612604
impl GetRuntimeContext for Ctx {
2562-
fn get_runtime_context() -> impl Serialize {
2605+
fn get_extra_context() -> impl Serialize {
25632606
serde_json::json!({
25642607
"useReadSyncFileAPI": true,
25652608
"shouldBootstrapMockFnThrowError": true,

crates/sb_ai/js/onnxruntime/cache_adapter.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { primordials } from 'ext:core/mod.js';
1+
import { primordials, internals } from 'ext:core/mod.js';
22
import * as webidl from 'ext:deno_webidl/00_webidl.js';
33
import * as DenoCaches from 'ext:deno_cache/01_cache.js';
44

@@ -9,7 +9,7 @@ const {
99

1010
async function open(cacheName, _next) {
1111
if (!ALLOWED_CACHE_NAMES.includes(cacheName)) {
12-
throw new Error("Web Cache is not available in this context");
12+
return await notAvailable();
1313
}
1414

1515
// NOTE(kallebysantos): Since default `Web Cache` is not alloed we need to manually create a new
@@ -56,6 +56,11 @@ CacheStoragePrototype.open = async function (args) {
5656
// scenario where `Web Cache` is free to use, the `sb_ai: Cache Adapter` should act as request
5757
// middleware ie. add new behaviour on top of `next()`
5858
async function notAvailable() {
59+
// Ignore errors when `debug = true`
60+
if(internals,internals.bootstrapArgs.opts.debug) {
61+
return;
62+
}
63+
5964
throw new Error("Web Cache is not available in this context");
6065
}
6166

0 commit comments

Comments
 (0)