Currently I'm trying to get into Rust async/await and the Tokio crate. One of the things that I'm trying to do is implement an async version of a algorithm that I have that uses a DAG. This DAG that was created by me and under the hood there is a vec. I implemented the DAG as a vec because I want to reuse posititions from "deleted" nodes of the DAG (a node is just sofly deleted). I have 3 functions that update the graph: add (that might call update), update (which is recursive) and remove. When add is called, it checks the predecessors of that node in the graph (by trying to get the predecessors from the graph) and adds their indexes in the vec under hood to another vec that the struct node has.
What I did from my initial version without async/await was I transformed the functios add, update and remove as async methods and I wrapped the DAG on Tokio's Mutex. Whenever I want to mutate I call the .lock().await from the mutex, do the changes that I want and then I drop the variable so the lock is dropped.
The problem is traversing and mutating the graph. From my logs, if I add a node its predecessors (that already exists in the graph) are marked as not being there (even though the logs show that they are).
Another approach that I thought was having a Mutex at each node of the graph instead of wrapping the whole graph. This way, only one thread will have a lock at each node. Perhaps this second approach is better?