WorkMaze / JUST.net

JUST - JSON Under Simple Transformation (XSLT equivalent for JSON).
MIT License
173 stars 54 forks source link

Is JsonTransformer thread-safe? #270

Open joshidp opened 1 year ago

joshidp commented 1 year ago

Hello JUST.net,

I am using JsonTransformer with single instance and when in multi-thread environment I am doing transform then results are not expected. Below code fails when jsonTransformer is declared outside the parallel loop but it works if jsonTransformer is declared inside loop context. How are we suppose to use JsonTransformer ? is it thread-safe?

var jsonTransformer = new JsonTransformer();

            var data = new List<THreadTestData>();

            data.Add(new THreadTestData()
            {
                Transformer = File.ReadAllText("atomicTX.json"),
                Input = File.ReadAllText("atomic.json"),
                Expected = "{\r\n  \"alias\": \"abc\",\r\n  \"eou\": null,\r\n  \"resourceType\": null,\r\n  \"resourceCategory\": \"FFF\",  \"reportsTo\": \"pqr\"\r\n}"
            });

            data.Add(new THreadTestData()
            {
                Transformer = File.ReadAllText("bulkTX.json"),
                Input = File.ReadAllText("bulk.json"),
                Expected = "[\r\n  {\r\n    \"alias\": \"abc\"\r\n  },\r\n  {\r\n    \"alias\": \"xyz\"\r\n  }\r\n]"
            });

            // Execute the loop in parallel
            Parallel.For(0, 100, i =>
            {
                THreadTestData threadTestData = null;
                {
                    threadTestData = data.First();
                    // var jsonTransformer = new JsonTransformer();
                    var tx = jsonTransformer.Transform(JObject.Parse(threadTestData.Transformer), threadTestData.Input);

                    if (tx.ToString() != threadTestData.Expected)
                    {

                    }
                    else
                    {

                    }
                }
                {
                    threadTestData = data.Last();
                    //  var jsonTransformer = new JsonTransformer();
                    var tx = jsonTransformer.Transform(JObject.Parse(threadTestData.Transformer), threadTestData.Input);

                    if (tx.ToString() != threadTestData.Expected)
                    {

                    }
                }

                Task.Delay(2 * 100).Wait();
            });

Thanks

Courela commented 1 year ago

Current version should be thread-safe.

260

joshidp commented 1 year ago

I am using latest 4.3.0 and its not acting thread-safe, above code snippet scenario can validate it.

Courela commented 1 year ago

You're right, different instances of JsonTransformer work fine, but the same instance does not, there's a property, JUSTContext, that is read and set throughout the code...

joshidp commented 1 year ago

JUSTContext have setting values, transformer and inputs are not part of it, so how JUSTContext can help here? Is it a bug?

JUSTContext context = new JUSTContext 
{ 
  EvaluationMode = EvaluationMode.Strict,
  DefaultDecimalPlaces = 4
};
Courela commented 1 year ago

Input is a property of JUSTContext (internal), it is set at the beginning of the tranformation, and it is changed whenever is needed (for example, multiple transformations use it, I'm not sure but maybe #applyover and loops also...)

joshidp commented 1 year ago

So, sounds like JsonTransformer is not thread-safe in true sense and we should re-instantiate JsonTransformer for each transformation.

Courela commented 1 year ago

Not thread-safe at all... One thing to check

s-summers commented 4 weeks ago

Are there any plans to release this fix to nuget?