Skip to content

Commit

Permalink
feat: add mechanism to bypass turbo engine for annotated methods
Browse files Browse the repository at this point in the history
This PR still needs some work, since we will need to transparently
forward VCs or eagerly evaluate them. We need to ensure that the parent
task is still lazy, but that we are just cutting out task tracking
between tasks.
  • Loading branch information
arlyon committed May 10, 2024
1 parent 01f812c commit d49e885
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 1 deletion.
19 changes: 18 additions & 1 deletion crates/turbo-tasks-build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,21 @@ use turbo_tasks_macros_shared::{
get_type_ident, GenericTypeInput, PrimitiveInput, ValueTraitArguments,
};

/// the same module exists in turbo-tasks-macros but due to its size we
/// just copy the relevant parts in both places
mod ignored {
use std::{cell::OnceCell, collections::HashSet};
// a newline-separated list of task names to opt-out of turbo tracking
const IGNORE_TASKS_RAW: Option<&str> = std::option_env!("TURBO_IGNORE_TASKS");
const IGNORE_TASKS: OnceCell<HashSet<&'static str>> = OnceCell::new();

pub fn task_ignored(name: &str) -> bool {
IGNORE_TASKS
.get_or_init(|| IGNORE_TASKS_RAW.unwrap_or_default().split(',').collect())
.contains(name)
}
}

pub fn generate_register() {
println!("cargo:rerun-if-changed=build.rs");

Expand Down Expand Up @@ -221,7 +236,9 @@ impl<'a> RegisterContext<'a> {
}

fn process_fn(&mut self, fn_item: ItemFn) -> Result<()> {
if has_attribute(&fn_item.attrs, "function") {
if has_attribute(&fn_item.attrs, "function")
&& !ignored::task_ignored(&fn_item.sig.ident.to_string())
{
let ident = &fn_item.sig.ident;
let type_ident = get_native_function_ident(ident);

Expand Down
26 changes: 26 additions & 0 deletions crates/turbo-tasks-macros/src/function_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,35 @@ use turbo_tasks_macros_shared::{get_native_function_id_ident, get_native_functio

use crate::func::{DefinitionContext, NativeFn, TurboFn};

/// the same module exists in turbo-tasks-build but due to its size we
/// just copy the relevant parts in both places
mod ignored {
use std::{cell::OnceCell, collections::HashSet};
// a newline-separated list of task names to opt-out of turbo tracking
const IGNORE_TASKS_RAW: Option<&str> = std::option_env!("TURBO_IGNORE_TASKS");
const IGNORE_TASKS: OnceCell<HashSet<&'static str>> = OnceCell::new();

Check failure on line 15 in crates/turbo-tasks-macros/src/function_macro.rs

View workflow job for this annotation

GitHub Actions / Turbopack rust clippy

a `const` item should never be interior mutable

pub fn task_ignored(name: &str) -> bool {
IGNORE_TASKS

Check failure on line 18 in crates/turbo-tasks-macros/src/function_macro.rs

View workflow job for this annotation

GitHub Actions / Turbopack rust clippy

a `const` item with interior mutability should not be borrowed
.get_or_init(|| IGNORE_TASKS_RAW.unwrap_or_default().split(',').collect())
.contains(name)
}
}

pub fn function(_args: TokenStream, input: TokenStream) -> TokenStream {
let item = parse_macro_input!(input as ItemFn);

// TODO: ideally here we would be able to match on the entire module path
// however macros are evaluated in a different context and we don't
// have access to it. in the mean time, just use the function name.
// the likelihood that two functions with the same name exist is low
// and, if we do need to disable just one of them, can be mitigated
// through naming
let name = item.sig.ident.to_string();
if ignored::task_ignored(&name) {
return quote! { #item }.into();
}

let ItemFn {
attrs,
vis,
Expand Down

0 comments on commit d49e885

Please sign in to comment.