-
Notifications
You must be signed in to change notification settings - Fork 30
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: some crashes have come up because of logger injection. the reason seems to be the the binder is being updated every inject #387
Conversation
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.
It looks good for fixing the logger issue.
We still have unsafe dictionaries as other possible sync failure sources. Can we fix them all?
@@ -17,6 +17,18 @@ | |||
import UIKit | |||
import Optimizely | |||
|
|||
private final class CustomLogger: OPTLogger { |
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.
This is redundant with the separate CustomLogger file. I see you changed it to private. Is it required?
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.
No, I just wanted to make sure it wasn't a problem if it was private.
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 let's keep it internal and remove this extra copy (or the other one).
if binders.property?[skLocal] != nil { | ||
binders.property?[skLocal] = b | ||
} else { | ||
binders.property?[skGlobal] = b | ||
} |
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.
Don't we need synchronization to update binders dictionary?
Let's fix this unsafe dictionaries/arrays in other places as well.
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.
the binder set is an atomic property. the binder is a copy and so this is an atomic operation. the get and set are separate. but, the again, since this is only an issue with a singleton that usually provides a instance with creation. it should not be an issue. i don't want to slow everything down by constantly wrapping everything in a dispatch.
Can you tell me where we are accessing unsafe dictionaries? I would handle that with a synched dictionary not by augment ing the atomic property by the way. |
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.
The test is broken and cannot catch the thread issue here.
} | ||
} | ||
// need to let the main global queue run otherwise some remained queued. | ||
Thread.sleep(forTimeInterval: 0.02) |
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.
This sleep delay breaks the test. 1000 async tasks not concurrent any more because this delay.
If we remove the sleep delay and using DispatchGroup for sync, this test fails because concurrency issue.
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.
This sleep delay breaks the test. 1000 async tasks not concurrent any more because this delay.
If we remove the sleep delay and using DispatchGroup for sync, this test fails because concurrency issue.
Please add a test if you think it would break. The test won't run all the queued in the global queue without the sleep. So.....
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.
Approved for logger bug fix.
The other thread issue I raised can be separated and will be reviewed later instead of blocking this fix.
Summary
There have been a small number of crashes reported and it appears to be the injection of loggers from multiple threads at the same time. This is because the binder was updating the instance variable even when the binder was always suppling new instances (i.e. when not a singleton).
The fix is two fold: