oleg-shilo / cs-script

C# scripting platform
http://www.cs-script.net
MIT License
1.56k stars 234 forks source link

Concurrent compilation #334

Open eugene-vv opened 1 year ago

eugene-vv commented 1 year ago

Hi Oleg, Reading the docs "https://github.com/oleg-shilo/cs-script/wiki/Performance%2C-Caching-and-Concurrency" I see that in Standard concurrency model (which is default on windows) in parallel script execution one engine must wait for another until it finished cached assembly validation/compilation. But in tests I got sometime Access denied error in first run when 2 parallel processes tries to compile and run the same script. Analyzing code I found in csscript.cs (line 927), that second process will wait only 3 sec for the first process. Am I right? Will second engine wait infinite time for first one finish compilation or not? I use 4.7.01 version. All the best, Eugene

oleg-shilo commented 1 year ago

Hey Eugene, let me refresh my memory and come back to you on this one

oleg-shilo commented 1 year ago

I am glad I had to look at it. It was an excellent opportunity to capture some reasons behind difficult architectural decisions made as early as 10 years ago.

second process will wait only 3 sec for the first process. Am I right?

Yes, you are right.

Will the second engine wait an infinite time for the first one to finish compilation or not?

No, it will wait only 3 seconds.


Why the default timeout is not infinite (-1) but 3 seconds? Achieving a reliable release of the system-wide synch object compilingFileLock was and still is problematic:

All this led to the frequent cases of the script engine waiting endlessly for no reason. Thus the ugly but more practical solution was to wait very conservatively for 3 seconds and then let cs-script proceed and either succeed (there is no active compiling at the time) or controllably fail (another compilation is still in progress).

Thus, unfortunately, the initial proper implementation of ConcurrencyControl had to be diluted over time to the less reliable but more pragmatic level. Meaning that the only way to implement a deterministic concurrency control is to do it from the script engine host process (shell or app).

What you can do in the situation. You can ensure that you are using in-memory assembly (InMemoryAssembly: True) and/or set the timeout to any other value. It might help if in your environment you do not experience those mutex-release problems.

Setting custom timeout will be available in the next release. I just implemented it as a response to your request (https://github.com/oleg-shilo/cs-script/commit/34e2cccdb69e8d0529fb2c2da72cc2ede41179be csscript.cs:929). You will be able to set envar "CSSCRIPT_CONCURRENCY_TIMEOUT" to "-1" and this will make the engine wait forever.

I will also add this explanation to the wiki page about concurrency.

oleg-shilo commented 1 year ago

I have published the prerelease with the change: https://github.com/oleg-shilo/cs-script/releases/tag/v4.7.2

eugene-vv commented 1 year ago

Thank you very much for detailed explanation and fast workaround providing!