You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have an inkling that separating the dependency stack from the storage will make something better. e.g. if the API was
struct Storage { ... }
// and DbStack would either be
struct DbStack<'db> {
storage: &'db Storage,
stack: Vec<Vec<Dependency>> // Notice the double Vec
}
// or
struct DbStack<'parent, 'db: 'parent> {
storage: &'db Storage,
parent_pointer: Option<&'parent mut DbStack>
dependencies: Vec<Dependency>
}
Then we could invoke memoized functions like
let storage = create_storage(); // this is Sync
let stack = storage.create_stack(); // you can call this many times. It contains a reference to storage
memoized_function(stack); // this takes &mut stack
// since its Send you can
tokio::spawn(|| {
let stack = &storage.create_stack();
memoized_function(stack)
})
I think the stack is the only thing we care about being in one thread.
If everything is a DAG, deadlocks are avoidable (I added "no loops" to #339), e.g. in this case:
Both a and b could just wait for the other to complete first or second. And that's optimal behavior, anyway.
And you can't modify a source without &mut, so there can't be a dependency stack created in that case.
Anyway, even before we do multi-threadedness, this seems to clean things up conceptually.
I don't think a Vec is the right abstraction for the dependency stack. Instead, each function call has a pointer to the parent, and the parent has to await the children. So, I sort of imagine that calling child_memoized_function(db_stack) creates a new db_stack with a pointer to the parent.
Anyway, in a single threaded context, a Vec is fine.
I consider this exploratory and low-priority
The text was updated successfully, but these errors were encountered:
rbalicki2
changed the title
Pico - multithreadedness
Pico - thoughts on multithreadedness
Feb 20, 2025
I have an inkling that separating the dependency stack from the storage will make something better. e.g. if the API was
Then we could invoke memoized functions like
I think the stack is the only thing we care about being in one thread.
If everything is a DAG, deadlocks are avoidable (I added "no loops" to #339), e.g. in this case:
Both a and b could just wait for the other to complete
first
orsecond
. And that's optimal behavior, anyway.And you can't modify a source without
&mut
, so there can't be a dependency stack created in that case.Anyway, even before we do multi-threadedness, this seems to clean things up conceptually.
I don't think a
Vec
is the right abstraction for the dependency stack. Instead, each function call has a pointer to the parent, and the parent has to await the children. So, I sort of imagine that callingchild_memoized_function(db_stack)
creates a newdb_stack
with a pointer to the parent.Anyway, in a single threaded context, a Vec is fine.
I consider this exploratory and low-priority
The text was updated successfully, but these errors were encountered: