Open Seabizkit opened 2 years ago
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.
Tagging subscribers to this area: @vitek-karas, @agocke, @vsadov See info in area-owners.md if you want to be subscribed.
Author: | Seabizkit |
---|---|
Assignees: | - |
Labels: | `area-AssemblyLoader-coreclr`, `untriaged` |
Milestone: | - |
update i added
finally {
loadContext.Unload();
}
and it appears to be working... like surely not? what is going on here, are some how required to call unload in release..?
PS - before i was not calling Unload(); at all as i was like when it goes out the scope the GC will handle it
It's hard to tell for sure without seeing everything, but based on your description I would guess that it has to do with lifetime of local variables. The runtime is free to unload the context if there are no references to it anywhere. If the only reference is in local variable I could see the JIT releasing the reference at different spots between Debug/Release. It would also explain why adding the finally solves this as that will make sure the local holds onto the context until the end. This is probably a bit more complicated due to the use of async...
You could try to gather a loader trace: https://docs.microsoft.com/en-us/dotnet/core/dependency-loading/collect-details - it might have enough detail to tell the order of things.
Moving this to Future for now since for so far this doesn't look like a bug in the product to me (just complex behavior , which is probably by design for now).
@vitek-karas i could you access to my private repo, further to this i have a memory leak, trying to diagnose but quite difficult.
I believe the memory leek is because unload is not actually unloading.
would you mind taking a look?
You can try the debugging guide here: https://learn.microsoft.com/en-us/dotnet/standard/assembly/unloadability#debug-unloading-issues It describes some of the tools you can use to figure out what prevents the ALC to unload.
Hi @vitek-karas
So been trying to simplify things so i can try see where things are going wrong.
I have test code ....,to try and test my plugin 'Paradox.Component.EmailPlugin'
[TestMethod]
public async Task TestMethod1Async()
{
var directory = Directory.GetCurrentDirectory();
var scrFolder = "src";
var indexOfSrc = directory.IndexOf(scrFolder);
var srcBaseDirectory = directory.Substring(0, indexOfSrc + scrFolder.Length);
var pluginFolder = Path.Combine(srcBaseDirectory, "_Plugins");
var plugins = Directory.GetDirectories(pluginFolder);
foreach (var item in plugins)
{
var folderName = Path.GetFileName(item);
var fullpath = Path.Combine(item, folderName + ".dll");
var loadContext = new PluginLoadContext(fullpath);
var componentUI = loadContext.GetImplementations<BaseComponentUI>().Single();
var plugin = loadContext.GetImplementations<IParadoxComponent>().Single();
await plugin.ExcuteAsync();
}
}
Paradox.Component.EmailPlugin has no other reference other than the interface project and that project reference no other projects.
the plugin code, I'm registering an IHost inside the plugin so I can get services via ServiceProvider
public class Plugin : IParadoxComponent
{
public Guid IdentifferName => new Guid("0EFC02C1-E923-4183-B98F-1562237BA62B");
public string Name => "Paradox email";
public string ShortName => "Email";
public string Author => "Paradox";
public string Description => "Create and send basic email.";
public string ImageIcon => "fa-envelope";
public string ImageUrl => "";
private Action<HostBuilderContext, IServiceCollection> SetupServiceNew()
{
Action<HostBuilderContext, IServiceCollection> configureDelegate = (hostBuilder, services) =>
{
var config = hostBuilder.Configuration;
services.AddScoped<IEmailSender, EmailSender>();
var provider = new FileExtensionContentTypeProvider();
services.AddSingleton<IMimeMappingHelper>(new MimeMappingHelper(provider));
};
return configureDelegate;
}
public async Task ExcuteAsync()
{
using (var host = DIBuilder.Start(SetupServiceNew()))
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
var emailSender = services.GetRequiredService<IEmailSender>();
var mappingHelper = services.GetRequiredService<IMimeMappingHelper>();
var instance = new ComponentProvider(emailSender, mappingHelper);
}
}
}
DIBuilder code
public class DIBuilder
{
private const string DefaultEnviroementName = "Development";
public static IHost Start(Action<HostBuilderContext, IServiceCollection> configureDelegate)
{
try
{
var host = CreateHostBuilder(configureDelegate).Build();
return host;
}
catch (Exception ex)
{
throw;
}
}
public static IHostBuilder CreateHostBuilder(Action<HostBuilderContext, IServiceCollection> configureDelegate, string[] args = null)
{
return Host.CreateDefaultBuilder(args)
.ConfigureHostConfiguration(configHost =>
{
//var global = Directory.GetCurrentDirectory();
string LocalPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var environment = Environment.GetEnvironmentVariable("ASPNET_ENVIROMENT") ??
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ??
DefaultEnviroementName;
configHost
.SetBasePath(LocalPath)
.AddJsonFile($"appsettings.json", true, reloadOnChange: false)
.AddJsonFile($"appsettings.{environment}.json", optional: true, reloadOnChange: false);
// .AddDatabaseConfiguration();
})
.ConfigureServices(configureDelegate);
}
}
An exception is being thrown: Could not load file or assembly 'System.Diagnostics.EventLog, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified.
this make non sense to me, could you assit the files inside of the plugin folder
It's hard to answer this without more details. I would:
Description
My code fails to run when deployed, seem to work when running through VS
Details I have a plugin which im using AssemblyLoadContext and have marked as
isCollectible: true
It all seem to work, but does not work when deployed.every project is on .net 6 to ensure no other variables when trying to debug this AssemblyLoadContext and usage.
-Web ---- Hosts - BackgroundProcessor -----------Kicks off Plugin code
Only code share with plugin is Component.Facade Lib which has no other references.(it works in VS).
Fails when trying to run plugin code. I deploy this with self container and targeting Arm32 Release mode, a PI4 with raspberry OS (32bit)
update: confirmed works in Debug but not Release in VS
Exception message: Could not load file or assembly 'Microsoft.Extensions.Hosting.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. An operation is not legal in the current state. (0x80131509)
Exception inner: Could not load file or assembly 'Microsoft.Extensions.Hosting.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. An operation is not legal in the current state. (0x80131509) AssemblyLoadContext is unloading or was already unloaded.
Plugin has:
my guess the above is this is the issue, but how are you meant to handle this?
the class which kicks off the plugin stuff is TaskComponentProcessor
inside there I have
i then call
code for PluginLoadContext
Statcktrace:
Reproduction Steps
It work when running through VS so, not sure how to debug, Open to suggestions.
in my plugin i have which i used to return a IServiceProvider so i can register any service the plugin may need.
Expected behavior
Should not through exception, or at least help with how to fix it.
Actual behavior
fails when deployed, giving the exception
Exception message: Could not load file or assembly 'Microsoft.Extensions.Hosting.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. An operation is not legal in the current state. (0x80131509)
Exception inner: Could not load file or assembly 'Microsoft.Extensions.Hosting.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. An operation is not legal in the current state. (0x80131509) AssemblyLoadContext is unloading or was already unloaded.
Regression?
No response
Known Workarounds
No response
Configuration
No response
Other information
No response