8000 PM-10836: Make PolicyService thread safe by shannon-livefront · Pull Request #825 · bitwarden/ios · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

PM-10836: Make PolicyService thread safe #825

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

Merged
merged 2 commits into from
Aug 15, 2024

Conversation

shannon-livefront
Copy link
Collaborator
@shannon-livefront shannon-livefront commented Aug 13, 2024

🎟️ Tracking

PM-10836

📔 Objective

Fix a crash that was reported through crashlytics. No reproduction steps that I know of.

⏰ Reminders before review

  • Contributor guidelines followed
  • All formatters and local linters executed and passed
  • Written new unit and / or integration tests where applicable
  • Protected functional changes with optionality (feature flags)
  • Used internationalization (i18n) for all UI strings
  • CI builds passed
  • Communicated to DevOps any deployment requirements
  • Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team

🦮 Reviewer guidelines

  • 👍 (:+1:) or similar for great changes
  • 📝 (:memo:) or ℹ️ (:information_source:) for notes or general info
  • ❓ (:question:) for questions
  • 🤔 (:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion
  • 🎨 (:art:) for suggestions / improvements
  • ❌ (:x:) or ⚠️ (:warning:) for more significant problems or concerns needing attention
  • 🌱 (:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt
  • ⛏ (:pick:) for minor or nitpick changes

@shannon-livefront shannon-livefront marked this pull request as draft August 13, 2024 17:52
Copy link
codecov bot commented Aug 13, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 88.48%. Comparing base (a030e9b) to head (1c75fa9).
Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #825   +/-   ##
=======================================
  Coverage   88.48%   88.48%           
=======================================
  Files         600      600           
  Lines       30268    30268           
=======================================
  Hits        26782    26782           
  Misses       3486     3486           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@shannon-livefront shannon-livefront marked this pull request as ready for review August 13, 2024 18:04
Copy link
Contributor
github-actions bot commented Aug 13, 2024

Logo
Checkmarx One – Scan Summary & Details00941258-d2c2-449b-8e4a-f9e29842026c

No New Or Fixed Issues Found

@@ -51,7 +51,7 @@ protocol PolicyService: AnyObject {
/// A default implementation of a `PolicyService` which manages syncing and updates to the user's
/// policies.
///
class DefaultPolicyService: 10000 PolicyService {
actor DefaultPolicyService: PolicyService {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎨 Could a test be added accessing the dictionary from different threads concurrently proving that is now thread safe?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a great idea! Do you know if there's already an example of that somewhere in the app?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry, I missed this earlier. See the tests now I think they're correct but were you able to confirm that they fail if you leave this as a class instead of an actor?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, mostly. It was always a sporadic issue, so if I set this as a class instead of an actor, I have to run the test repeatedly before it fails

Copy link
Contributor
@KatherineInCode KatherineInCode Aug 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ Are we going to have to change more classes into actors for managing thread safety with the Swift 6 concurrency model? Is a bunch of actors an ideal solution?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's probably a good idea, unless anyone knows of any drawbacks to using actors? I'm not entirely sure where to look in the app for which classes would need to be changed, though. Should we just go through and update every service?

Copy link
Contributor
@KatherineInCode KatherineInCode Aug 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding is that actors will execute on non-main threads (aside from @MainActor-marked things) which could potentially produce unexpected behavior? There also seems to be performance implications by having too many actors calling each other, but I'm not sure we're doing enough calls to hit that in a noticeable manner.

It might make more sense to mark the particular properties/methods as isolated rather than making the whole object into an actor? But there's a lot about the Swift 6 concurrency model that I still don't fully grok, so I'm not completely sure of the implications one way or another.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Services should only need to be actors if they are managing shared state (like the policies dictionary here). Most services don't do this though; they mostly interact with other services rather than managing state of their own. StateService is already an actor and the database is accessed on a background context.

@KatherineInCode Those are good points; it's hard to say if we would run into performance implications without profiling, but my gut feeling as well is that we don't do enough of actor hopping that it would make a noticeable difference. I'm still figuring out isolation as well, but I guess I'm not following how that would help us here. Actor is going to isolate all methods/properties here; but most(all?) methods here end up relying on the policies dictionary so I'm not sure if we could make any methods be non-isolated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That all makes sense, and I think we're good with just making this an actor for now. It's something for us to keep in mind over time, though, especially if we continue to run into these sorts of thread errors.

👍🏻

@shannon-livefront shannon-livefront force-pushed the PM-10836-policy-update-crash branch from 6b863b7 to 1c75fa9 Compare August 14, 2024 18:36
@shannon-livefront shannon-livefront merged commit 12d1998 into main Aug 15, 2024
8 checks passed
@shannon-livefront shannon-livefront deleted the PM-10836-policy-update-crash branch August 15, 2024 16:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
0