cs-script
cs-script copied to clipboard
Concurrent compilation
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
Hey Eugene, let me refresh my memory and come back to you on this one
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:
- Win and Linux have different implementations for their mutex equivalents.
- .NET Framework and Mono did not offer a consistent implementation either.
- What is even more challenging is that the actual compilers csc.exe/mono.exe had the tendency to hang in memory even after successful compilation of the assembly. .NET Core is even more guilty of this. IE not terminating the forked dotnet.exe process in case of a compilation error.
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.
I have published the prerelease with the change: https://github.com/oleg-shilo/cs-script/releases/tag/v4.7.2
Thank you very much for detailed explanation and fast workaround providing!