From 71726cc6e2520a7c3c5a730f4d6852355a75f8bf Mon Sep 17 00:00:00 2001 From: Serhii Tatarintsev Date: Wed, 17 Jan 2024 10:35:09 +0100 Subject: [PATCH] qe-wasm: Fix consistent `now()` value (#4650) * qe-wasm: Fix consistent `now()` value We implemented introduced consitent `request_now` value in #3200, however, we've opted out of thread local value if there is no active tokio handle. This is problem for WASM build, since it does not have use an actual tokio runtime. Replacing handle check with `LocalKey::try_with` allows us to use task local variable without the runtime, while still preserving fallback for immediate value if task local is not set. Fix prisma/team-orm#645 * Fix formatting * Reword comment --- .../tests/new/regressions/prisma_12572.rs | 6 +----- .../core/src/executor/request_context.rs | 17 +++++++++-------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/query-engine/connector-test-kit-rs/query-engine-tests/tests/new/regressions/prisma_12572.rs b/query-engine/connector-test-kit-rs/query-engine-tests/tests/new/regressions/prisma_12572.rs index a107b354d159..35f056f8fa80 100644 --- a/query-engine/connector-test-kit-rs/query-engine-tests/tests/new/regressions/prisma_12572.rs +++ b/query-engine/connector-test-kit-rs/query-engine-tests/tests/new/regressions/prisma_12572.rs @@ -26,11 +26,7 @@ mod prisma_12572 { .to_owned() } - #[connector_test(exclude( - Postgres("pg.js.wasm", "neon.js.wasm"), - Sqlite("libsql.js.wasm"), - Vitess("planetscale.js.wasm") - ))] + #[connector_test] async fn all_generated_timestamps_are_the_same(runner: Runner) -> TestResult<()> { runner .query(r#"mutation { createOneTest1(data: {id:"one", test2s: { create: {id: "two"}}}) { id }}"#) diff --git a/query-engine/core/src/executor/request_context.rs b/query-engine/core/src/executor/request_context.rs index e4f0c7122ee9..f69777bfe76e 100644 --- a/query-engine/core/src/executor/request_context.rs +++ b/query-engine/core/src/executor/request_context.rs @@ -18,14 +18,15 @@ tokio::task_local! { /// /// If we had a query context we carry for the entire lifetime of the query, it would belong there. pub(crate) fn get_request_now() -> PrismaValue { - // FIXME: we want to bypass task locals if this code is executed outside of a tokio context. As - // of this writing, it happens only in the query validation test suite. - // - // Eventually, this will go away when we have a plain query context reference we pass around. - if tokio::runtime::Handle::try_current().is_err() { - return PrismaValue::DateTime(chrono::Utc::now().into()); - } - REQUEST_CONTEXT.with(|rc| rc.request_now.clone()) + REQUEST_CONTEXT.try_with(|rc| rc.request_now.clone()).unwrap_or_else(|_| + // Task local might not be set in some cases. + // At the moment of writing, this happens only in query validation test suite. + // In that case, we want to fall back to realtime value. On the other hand, if task local is + // set, we want to use it, even if we are not running inside of tokio runtime (for example, + // in WASM case) + // + // Eventually, this will go away when we have a plain query context reference we pass around. + PrismaValue::DateTime(chrono::Utc::now().into())) } /// The engine protocol used for the whole duration of a request.