static JSContext issue with multiple threads #21
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
It seems that static JSContext (Iterator.rruleContext) is causing problems when there are calculations on different threads. It happens, when in some (not so rare) cases two
context?.evaluateScript("var rule = new RRule({ \(ruleJSONString) })")
is being called one after another and only then two dates calculationsalso one after another. And in such case the second
new RRule({ \(ruleJSONString) })
overwrites first RRule's properties in static JSContext and first calculation uses wrong parameters.One way to avoid this issue would be reduce evaluateScript calls (create a rule and evaluate it in one evaluateScript call. I couldn't reproduce this issue after such modification):
guard let allOccurrences = Iterator.rruleContext?.evaluateScript("new RRule({ \(ruleJSONString) }).all()").toArray() as? [Date] else {
instead of
I also implemented a test, that could help quite easily reproduce the issue: you can launch Sample app and make
testRRuleIteratorMultipleThreads()
call in theviewDidLoad()
. There are 2 background thread that generates rrule and checks the returned dates. If everything worked as expected, then there would be no logs in console similar toprint("dates mismatch, got: ", occurrences.first, ", expected: ", startDate)
- first date returned by rrule's Iterator.rruleContext?.evaluateScript should be equal to its startDate. But in some 5th-10th iteration one thread overrides other's rrule parameters and wrong parameters are being used. I hope I made myself clear.