Currently when a task gets blocked, we have one of the following situations:
- The task is blocked due to using a primitive from
shuttle::sync.
- The task is blocked due to being blocked on a
Future which is Poll::Pending.
For situation 1 we know for sure why the task is blocked, while for situation 2 we do not, as it bubbles up as the task being blocked on an opaque Future in shuttle::future::block_on.
Some comments:
- Many of the async primitives have sync ways to acquire the primitive (eg.
tokio::sync::Mutex::blocking_lock) that currently are implemented by doing a shuttle::future::block_on on the async variant (eg. tokio::sync::Mutex::blocking_lock). If we had only used sync methods then we would have more information about why the task is blocked.
- There should be a better "reverse mapping" from
Acquires to tasks, so that we can log which permits a task holds (and also what primitives those permits are related to) and which permits its wanting to acquire (and this information should be displayed on a deadlock).
- If we expose "building blocks" for creating Shuttle primitives then we should take some care in making it easy to have good debuggability.
- I don't see a great way to fully "solve"
block_on; we should for sure track_caller, but that still only tells us what we are blocking on. Let's say we are blocking on a FuturesUnordered then ideally we'd be able to investigate the state of all Futures in it.
- We can get slightly more information for
Futures by adding callbacks when a Waker is cloned (
|
RawWakerVTable::new(raw_waker_clone, raw_waker_wake, raw_waker_wake_by_ref, raw_waker_drop); |
), under the assumption that that is done right before a Future becomes Poll::Pending
Currently when a task gets blocked, we have one of the following situations:
shuttle::sync.Futurewhich isPoll::Pending.For situation 1 we know for sure why the task is blocked, while for situation 2 we do not, as it bubbles up as the task being blocked on an opaque
Futureinshuttle::future::block_on.Some comments:
tokio::sync::Mutex::blocking_lock) that currently are implemented by doing ashuttle::future::block_onon the async variant (eg.tokio::sync::Mutex::blocking_lock). If we had only used sync methods then we would have more information about why the task is blocked.Acquires to tasks, so that we can log which permits a task holds (and also what primitives those permits are related to) and which permits its wanting to acquire (and this information should be displayed on a deadlock).block_on; we should for suretrack_caller, but that still only tells us what we are blocking on. Let's say we are blocking on aFuturesUnorderedthen ideally we'd be able to investigate the state of allFutures in it.Futures by adding callbacks when aWakeriscloned (shuttle/shuttle/src/runtime/task/waker.rs
Line 55 in 49faea2
FuturebecomesPoll::Pending