Skip to content

Commit

Permalink
Merge branch 'main' into tomknickman/turbo-531-globally-installed-tur…
Browse files Browse the repository at this point in the history
  • Loading branch information
tknickman committed Dec 5, 2022
2 parents c017ec3 + d0b6365 commit 05e35c9
Show file tree
Hide file tree
Showing 19 changed files with 286 additions and 112 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions crates/next-dev/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ use turbo_tasks::{
use turbo_tasks_fs::{DiskFileSystemVc, FileSystemVc};
use turbo_tasks_memory::MemoryBackend;
use turbopack_cli_utils::issue::{ConsoleUi, ConsoleUiVc, LogOptions};
use turbopack_core::{issue::IssueSeverity, resolve::parse::RequestVc};
use turbopack_core::{
issue::IssueSeverity,
resolve::{parse::RequestVc, pattern::QueryMapVc},
};
use turbopack_dev_server::{
fs::DevServerFileSystemVc,
introspect::IntrospectionSource,
Expand Down Expand Up @@ -291,7 +294,7 @@ async fn source(
.map(|r| match r {
EntryRequest::Relative(p) => RequestVc::relative(Value::new(p.clone().into()), false),
EntryRequest::Module(m, p) => {
RequestVc::module(m.clone(), Value::new(p.clone().into()))
RequestVc::module(m.clone(), Value::new(p.clone().into()), QueryMapVc::none())
}
})
.collect();
Expand Down
13 changes: 13 additions & 0 deletions crates/turbo-tasks-fs/src/invalidator_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,16 @@ impl<'de> Deserialize<'de> for InvalidatorMap {
deserializer.deserialize_newtype_struct("InvalidatorMap", V)
}
}

impl Drop for InvalidatorMap {
fn drop(&mut self) {
while let Ok((_, value)) = self.queue.pop() {
value.invalidate();
}
for (_, invalidators) in self.map.lock().unwrap().drain() {
for invalidator in invalidators {
invalidator.invalidate();
}
}
}
}
2 changes: 2 additions & 0 deletions crates/turbo-tasks-fs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ use serde::{Deserialize, Serialize};
use serde_json::Value;
use tokio::{fs, io::AsyncReadExt};
use turbo_tasks::{
mark_stateful,
primitives::{BoolVc, StringReadRef, StringVc},
spawn_thread,
trace::TraceRawVcs,
Expand Down Expand Up @@ -271,6 +272,7 @@ pub fn path_to_key(path: impl AsRef<Path>) -> String {
impl DiskFileSystemVc {
#[turbo_tasks::function]
pub async fn new(name: String, root: String) -> Result<Self> {
mark_stateful();
// create the directory for the filesystem on disk, if it doesn't exist
fs::create_dir_all(&root).await?;

Expand Down
1 change: 1 addition & 0 deletions crates/turbo-tasks/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ indexmap = { workspace = true, features = ["serde"] }
mopa = "0.2.0"
nohash-hasher = "0.2.0"
once_cell = "1.13.0"
parking_lot = "0.12.1"
pin-project-lite = "0.2.9"
regex = "1.6.0"
serde = { version = "1.0.136", features = ["rc", "derive"] }
Expand Down
6 changes: 4 additions & 2 deletions crates/turbo-tasks/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ mod raw_vc;
mod read_ref;
pub mod registry;
pub mod small_duration;
mod state;
mod task_input;
mod timed_future;
pub mod trace;
Expand All @@ -71,14 +72,15 @@ pub use id::{
};
pub use join_iter_ext::{JoinIterExt, TryJoinIterExt};
pub use manager::{
dynamic_call, emit, get_invalidator, run_once, spawn_blocking, spawn_thread, trait_call,
turbo_tasks, Invalidator, StatsType, TaskIdProvider, TurboTasks, TurboTasksApi,
dynamic_call, emit, get_invalidator, mark_stateful, run_once, spawn_blocking, spawn_thread,
trait_call, turbo_tasks, Invalidator, StatsType, TaskIdProvider, TurboTasks, TurboTasksApi,
TurboTasksBackendApi, TurboTasksCallApi,
};
pub use native_function::{NativeFunction, NativeFunctionVc};
pub use nothing::{Nothing, NothingVc};
pub use raw_vc::{CellId, CollectiblesFuture, RawVc, ReadRawVcFuture, ResolveTypeError};
pub use read_ref::ReadRef;
pub use state::State;
pub use task_input::{FromTaskInput, SharedReference, SharedValue, TaskInput};
pub use turbo_tasks_macros::{function, value, value_impl, value_trait};
pub use value::{TransientInstance, TransientValue, Value};
Expand Down
6 changes: 6 additions & 0 deletions crates/turbo-tasks/src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,12 @@ pub fn get_invalidator() -> Invalidator {
}
}

/// Marks the current task as stateful. This prevents the tasks from being
/// dropped without persisting the state.
pub fn mark_stateful() {
// TODO pass this to the backend
}

pub fn emit<T: ValueTraitVc>(collectible: T) {
with_turbo_tasks(|tt| tt.emit_collectible(T::get_trait_type_id(), collectible.into()))
}
Expand Down
142 changes: 142 additions & 0 deletions crates/turbo-tasks/src/state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
use std::{fmt::Debug, mem::take};

use auto_hash_map::AutoSet;
use parking_lot::{Mutex, MutexGuard};
use serde::{Deserialize, Deserializer, Serialize};

use crate::{get_invalidator, mark_stateful, trace::TraceRawVcs, Invalidator};

pub struct State<T> {
inner: Mutex<StateInner<T>>,
}

struct StateInner<T> {
value: T,
invalidators: AutoSet<Invalidator>,
}

pub struct StateRef<'a, T> {
inner: MutexGuard<'a, StateInner<T>>,
}

impl<T: Debug> Debug for State<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("State")
.field("value", &self.inner.lock().value)
.finish()
}
}

impl<T: TraceRawVcs> TraceRawVcs for State<T> {
fn trace_raw_vcs(&self, context: &mut crate::trace::TraceRawVcsContext) {
self.inner.lock().value.trace_raw_vcs(context);
}
}

impl<T: Default> Default for State<T> {
fn default() -> Self {
// Need to be explicit to ensure marking as stateful.
Self::new(Default::default())
}
}

impl<T> PartialEq for State<T> {
fn eq(&self, _other: &Self) -> bool {
false
}
}
impl<T> Eq for State<T> {}

impl<T: Serialize> Serialize for State<T> {
fn serialize<S: serde::Serializer>(&self, _serializer: S) -> Result<S::Ok, S::Error> {
// For this to work at all we need to do more. Changing the the state need to
// invalidate the serialization of the task that contains the state. So we
// probably need to store the state outside of the task to be able to serialize
// it independent from the creating task.
panic!("State serialization is not implemented yet");
}
}

impl<'de, T: Deserialize<'de>> Deserialize<'de> for State<T> {
fn deserialize<D: Deserializer<'de>>(_deserializer: D) -> Result<Self, D::Error> {
panic!("State serialization is not implemented yet");
}
}

impl<T> Drop for State<T> {
fn drop(&mut self) {
let mut inner = self.inner.lock();
for invalidator in take(&mut inner.invalidators) {
invalidator.invalidate();
}
}
}

impl<T> State<T> {
pub fn new(value: T) -> Self {
mark_stateful();
Self {
inner: Mutex::new(StateInner {
value,
invalidators: AutoSet::new(),
}),
}
}

/// Gets the current value of the state. The current task will be registered
/// as dependency of the state and will be invalidated when the state
/// changes.
pub fn get(&self) -> StateRef<'_, T> {
let invalidator = get_invalidator();
let mut inner = self.inner.lock();
inner.invalidators.insert(invalidator);
StateRef { inner }
}

/// Sets the current state without comparing it with the old value. This
/// should only be used if one is sure that the value has changed.
pub fn set_unconditionally(&self, value: T) {
let mut inner = self.inner.lock();
inner.value = value;
for invalidator in take(&mut inner.invalidators) {
invalidator.invalidate();
}
}

/// Updates the current state with the `update` function. The `update`
/// function need to return `true` when the value was modified. Exposing
/// the current value from the `update` function is not allowed and will
/// result in incorrect cache invalidation.
pub fn update_conditionally(&self, update: impl FnOnce(&mut T) -> bool) {
let mut inner = self.inner.lock();
if !update(&mut inner.value) {
return;
}
for invalidator in take(&mut inner.invalidators) {
invalidator.invalidate();
}
}
}

impl<T: PartialEq> State<T> {
/// Update the current state when the `value` is different from the current
/// value. `T` must implement [PartialEq] for this to work.
pub fn set(&self, value: T) {
let mut inner = self.inner.lock();
if inner.value == value {
return;
}
inner.value = value;
for invalidator in take(&mut inner.invalidators) {
invalidator.invalidate();
}
}
}

impl<'a, T> std::ops::Deref for StateRef<'a, T> {
type Target = T;

fn deref(&self) -> &Self::Target {
&self.inner.value
}
}
1 change: 1 addition & 0 deletions crates/turbopack-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ futures = "0.3.25"
indexmap = { workspace = true }
lazy_static = "1.4.0"
patricia_tree = "0.3.1"
qstring = "0.7.2"
rand = "0.8.5"
regex = "1.5.4"
serde = { version = "1.0.136", features = ["rc"] }
Expand Down
10 changes: 7 additions & 3 deletions crates/turbopack-core/src/resolve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use self::{
},
origin::ResolveOriginVc,
parse::{Request, RequestVc},
pattern::QueryMapVc,
};
use crate::{
asset::{AssetVc, AssetsVc},
Expand Down Expand Up @@ -649,9 +650,11 @@ pub async fn resolve(
options,
)
}
Request::Module { module, path } => {
resolve_module_request(context, options, options_value, module, path).await?
}
Request::Module {
module,
path,
query,
} => resolve_module_request(context, options, options_value, module, path, query).await?,
Request::ServerRelative { path } => {
let mut new_pat = path.clone();
new_pat.push_front(".".to_string().into());
Expand Down Expand Up @@ -803,6 +806,7 @@ async fn resolve_module_request(
options_value: &ResolveOptions,
module: &str,
path: &Pattern,
_: &QueryMapVc,
) -> Result<ResolveResultVc> {
let result = find_package(
context,
Expand Down

0 comments on commit 05e35c9

Please sign in to comment.