예제 #1
0
        public static void ShutdownAllBackgroundThreads()
        {
            IsShuttingDown = true;
            CTS.Cancel();

            SessionLog.Info("Shutting down");

            Log.Information("Shutting down workers...");
            WorkSpawner.Shutdown();
            Log.Information("Shutting down counter monitor...");
            SignalR.HomeDashboard.DotNetCoreCounterListener.Instance?.Stop();
            Log.Information("Shutting down stats counter...");
            Performance.StatsDB.Shutdown();
            Log.Information("Shutting down common notifications...");
            Hubs.CommonNotificationThread.Instance?.Shutdown();
            Log.Information("Shutting down exception logger...");
            ExceptionLogger.Instance?.Shutdown();
            Log.Information("Shutting down background thread plugins...");
            BackgroundThreadPluginManager.Instance?.Shutdown();


            Log.Information("Shutting down real-time tracker...");
            RealtimeTrackerThread.Instance.Shutdown();
            Log.Information("Shutting down data collector...");
            DataCollectorThread.Instance.Shutdown();

            Log.Information("Shutting jsDAL health monitor...");
            jsDALHealthMonitorThread.Instance.Shutdown();

            Log.Information("Shutting down session log...");
            SessionLog.Shutdown();
        }
예제 #2
0
        private void ParseAndLoadPluginAssembly(AssemblyLoadContext asmCtx, Assembly assembly, string inlineEntryId = null)
        {
            if (ParsePluginAssembly(assembly, out var pluginInfoList, out var errorList, checkForConflict: true))
            {
                foreach (var pluginInfo in pluginInfoList)
                {
                    SessionLog.Info($"{(inlineEntryId != null ? "(Inline) " : "")}Plugin '{pluginInfo.Name}' ({pluginInfo.Guid}) found in assembly: {assembly.FullName}");

                    var existing = PluginAssemblies.FirstOrDefault(a => a.Assembly == assembly);

                    if (existing == null)
                    {
                        var newPA = new PluginAssembly(asmCtx, assembly, inlineEntryId);
                        newPA.AddPlugin(pluginInfo);
                        _pluginAssemblies.Add(newPA);
                    }
                    else
                    {
                        existing.AddPlugin(pluginInfo);
                    }
                }
            }
        }
예제 #3
0
        private void CompileCodeIntoAssemblyContext(InlineModuleManifestEntry inlineEntry, string code)
        {
            var ctxName    = $"Inline Plugin Context {++_asmCtxCounter}";
            var pluginPath = Path.GetFullPath("plugins");
            var asmCtx     = new PluginAssemblyLoadContext(pluginPath, ctxName, true /*enable unloading*/);

            ASM_CTXES.Add(asmCtx);

            SessionLog.Info($"Created {ctxName} for {inlineEntry.Name}".PadRight(35));

            var assemblyBytes = CSharpCompilerHelper.CompileIntoAssembly(inlineEntry.Name, code, out var problems);

            if ((problems != null && problems.Count == 0))
            {
                Assembly assembly = null;

                try
                {
                    using (var ms = new MemoryStream(assemblyBytes))
                    {
                        assembly = asmCtx.LoadFromStream(ms);

                        ParseAndLoadPluginAssembly(asmCtx, assembly, inlineEntry.Id);
                    }
                }
                catch (Exception ee)
                {
                    SessionLog.Error($"Failed to load inline plugin assembly '{assembly?.FullName}' {inlineEntry.Name}/{inlineEntry.Id}. See exception that follows.");
                    SessionLog.Exception(ee);
                }
            }
            else
            {
                SessionLog.Error($"Inline plugin {inlineEntry.Name} ({inlineEntry.Id}) failed to compile with the following error(s): {string.Join(", ", problems)}");
            }
        }
예제 #4
0
        public async Task InitAsync()
        {
            // load from plugin directory
            try
            {
                // AppDomain.CurrentDomain.AssemblyResolve += (sender, e) =>
                // {
                //     try
                //     {
                //         var asmName = new AssemblyName(e.Name);
                //         var requestingLocation = e.RequestingAssembly.Location;
                //         var requestingDir = Path.GetDirectoryName(requestingLocation);

                //         // look for a dll in the same location as the requesting assembly
                //         var path = Path.Combine(requestingDir, asmName.Name + ".dll");

                //         if (!File.Exists(path)) return null;

                //         Assembly.LoadFrom(path);

                //         return null;
                //     }
                //     catch
                //     {
                //         return null;
                //     }
                // };

                var pluginPath = Path.GetFullPath("plugins");

                if (Directory.Exists("./plugins"))
                {
                    var dllCollection = Directory.EnumerateFiles("plugins", "*.dll", SearchOption.TopDirectoryOnly);

                    foreach (var dllPath in dllCollection)
                    {
                        // skip jsdal-plugin base
                        if (dllPath.Equals("plugins\\jsdal-plugin.dll", StringComparison.OrdinalIgnoreCase))
                        {
                            continue;
                        }

                        try
                        {
                            var ctxName = $"Plugin Context {++_asmCtxCounter}";
                            var asmCtx  = new PluginAssemblyLoadContext(pluginPath, ctxName, true /*enable unloading*/);
                            ASM_CTXES.Add(asmCtx);
                            SessionLog.Info($"Created {ctxName} for {dllPath}".PadRight(35));


                            var dllFullPath    = Path.GetFullPath(dllPath);
                            var pluginAssembly = asmCtx.LoadFromAssemblyPath(dllFullPath);

                            ParseAndLoadPluginAssembly(asmCtx, pluginAssembly, null);
                        }
                        catch (Exception ee)
                        {
                            SessionLog.Error("Failed to load plugin DLL '{0}'. See exception that follows.", dllPath);
                            SessionLog.Exception(ee);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                SessionLog.Exception(ex);
            }

            // load inline assemblies
            try
            {
                foreach (var inlineEntry in InlineModuleManifest.Instance.Entries)
                {
                    var sourcePath = Path.Combine(InlinePluginSourcePath, inlineEntry.Id);

                    if (File.Exists(sourcePath))
                    {
                        var code = await File.ReadAllTextAsync(sourcePath);

                        CompileCodeIntoAssemblyContext(inlineEntry, code);
                    }
                    else
                    {
                        SessionLog.Error($"Inline module {inlineEntry.Name} not found at '{sourcePath}'");
                    }
                }
            }
            catch (Exception ex)
            {
                SessionLog.Exception(ex);
            }

            // init server-wide types
            // try
            // {
            //     InitServerWidePlugins();
            // }
            // catch (Exception ex)
            // {
            //     SessionLog.Exception(ex);
            // }
        }
예제 #5
0
 private void OnUnloading(AssemblyLoadContext ctx)
 {
     SessionLog.Info($"Unloading assembly context {ctx.Name}");
     PluginLoader.RemoveAssemblyContextRef(this);
 }