using Microsoft.IdentityModel.Tokens; using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.Bus; using Sarand.Net.Standard.Base.Utils; using Saxonite.Net.Standard.Base.App; using Saxonite.Net.Standard.Base.Bus; using Saxonite.Net.Standard.Base.Consoles; using System; using System.Collections.Generic; using System.Text; namespace Saxonite.Net.Core.Web.Base.Consoles { //======================================================================= public abstract class SaxDataCacheConsole_Web : SaxDataCacheConsole { //------------------------------------------------------------------- // Data members. private class DataMembers { public SaxInternals internals; } private DataMembers data = new DataMembers(); //------------------------------------------------------------------- // Protected construction. protected SaxDataCacheConsole_Web(SaxSessionContext sessionContext) : base(sessionContext) { data.internals = new SaxInternals(sessionContext, false); } protected override void Dispose(bool disposing) { if (disposing) { data.internals.Dispose(); } base.Dispose(disposing); } //------------------------------------------------------------------- // Utilities. protected abstract void ForceRefresh(); public override void PopulateCachedDataToInternals(SaxInternals internals) { if (regionsData.regionDataMap == null) ForceRefresh(); // Regions. List activeRegionDataList = new List(); lock (regionsData) activeRegionDataList.AddRange(regionsData.activeRegionDataList); internals.PopulateRegionCache(activeRegionDataList); // Sports. List activeSportDataList = new List(); lock (sportsData) activeSportDataList.AddRange(sportsData.activeSportDataList); internals.PopulateSportCache(activeSportDataList); } //------------------------------------------------------------------- // Regions. public bool RegionsSupported { get; protected set; } = false; private class RegionsData { public Dictionary regionDataMap = null; public List activeRegionDataList = null; } private readonly RegionsData regionsData = new RegionsData(); public override List GetActiveRegions() { String fn = GetType().Name + ".ActiveRegions"; if (!RegionsSupported) throw new NotSupportedException(fn + " Regions not supported."); List activeRegions = new List(); List activeRegionDataList = new List(); if (regionsData.regionDataMap == null) ForceRefresh(); lock (regionsData) { if (regionsData.regionDataMap == null) throw new NotSupportedException(fn + " Regions not populated."); activeRegionDataList.AddRange(regionsData.activeRegionDataList); } foreach (SaxRegion.Data regionData in activeRegionDataList) activeRegions.Add(GetRegion(regionData)); return activeRegions; } protected void RefreshRegions() { String fn = GetType().Name + ".RefreshRegions"; if (!RegionsSupported) throw new NotSupportedException(fn + " Regions not supported."); SaLogger.Info(fn + " START.", false); DateTime startedAt = DateTime.Now; // Refreshed lists will be populated in isolation and then used to instantaneously replace the cache lists. Dictionary newRegionDataMap = new Dictionary(); List newActiveRegionDataList = new List(); // Query Regions to replace cache. SaxRegion.Params prmRegion = new SaxRegion.Params(); prmRegion.StatusCat = SaxRegion.StatusCat.NotDeleted; foreach (SaxRegion region in data.internals.ReferenceMgr.GetRegionList(prmRegion)) { // Only interested in retaining the Data objects. newRegionDataMap[region.Id] = region.GetData(); region.Dispose(); } // Populate replacement list of active regions. foreach (SaxRegion.Data regionData in newRegionDataMap.GetValues()) { if (IsRegionActive(newRegionDataMap, regionData)) newActiveRegionDataList.Add(regionData.Clone()); } // Replace the list of Regions. lock (regionsData) { // Assign the refreshed regions and active regions. // NB The old regions don't need to be disposed as they are SaxRegion.Data objects. regionsData.regionDataMap = newRegionDataMap; regionsData.activeRegionDataList = newActiveRegionDataList; } SaLogger.Info(fn + " END. Regions found: " + regionsData.regionDataMap.Count + ". Elapsed: " + DateUtil.FormatNumberOfSeconds((DateTime.Now - startedAt).TotalSeconds), true); } private static bool IsRegionActive(Dictionary regionDataMap, SaxRegion.Data regionData) { if (regionData == null) return false; if (!regionData.IsStatusActive) return false; if (SysId.IsValid(regionData.RegionIdParent)) return IsRegionActive(regionDataMap, regionDataMap.GetValue(regionData.RegionIdParent, null)); return true; } private SaxRegion GetRegion(SaxRegion.Data regionData) { if (regionData == null) return null; SaxRegion region = data.internals.ReferenceMgr.CreateRegion(); region.SetData(regionData); return region; } //------------------------------------------------------------------- // Sports. public bool SportsSupported { get; protected set; } = false; private class SportsData { public Dictionary sportDataMap = null; public List activeSportDataList = null; } private readonly SportsData sportsData = new SportsData(); public override List GetActiveSports() { String fn = GetType().Name + ".ActiveSports"; if (!SportsSupported) throw new NotSupportedException(fn + " Sports not supported."); List activeSports = new List(); List activeSportDataList = new List(); if (sportsData.sportDataMap == null) ForceRefresh(); lock (sportsData) { if (sportsData.sportDataMap == null) throw new NotSupportedException(fn + " Sports not populated."); activeSportDataList.AddRange(sportsData.activeSportDataList); } foreach (SaxSport.Data sportData in activeSportDataList) activeSports.Add(GetSport(sportData)); return activeSports; } protected void RefreshSports() { String fn = GetType().Name + ".RefreshSports"; if (!SportsSupported) throw new NotSupportedException(fn + " Sports not supported."); SaLogger.Info(fn + " START.", false); DateTime startedAt = DateTime.Now; // Refreshed lists will be populated in isolation and then used to instantaneously replace the cache lists. Dictionary newSportDataMap = new Dictionary(); List newActiveSportDataList = new List(); // Query Sports to replace cache. SaxSport.Params prmSport = new SaxSport.Params(); prmSport.StatusCat = SaxSport.StatusCat.NotDeleted; foreach (SaxSport sport in data.internals.ReferenceMgr.GetSportList(prmSport)) { // Only interested in retaining the Data objects. newSportDataMap[sport.Id] = sport.GetData(); sport.Dispose(); } // Populate replacement list of active sports. foreach (SaxSport.Data sportData in newSportDataMap.GetValues()) { if (IsSportActive(newSportDataMap, sportData)) newActiveSportDataList.Add(sportData.Clone()); } // Replace the list of Sports. lock (sportsData) { // Assign the refreshed sports and active sports. // NB The old sports don't need to be disposed as they are SaxSport.Data objects. sportsData.sportDataMap = newSportDataMap; sportsData.activeSportDataList = newActiveSportDataList; } SaLogger.Info(fn + " END. Sports found: " + sportsData.sportDataMap.Count + ". Elapsed: " + DateUtil.FormatNumberOfSeconds((DateTime.Now - startedAt).TotalSeconds), true); } private static bool IsSportActive(Dictionary sportDataMap, SaxSport.Data sportData) { if (sportData == null) return false; if (!sportData.IsStatusActive) return false; return true; } private SaxSport GetSport(SaxSport.Data sportData) { if (sportData == null) return null; SaxSport sport = data.internals.ReferenceMgr.CreateSport(); sport.SetData(sportData); return sport; } //------------------------------------------------------------------- } //======================================================================= }