digitaltwinconsortium / DTDLParser

Digital Twin Definition Language parser for .NET
MIT License
14 stars 8 forks source link

IndexOutOfRangeException when parsing models in multithreads #86

Closed jaslawinMs closed 1 year ago

jaslawinMs commented 1 year ago

version: 1.0.4-preview

When multiple threads are parsing models sometimes this exception is thrown:

Message:  System.IndexOutOfRangeException : Index was outside the bounds of the array.

Stack Trace: 

HashSet`1.AddIfNotPresent(T value, Int32& location)
HashSet`1.Add(T item)
Model.TrySetObjectProperty(Dtmi elementId, String layer, String propertyName, JsonLdProperty propProp, Dtmi referencedElementId, String keyProp, String keyValue, ParsingErrorCollection parsingErrorCollection) line 71
Model.SetObjectProperties(List`1 objectPropertyInfoList, ParsingErrorCollection parsingErrorCollection, StandardElementCollection standardElementCollection, Boolean preserveElementAliases) line 141
ModelParser.ParseInternal(IEnumerable`1 jsonTexts, DtdlParseLocator dtdlLocator) line 168
ModelParser.Parse(IEnumerable`1 jsonTexts, DtdlParseLocator dtdlLocator) line 71
rido-min commented 1 year ago

can we add a test to verify multi thread scenarios?

jrdouceur commented 1 year ago

Not really. Not a deterministic test. It shows up only probabilistically unless we were to use some concurrency test system that allows us to control the interleaving.

rido-min commented 1 year ago

I understand that multi-threading issues are difficult to reproduce, but we could try to reproduce, maybe using some test benchmark like https://github.com/timcassell/ProtoBenchmarkHelpers ?

jrdouceur commented 1 year ago

According to #87:

this can be reproduced when running unit-tests that use the model parser from the Visual Studio unit-test runner, which will execute the tests on multiple threads by default.

So one option may be to change the ci action to execute tests in parallel.

rido-min commented 1 year ago

@jaslawinMs can you share more details about your tests? Do you share any parser instances across threads, maybe using static variables? or is the parser instantiated on each test method?

jaslawinMs commented 1 year ago

tests are executed in parallel (xunit). The parser object is created for each test (a field in a test class). I also used static field and ThreadStatic attribute but it had no effect