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

EnsureBinAssembliesLoaded() issue #21

Closed
ltoshev opened this issue Sep 17, 2013 · 3 comments
Closed

EnsureBinAssembliesLoaded() issue #21

ltoshev opened this issue Sep 17, 2013 · 3 comments

Comments

@ltoshev
Copy link

ltoshev commented Sep 17, 2013

Hi guys

I use the library on production and right now how it is coded makes this library unusable on a site that has the scale of youtube.com.

Let me explain the issue. So when the RazorMachine initializes - it calls the following two functions on init:

In TryResolveWildcardReferences() {
...

AppDomain.CurrentDomain
.EnsureXiptonAssembliesLoaded()
.EnsureBinAssembliesLoaded();

}

EnsureBinAssembliesLoaded() on its own loads all the DLLs in the bin folder:

which is 5000 for our production site.

This leads to reaching the AppPool memory limit and the application is killed by IIS.

Can you tell me why do we need this EnsureBinAssembliesLoaded() and can you tell me which assemblies are the really needed ones?

This is the offending code:

Directory.GetFiles(binFolder, ".dll")
.Union(Directory.GetFiles(binFolder, "
.exe"))
.ToList()
.ForEach(domain.EnsureAssemblyIsLoaded);

Can you tell me which assemblies are really required?

@ltoshev
Copy link
Author

ltoshev commented Sep 17, 2013

I have modified the code locally to work like this:

public static AppDomain EnsureBinAssembliesLoaded(this AppDomain domain, IList references) {
....

//Directory.GetFiles(binFolder, ".dll")
// .Union(Directory.GetFiles(binFolder, "
.exe"))
// .ToList()
// .ForEach(domain.EnsureAssemblyIsLoaded);

references.Where(x => x.EndsWith(".dll") && !x.EndsWith("*.dll")).Select(x => Path.Combine(binFolder, x)).ToList().ForEach(domain.EnsureAssemblyIsLoaded);

....

}

@jlamfers
Copy link
Owner

The method EnsureBinAssembliesLoaded() is there to preload assemblies (only in case wildcards are used) to be able to find the maximum set of full reference names, by iterating the loaded assemblies at the current domain afterwards. All these references are passed to the template compiler so that you will not receive complains about missing references. The assumption being made here is that any needed custom assembly is at the bin folder, so that you do not need to worry about referencing your custom assemblies.

In your case apparently this approach is not desirable. Anyway, you always can configure custom references without using the wildcard references at your RazorMachine configuration. If you want to configure these in code (or if you only want to use the minimum required default references without the wildcards) you could do something like:

 var rm = new RazorMachine(references: new RazorConfig().References.Where(r => !r.Contains("*")), replaceReferences: true);

The flag replaceReferences is needed to indicate that the passed references must fully replace the present references, else the passed references would be merged with the present collection.

@jlamfers
Copy link
Owner

I just added an optional argument (default true) at the RazorConfig constructor: allowWildcardReferences. Use argument false for not allowing (and using) any wild card reference for the corresponding instance.

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