Hey there,
I'm struggling with interror mutability in an multithreaded environment.
I have a database struct that holds sets of elements which are interconnected for tree traversal:
pub struct Db<GranteeId: Key, ActionId: Key> {
grantees: HashSet<Grantee<GranteeId, ActionId>>,
actions: HashSet<Action<ActionId, GranteeId>>,
}
pub struct Grantee<GranteeId: Key, ActionId: Key> {
pub key: GranteeId,
interior: Rc<RefCell<GranteeInterior<GranteeId, ActionId>>>,
}
pub struct GranteeInterior<GranteeId: Key, ActionId: Key> {
pub grantee_of: HashSet<Grantee<GranteeId, ActionId>>,
pub grantees: HashSet<Grantee<GranteeId, ActionId>>,
pub actions: HashSet<Action<ActionId, GranteeId>>,
}
pub struct Action<ActionId: Key, GranteeId: Key> {
pub key: ActionId,
interior: Rc<RefCell<HashSet<Grantee<GranteeId, ActionId>>>>,
}
This works flawless for single threaded applications
Multithreading is where the struggle begins. I know I need to wrap the Db-struct to share it across threads like this type async_db = Arc<RwLock<Db<GranteeId, ActionId>>>
Initially I thought this would work as is because the access would have been locked as is. But unfortunately I need to replace every Rc
with Arc
and RefCell
with RwLock
because other wise it would not impl Send + Sync
;
This looks like a lot of extra work. Is there a more elegant and performant way to do this? I figured, as they're all interior mutable, even a RwLock would allow to mutate it even if a lock was given.
I do not want to lock every Grantee/Action that I visit.
Would a Mutex
work better?