Skip to content
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

fix: getCallManagerForClient is not thread safe #2060

Merged

Conversation

MohamadJaara
Copy link
Member


PR Submission Checklist for internal contributors

  • The PR Title

    • conforms to the style of semantic commits messages¹ supported in Wire's Github Workflow²
    • contains a reference JIRA issue number like SQPIT-764
    • answers the question: If merged, this PR will: ... ³
  • The PR Description

    • is free of optional paragraphs and you have filled the relevant parts to the best of your ability

What's new in this PR?

Issues

GlobalCallManager.getCallManagerForClient is not thread safe, this can cause a case where multiple instances of AVS being created

Solutions

use computeIfAbsent to fix the issue

Needs releases with:

  • GitHub link to other pull request

Testing

Test Coverage (Optional)

  • I have added automated test to this contribution

How to Test

Briefly describe how this change was tested and if applicable the exact steps taken to verify that it works as expected.

Notes (Optional)

Specify here any other facts that you think are important for this issue.

Attachments (Optional)

Attachments like images, videos, etc. (drag and drop in the text box)


PR Post Submission Checklist for internal contributors (Optional)

  • Wire's Github Workflow has automatically linked the PR to a JIRA issue

PR Post Merge Checklist for internal contributors

  • If any soft of configuration variable was introduced by this PR, it has been added to the relevant documents and the CI jobs have been updated.

References
  1. https://sparkbox.com/foundry/semantic_commit_messages
  2. https://github.com/wireapp/.github#usage
  3. E.g. feat(conversation-list): Sort conversations by most emojis in the title #SQPIT-764.

@github-actions
Copy link
Contributor

github-actions bot commented Sep 14, 2023

Unit Test Results

   410 files     410 suites   26s ⏱️
2 248 tests 2 128 ✔️ 120 💤 0

Results for commit 651316a.

♻️ This comment has been updated with latest results.

@datadog-wireapp
Copy link

datadog-wireapp bot commented Sep 14, 2023

Datadog Report

All test runs d59612b 🔗

2 Total Test Services: 0 Failed, 0 with New Flaky, 2 Passed

Test Services
Service Name Failed Known Flaky New Flaky Passed Skipped Wall Time Branch View
kalium-ios 0 0 0 2128 120 9m 35s Link
kalium-jvm 0 0 0 2245 98 10m 3s Link

@codecov-commenter
Copy link

Codecov Report

❗ No coverage uploaded for pull request base (release/candidate@b07dccc). Click here to learn what that means.
The diff coverage is n/a.

@@                 Coverage Diff                  @@
##             release/candidate    #2060   +/-   ##
====================================================
  Coverage                     ?   58.04%           
  Complexity                   ?       24           
====================================================
  Files                        ?     1004           
  Lines                        ?    37578           
  Branches                     ?     3431           
====================================================
  Hits                         ?    21813           
  Misses                       ?    14293           
  Partials                     ?     1472           

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b07dccc...f8a43d7. Read the comment docs.

@MohamadJaara MohamadJaara requested review from a team, yamilmedina, alexandreferris, borichellow, Garzas and trOnk12 and removed request for a team September 15, 2023 07:31
@MohamadJaara MohamadJaara enabled auto-merge (squash) September 15, 2023 07:31
Comment on lines +88 to +103
return callManagerHolder.computeIfAbsent(userId) {
CallManagerImpl(
calling = calling,
callRepository = callRepository,
userRepository = userRepository,
currentClientIdProvider = currentClientIdProvider,
selfConversationIdProvider = selfConversationIdProvider,
callMapper = callMapper,
messageSender = messageSender,
conversationRepository = conversationRepository,
federatedIdMapper = federatedIdMapper,
qualifiedIdMapper = qualifiedIdMapper,
videoStateChecker = videoStateChecker,
conversationClientsInCallUpdater = conversationClientsInCallUpdater,
kaliumConfigs = kaliumConfigs
)
Copy link
Member

Choose a reason for hiding this comment

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

Not sure if I understand correctly the fix as computeIfAbsent is not thread safe AFAIK.

Also this way we will not have instance by logged in user.

Copy link
Member Author

Choose a reason for hiding this comment

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

Previously, there was a process in place. It first checked if a map contained a "callManager" for a specific user ID. If not, it would create a new "callManager" and save its reference in the map. However, there was a problem. If two threads simultaneously performed this check, they could both conclude that there was no "callManager" for the user and both create a new one.

Now, we've improved this process by using a Java data structure called ConcurrentHashMap. With it, we use the computeIfAbsent method, which ensures that even if multiple threads try to create a "callManager" at the same time, it will be done in a way that is safe and does not result in duplicate "callManagers."

Copy link
Member Author

Choose a reason for hiding this comment

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

you can check out what it does here

Copy link
Member Author

Choose a reason for hiding this comment

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

as computeIfAbsent is not thread safe AFAIK.

computeIfAbsent in HashMap are not thread safe but we are using ConcurrentHashMap which it is

Copy link
Member

Choose a reason for hiding this comment

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

but now with this changes, we are no longer adding instances to callManagerHolder

Copy link
Member Author

Choose a reason for hiding this comment

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

If the specified key is not already associated with a value, attempts to compute its value using the given mapping function and enters it into this map unless null

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html#computeIfAbsent-K-java.util.function.Function-

@MohamadJaara MohamadJaara merged commit c03952f into release/candidate Sep 15, 2023
14 checks passed
@MohamadJaara MohamadJaara deleted the fix/getCallManagerForClient-is-not-thread-safe branch September 15, 2023 10:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants