From 93dbde28188b9d8281157dfd979a9448e7e0c4ed Mon Sep 17 00:00:00 2001 From: Madpeter <57852827+Madpeterz@users.noreply.github.com> Date: Fri, 3 Oct 2025 21:56:33 +0100 Subject: [PATCH] Improve inventory preload tracking and reporting Refactored inventory preload logic to track both folder and item counts, and updated related command and service methods to report these values. Changed folder loading to be asynchronous and recursive, improved reporting format, and fixed root folder naming in inventory contents command. --- SecondBotEvents/Commands/Inventory.cs | 8 +- SecondBotEvents/Services/DataStoreService.cs | 78 ++++++++++++-------- 2 files changed, 52 insertions(+), 34 deletions(-) diff --git a/SecondBotEvents/Commands/Inventory.cs b/SecondBotEvents/Commands/Inventory.cs index 7f079c8..1c7c213 100644 --- a/SecondBotEvents/Commands/Inventory.cs +++ b/SecondBotEvents/Commands/Inventory.cs @@ -1092,11 +1092,11 @@ namespace SecondBotEvents.Commands } [About("Requests the number of folders preloaded")] - [ReturnHints("number of preloaded folders")] + [ReturnHints("folders:X,items:X as a string")] [CmdTypeGet()] - public object InventoryPreloadFolderCount() + public object InventoryPreloadCount() { - return BasicReply(master.DataStoreService.GetPreloadedFolderCount().ToString()); + return BasicReply("folders:"+ master.DataStoreService.GetPreloadedFolderCount().ToString()+",items:"+master.DataStoreService.GetPreloadedItemCount().ToString()); } @@ -1111,7 +1111,7 @@ namespace SecondBotEvents.Commands [CmdTypeGet()] public object InventoryContentsCatched() { - InventoryNodeEntry root = LoadInventoryNode(GetClient().Inventory.Store.RootFolder.UUID,"root"); + InventoryNodeEntry root = LoadInventoryNode(GetClient().Inventory.Store.RootFolder.UUID,"My Inventory"); return BasicReply(JsonConvert.SerializeObject(root)); } diff --git a/SecondBotEvents/Services/DataStoreService.cs b/SecondBotEvents/Services/DataStoreService.cs index b2959c9..06d2b36 100644 --- a/SecondBotEvents/Services/DataStoreService.cs +++ b/SecondBotEvents/Services/DataStoreService.cs @@ -223,11 +223,13 @@ namespace SecondBotEvents.Services return "Loading "+preloadingFolders.Count()+" inventory folders"; } } + int sum = commandHistories.Count + KeyValueStoreLastUsed.Count + KeyValueStore.Count + chatWindowsOwner.Count + chatWindowsIsGroup.Count + chatWindowsUnread.Count + chatWindows.Count + localChatHistory.Count + groupRoles.Count + groupMembers.Count + groupsKey2Name.Count + avatarsName2Key.Count + avprops.Count; - return sum.ToString(); + string returndat = "Total entrys: "+sum.ToString()+", Preloaded inventory: "+preloadFolderCount.ToString()+" folders and "+preloadItemCount.ToString()+" items"; + return returndat; } public void AddCommandToHistory(bool status, string command, string[] args, string results=null) @@ -1017,21 +1019,26 @@ namespace SecondBotEvents.Services if(myConfig.GetPrefetchInventory() == true) { preloadDone = false; - Task.Run(() => + _ = Task.Run(async () => { - preloadFolder("root", GetClient().Inventory.Store.RootFolder.UUID, myConfig.GetPrefetchInventoryDepth(), 0); + await preloadFolder("root", GetClient().Inventory.Store.RootFolder.UUID, myConfig.GetPrefetchInventoryDepth(), 0); }); } } protected List preloadingFolders = []; protected bool preloadDone = true; - public int preloadFolderCount = 0; + protected int preloadFolderCount = 0; + protected int preloadItemCount = 0; public int GetPreloadedFolderCount() { return preloadFolderCount; } + public int GetPreloadedItemCount() + { + return preloadItemCount; + } public bool preloadInventoryReady() { if(myConfig.GetPrefetchInventory() == false) @@ -1049,38 +1056,49 @@ namespace SecondBotEvents.Services return true; } - protected async void preloadFolder(string foldername,UUID folder, int maxDepth, int currentDepth) + protected async Task preloadFolder(string foldername,UUID folder, int maxDepth, int currentDepth) { - await Task.Run(async () => + lock (preloadingFolders) { - lock (preloadingFolders) + preloadingFolders.Add(folder.Guid.ToString()); + } + + await Task.Delay(_delayRandom.Next(500, 1251) * (currentDepth+1)); + + List foldercontents = GetClient().Inventory.FolderContents( + folder, + GetClient().Self.AgentID, true, true, + InventorySortOrder.ByDate, TimeSpan.FromSeconds(30), false); + + List subFolderTasks = []; + + foreach (InventoryBase item in foldercontents) + { + string entrytype = item.GetType().Name.Replace("Inventory", ""); + if (entrytype != "Folder") { - preloadingFolders.Add(folder.Guid.ToString()); + Interlocked.Increment(ref preloadItemCount); + continue; } - await Task.Delay(_delayRandom.Next(500, 1251) * (currentDepth+1)); - List foldercontents = GetClient().Inventory.FolderContents( - GetClient().Inventory.Store.RootFolder.UUID, - GetClient().Self.AgentID, true, true, - InventorySortOrder.ByName, TimeSpan.FromSeconds(30), false); - foreach (InventoryBase item in foldercontents) + if ((currentDepth + 1) > maxDepth) { - string entrytype = item.GetType().Name.Replace("Inventory", ""); - if (entrytype != "Folder") - { - continue; - } - if ((currentDepth + 1) > maxDepth) - { - continue; - } - preloadFolder(item.Name, item.UUID, maxDepth, currentDepth + 1); + continue; } - lock (preloadingFolders) - { - preloadFolderCount++; - preloadingFolders.Remove(folder.Guid.ToString()); - } - }); + // Start loading subfolder but don't wait for it yet + subFolderTasks.Add(preloadFolder(item.Name, item.UUID, maxDepth, currentDepth + 1)); + } + + // Wait for all subfolder tasks to complete + if (subFolderTasks.Count > 0) + { + await Task.WhenAll(subFolderTasks); + } + + lock (preloadingFolders) + { + preloadFolderCount++; + preloadingFolders.Remove(folder.Guid.ToString()); + } } readonly string[] hard_blocked_agents = ["secondlife", "second life"];