Antaris / RazorEngine

Open source templating engine based on Microsoft's Razor parsing engine
http://antaris.github.io/RazorEngine
Other
2.13k stars 576 forks source link

Temp folder cleanup options #277

Open hclinton opened 9 years ago

hclinton commented 9 years ago

I have an issue with tens of thousands RazorEngine directories in the temp folder on the CI server. They are generated by integration tests that are executed in parallel. Setting 'DisableTempFileLocking' does not help. Deleting all folders matching RazorEngine_* mask would interfere with parallel tests.

So, is there a way to specify a temp folder to be used by IRazorEngineService instance so that it can be removed programmatically after test has finished? Or maybe some alternative solution?

Thank you for you work!

matthid commented 9 years ago

Setting 'DisableTempFileLocking' does not help

Why not? This should always make RazorEngine cleanup the files afterwards (if you do not crash the runtime). So if there are still files it's probably a bug and a repro would be appreciated. Actually since the latest versions I rarely (never) see RazorEngine folders in the temp folder.

hclinton commented 9 years ago

Wow that was fast! Unfortunately we don't have control over the code that executes a test. Not sure whether they mess up AppDomains, or pool them, or crash the process at the end. We currently don't have control over this. My thinking was that being able to specify temp folder to be used by IRazorEngineService instance may also help for production environments where someone may want to use faster (RAM-based for example) disk for them. Thank you again!

matthid commented 9 years ago

Yeah I kind of agree. It can actually be done by inheriting CSharpDirectCompilerService and overwriting GetTemporaryDirectory, then implement ICompilerServiceFactory (by simply returning your instance) and set that as your CompilerServiceFactory in the configuration.

I would probably accept a PR to simplify this. However I feel like the configuration currently combines a bit too much and should be cleaned up eventually...

dankarmy commented 9 years ago

I can confirm that regardless whether DisableTempFileLocking is set or not, the temp files/folder is not deleted during dispose of the IRazorEngineService - yet I am able to delete the .dll (and any files) in the temp directory myself when the main application is running so I don't think the issue is locking of files.

matthid commented 9 years ago

The files are deleted when the CompilationData instances are disposed (https://github.com/Antaris/RazorEngine/blob/master/src/source/RazorEngine.Core/Compilation/CompilationData.cs). Those are saved as part of ICompiledTemplate.

This means all files should be deleted after the runtime is shutdown properly (the process is non-deterministic as it depends on the garbage collection). So to make it clear: The files will be cleaned up eventually (even when the runtime doesn't exit). However the exact time depends on the garbage collector.

You can however manually step in and dispose the CompilationData instances in your cache implementation. You can then start the process by disposing your own cache implementation or the IRazorEngineService instance.

Edit:

To clarify even more: IRazorEngineService -> (references) ICachingProvider -> ICompiledTemplate -> CompilationData. So it can take a while for the GC to notice that the CompilationData instances can be cleaned up. And you need to make sure to have no references to anything within this chain.