-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pg
: Add ScopeName
-> Vec<GroupName>
mapping
#190
Conversation
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #190 +/- ##
==========================================
+ Coverage 79.73% 79.75% +0.01%
==========================================
Files 50 50
Lines 9790 9824 +34
==========================================
+ Hits 7806 7835 +29
- Misses 1984 1989 +5 ☔ View full report in Codecov by Sentry. |
51f5eff
to
ec7c015
Compare
ractor/src/pg/mod.rs
Outdated
@@ -138,6 +140,18 @@ pub fn join_scoped(scope: ScopeName, group: GroupName, actors: Vec<ActorCell>) { | |||
vacancy.insert(map); | |||
} | |||
} | |||
match monitor.index.entry(scope.to_owned()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so the problem that this approach takes (which is why it wasn't done this way in the beginning) is that this is technically a subtle race condition. We will probably need a global lock around both of the hash maps or something, but then there's going to be the benchmarking of the performance hit for taking a global lock.
Dashmaps are sharded maps so they can do concurrent updates from multiple threads, but what we'd be doing is locking around both maps with a singleton global lock.
Unless we can try and acquire both sharded locks, doing the updates, and then only releasing the locks simultaneously.
i.e.
lock(a)
lock(b)
update(a)
update(b)
release(a)
release(b)
It will be a little ugly with the scopes, but it's the best option for concurrent updates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right of course.
I hope to find the time to experiment and benchmark, can't currently promise a timeline, though :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then again, as far as I understand we are only talking about the map
and index
fields which are only mutated in the join*
and leave*
functions.
It duplicates a bit more code but I think just locking both fields and then nesting their updates (so the locks get dropped simultaneously when leaving scope) might work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One small change left and I think we're good to merge it! Thanks for all the work put into this PR!
ractor/src/pg/mod.rs
Outdated
@@ -186,10 +200,21 @@ pub fn leave_scoped(scope: ScopeName, group: GroupName, actors: Vec<ActorCell>) | |||
mut_ref.remove(&actor.get_id()); | |||
} | |||
|
|||
// the scope and group tuple is empty, remove it | |||
// if the scope and group tuple is empty, remove it | |||
if mut_ref.is_empty() { | |||
occupied.remove(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so to the point above, i think we'd move this before the removal of the index? I still need to think a bit if there's a race that could occur here even with the drop operations release the locks sequentially
ractor/src/pg/mod.rs
Outdated
occupied_map.remove(); | ||
|
||
// remove the group and possibly the scope from the monitor's index | ||
if let Some(mut groups_in_scope) = monitor_idx { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe to be safe, move this outside of the if statement on line 224. That way we check / update the index regardless of what the occupied map says
38b05c3
to
a67ad37
Compare
a67ad37
to
a8e477c
Compare
It was/is a(n educative) pleasure. I'm learning quite a lot from this code base and your reviews. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, let's merge it!
Supersedes #189 and introduces an
index
field to thePgState
struct to mapScopeName
toVec<GroupName>
.If this isn't what was in mind, I'd need another pointer :)
Would also be open to refactoring the index's value and the modules
Vec<...>
-method returns toHashSet
s if that makes more sense.And sorry for the PR noise :)
--
Relating to #177 (comment)
and #184 (comment)