From 700b6e2d68203029918b961f891e42f5581f2acc Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Wed, 4 Nov 2020 08:10:21 -0500 Subject: [PATCH] optimize performance when running on WebAssembly by caching assembly payload that needs to be served to new clients --- .../Controllers/InstallationController.cs | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/Oqtane.Server/Controllers/InstallationController.cs b/Oqtane.Server/Controllers/InstallationController.cs index 39b00b2f..7aaf537c 100644 --- a/Oqtane.Server/Controllers/InstallationController.cs +++ b/Oqtane.Server/Controllers/InstallationController.cs @@ -11,6 +11,7 @@ using Oqtane.Models; using Oqtane.Modules; using Oqtane.Shared; using Oqtane.Themes; +using Microsoft.Extensions.Caching.Memory; namespace Oqtane.Controllers { @@ -21,13 +22,15 @@ namespace Oqtane.Controllers private readonly IInstallationManager _installationManager; private readonly IDatabaseManager _databaseManager; private readonly ILocalizationManager _localizationManager; + private readonly IMemoryCache _cache; - public InstallationController(IConfigurationRoot config, IInstallationManager installationManager, IDatabaseManager databaseManager, ILocalizationManager localizationManager) + public InstallationController(IConfigurationRoot config, IInstallationManager installationManager, IDatabaseManager databaseManager, ILocalizationManager localizationManager, IMemoryCache cache) { _config = config; _installationManager = installationManager; _databaseManager = databaseManager; _localizationManager = localizationManager; + _cache = cache; } // POST api/ @@ -70,6 +73,19 @@ namespace Oqtane.Controllers public IActionResult Load() { if (_config.GetSection("Runtime").Value == "WebAssembly") + { + return File(GetAssemblies(), System.Net.Mime.MediaTypeNames.Application.Octet, "oqtane.zip"); + } + else + { + HttpContext.Response.StatusCode = 401; + return null; + } + } + + private byte[] GetAssemblies() + { + return _cache.GetOrCreate("assemblies", entry => { // get list of assemblies which should be downloaded to client var assemblies = AppDomain.CurrentDomain.GetOqtaneClientAssemblies(); @@ -85,7 +101,7 @@ namespace Oqtane.Controllers continue; } - if(Directory.Exists(assembliesFolderPath)) + if (Directory.Exists(assembliesFolderPath)) { foreach (var resourceFile in Directory.EnumerateFiles(assembliesFolderPath)) { @@ -120,42 +136,32 @@ namespace Oqtane.Controllers } // create zip file containing assemblies and debug symbols - byte[] zipfile; using (var memoryStream = new MemoryStream()) { using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true)) { - ZipArchiveEntry entry; foreach (string file in list) { - entry = archive.CreateEntry(file + ".dll"); using (var filestream = new FileStream(Path.Combine(binFolder, file + ".dll"), FileMode.Open, FileAccess.Read)) - using (var entrystream = entry.Open()) + using (var entrystream = archive.CreateEntry(file + ".dll").Open()) { filestream.CopyTo(entrystream); } - // include debug symbols ( we may want to consider restricting this to only host users or when running in debug mode for performance ) + // include debug symbols if (System.IO.File.Exists(Path.Combine(binFolder, file + ".pdb"))) { - entry = archive.CreateEntry(file + ".pdb"); using (var filestream = new FileStream(Path.Combine(binFolder, file + ".pdb"), FileMode.Open, FileAccess.Read)) - using (var entrystream = entry.Open()) + using (var entrystream = archive.CreateEntry(file + ".pdb").Open()) { filestream.CopyTo(entrystream); } } } } - zipfile = memoryStream.ToArray(); + return memoryStream.ToArray(); } - return File(zipfile, System.Net.Mime.MediaTypeNames.Application.Octet, "oqtane.zip"); - } - else - { - HttpContext.Response.StatusCode = 401; - return null; - } + }); } } }