-
Notifications
You must be signed in to change notification settings - Fork 155
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 crash about several DataStores using the same file #2312
Conversation
- Create `@SessionCoroutineScope` annotation to pass a session-managed coroutine scope to the DI. - Expose this scope from `MatrixClient`. - Rework DataStore file creation a bit.
📱 Scan the QR code below to install the build (arm64 only) for this PR. |
0a54f82
to
bc47708
Compare
bc47708
to
0963aae
Compare
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## develop #2312 +/- ##
===========================================
- Coverage 70.08% 70.06% -0.02%
===========================================
Files 1353 1355 +2
Lines 33247 33256 +9
Branches 6877 6877
===========================================
+ Hits 23301 23302 +1
- Misses 6638 6646 +8
Partials 3308 3308 ☔ View full report in Codecov by Sentry. |
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 remark otherwise LGTM
@@ -33,6 +35,10 @@ interface SessionComponent : NodeFactoriesBindings { | |||
interface Builder { | |||
@BindsInstance | |||
fun client(matrixClient: MatrixClient): Builder | |||
|
|||
@BindsInstance |
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.
Why using @BindsInstance
here? I'd just use @Provides
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.
Won't @Provides
need the function to be implemented?
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.
We already have lots of @provides in the SessionMatrixModule
. I'd use the builder only for things we got from the outer world.
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.
Oh, now I see what you mean. Yeah, a provides is better here.
@jmartinesp I can repro the crash on the latest nightly systematically by:
But they are other recipes, for instance:
|
@@ -0,0 +1 @@ | |||
Fix 'There are multiple DataStores active for the same file' crashes |
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.
I am tempted to say that it's not necessary to add a file for the changelog, since the crash was not on the previous release.
@bmarty thanks for the reproducible steps! Sadly, it seems like the fix does not really fix the issue then... I'll keep trying. |
…ncesStoreFactory` until we figure out what went wrong with the scoping
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.
Glad to see that the issue is fixed!
I have some more remarks before we can merge this PR.
@ContributesTo(SessionScope::class) | ||
object SessionPreferencesModule { | ||
@Provides | ||
@SingleIn(SessionScope::class) |
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.
I think @SingleIn(SessionScope::class)
is not necessary here. defaultSessionPreferencesStoreFactory
is already handling the concurrency access.
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.
True, I was just keeping it there in case we can solve the underlying issue and remove DefaultSessionPreferencesStoreFactory
. But it doesn't do anything at the moment, so we can remove it.
@SingleIn(SessionScope::class) | ||
fun providesSessionPreferencesStore( | ||
defaultSessionPreferencesStoreFactory: DefaultSessionPreferencesStoreFactory, | ||
currentSessionIdHolder: CurrentSessionIdHolder, |
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.
Since this object has the scope SessionScope
, can we inject directly the sessionId: String
instead of the CurrentSessionIdHolder
?
Oh actually CurrentSessionIdHolder
is not what I though. It's not really a Holder
, but more an accessor (or a provider). I think it will be simpler to provide the sessionId
in SessionMatrixModule
like some other fields and remove CurrentSessionIdHolder
. Out of scope of this PR 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.
I think it will be simpler to provide the sessionId in SessionMatrixModule like some other fields and remove CurrentSessionIdHolder. Out of scope of this PR though.
The problem is Anvil/Dagger doesn't understand that a SessionId
is since it's Java based, for the DI library it's just a String
and it won't allow you to inject it anywhere. That's why we had to create the holder wrapper. But maybe its name can be misleading.
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.
We had annotations to be able to inject String
s in the previous project and it was quite handy.
) { | ||
private val cache = ConcurrentHashMap<SessionId, DefaultSessionPreferencesStore>() | ||
|
||
fun get(sessionId: SessionId, sessionCoroutineScope: CoroutineScope) = cache.getOrPut(sessionId) { |
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.
There is a warning here:
Declaration has type inferred from a platform call, which can lead to unchecked nullability issues. Specify type explicitly as nullable or non-nullable.
DefaultSessionPreferencesStore(context, sessionId, sessionCoroutineScope) | ||
} | ||
|
||
fun remove(sessionId: SessionId) = cache.remove(sessionId) |
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.
Not used?
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.
Yeah, I might just remove this and clear
until I create a way to clear these values in another PR (#2303 ?).
|
||
fun remove(sessionId: SessionId) = cache.remove(sessionId) | ||
|
||
fun clear() = cache.clear() |
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.
Not used, but I do not see in which case we may want to have such method. So maybe just remove it?
Quality Gate passedKudos, no new issues were introduced! 0 New issues |
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.
Thanks for the update!
Type of change
Content
@SessionCoroutineScope
annotation to pass a session-managed coroutine scope to the DI.MatrixClient
.Motivation and context
Fixes #2308 (I hope).
Tests
To be honest, I'm not 100% sure how to trigger this issue. I tried logging out and in again, which was my theory for why this was happening, but sadly I couldn't reproduce the issue.
Tested devices
Checklist