Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Concurrency issue when initializing JS engine switcher in startup #115

Closed
VilleHakli opened this issue Feb 5, 2024 · 4 comments
Closed

Comments

@VilleHakli
Copy link

In our tests we use WebApplicationFactory from ASP.NET Core testing package to test our controllers which uses startup class to bootstrap the server used during tests. Because we run test fixtures in parallel there can be multiple separate threads running the startup code. This raised an issue where the test setup fails because of concurrency exception when JS engine switcher is being initialized.

The exception is thrown from JsEngineFactoryCollection's Add method where the same factory was added twice. However I did not dig deep enough to be sure if there might be similar issues elsewhere.

I'm not sure if this is something that is even supported, so if this is a feature rather than an bug, feel free to close the issue. We have circumvented the issue by using lock to block multiple threads from running startup initialization concurrently in our tests.

@Taritsyn
Copy link
Owner

Taritsyn commented Feb 5, 2024

Hello, Ville!

It is assumed that registration of engines in the JavaScript Engine Switcher is performed only once at start of the application (for example, in regular tests I use a special initializer). Under normal conditions, methods of the Startup class are also called only once when the application starts. Perhaps this behavior changes when using a WebApplicationFactory and because of this the error occurs.

Internally, registration of engines in the JavaScript Engine Switcher is based not on the IServiceCollection interface, but on the JsEngineSwitcher.Current property. In fact, JavaScript Engine Switcher is a global variable. This implementation is due to the fact that this library was created before appeared .NET Core and is still used in a large number of projects written in .NET Framework.

Are you directly using a JavaScript Engine Switcher or using some library that uses it as a dependency?

@VilleHakli
Copy link
Author

VilleHakli commented Feb 6, 2024

We are not using the JavaScript Engine Switcher directly our self, only configuring it. It is being used by LigerShark.WebOptimizer.Sass (or more precisely, one of its dependencies).

Now that I think about it, we do not need to compile the sass in our tests and thus there should not be any need to configure JavaScript Engine Switcher in tests.

I'm closing this issue as this is not common/supported case and there are many easy ways to circumvent the problem.

Thanks for all the work you do with this library!

@Taritsyn
Copy link
Owner

Taritsyn commented Feb 6, 2024

We are not using the JavaScript Engine Switcher directly our self, only configuring it. It is being used by LigerShark.WebOptimizer.Sass (or more precisely, one of its dependencies).

Thanks for information! I have an idea how to prevent this error.

@Taritsyn
Copy link
Owner

Taritsyn commented Feb 7, 2024

Hello, Ville!

I tried to solve this problem in JavaScript Engine Switcher 3.24.0 and WebOptimizer.Sass 3.0.115. You need to add the following setting to the Startup.cs file:

public void ConfigureServices(IServiceCollection services)
{// Registration of JS engines
    services.AddJsEngineSwitcher(options =>
    {
        options.AllowCurrentProperty = false;
        options.DefaultEngineName = JintJsEngine.EngineName;
    })
        .AddJint()
        ;

In this case, AllowCurrentProperty property forbid access to the JsEngineSwitcher.Current property, and thus all work is done through standard ASP.NET Core DI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants