using MatrixRoomUtils.Core.Extensions; using MatrixRoomUtils.Core.Responses; namespace MatrixRoomUtils.Core; public class RuntimeCache { public static bool WasLoaded = false; static RuntimeCache() => Task.Run(async () => { while (true) { await Task.Delay(1000); foreach (var (key, value) in GenericResponseCache) if (value.Cache.Any()) SaveObject("rory.matrixroomutils.generic_cache:" + key, value); else RemoveObject("rory.matrixroomutils.generic_cache:" + key); } }); public static string? LastUsedToken { get; set; } public static AuthenticatedHomeServer CurrentHomeServer { get; set; } public static Dictionary LoginSessions { get; set; } = new(); public static Dictionary HomeserverResolutionCache { get; set; } = new(); // public static Dictionary ProfileCache { get; set; } = new(); public static Dictionary> GenericResponseCache { get; set; } = new(); public static Action Save { get; set; } = () => { Console.WriteLine("RuntimeCache.Save() was called, but no callback was set!"); }; public static Action SaveObject { get; set; } = (key, value) => { Console.WriteLine($"RuntimeCache.SaveObject({key}, {value}) was called, but no callback was set!"); }; public static Action RemoveObject { get; set; } = key => { Console.WriteLine($"RuntimeCache.RemoveObject({key}) was called, but no callback was set!"); }; } public class UserInfo { public ProfileResponse Profile { get; set; } = new(); public LoginResponse LoginResponse { get; set; } public string AccessToken => LoginResponse.AccessToken; } public class HomeServerResolutionResult { public string Result { get; set; } public DateTime ResolutionTime { get; set; } } public class ObjectCache where T : class { public ObjectCache() => //expiry timer Task.Run(async () => { while (Cache.Any()) { await Task.Delay(1000); foreach (var x in Cache.Where(x => x.Value.ExpiryTime < DateTime.Now).OrderBy(x => x.Value.ExpiryTime).Take(15).ToList()) // Console.WriteLine($"Removing {x.Key} from cache"); Cache.Remove(x.Key); //RuntimeCache.SaveObject("rory.matrixroomutils.generic_cache:" + Name, this); } }); public Dictionary> Cache { get; set; } = new(); public string Name { get; set; } = null!; public GenericResult this[string key] { get { if (Cache.ContainsKey(key)) { // Console.WriteLine($"cache.get({key}): hit"); // Console.WriteLine($"Found item in cache: {key} - {Cache[key].Result.ToJson(indent: false)}"); if (Cache[key].ExpiryTime < DateTime.Now) Console.WriteLine($"WARNING: item {key} in cache {Name} expired at {Cache[key].ExpiryTime}:\n{Cache[key].Result.ToJson(false)}"); return Cache[key]; } Console.WriteLine($"cache.get({key}): miss"); return null; } set => Cache[key] = value; // Console.WriteLine($"set({key}) = {Cache[key].Result.ToJson(indent:false)}"); // Console.WriteLine($"new_state: {this.ToJson(indent:false)}"); // Console.WriteLine($"New item in cache: {key} - {Cache[key].Result.ToJson(indent: false)}"); // Console.Error.WriteLine("Full cache: " + Cache.ToJson()); } public bool ContainsKey(string key) => Cache.ContainsKey(key); } public class GenericResult { public GenericResult() { //expiry timer } public GenericResult(T? result, DateTime? expiryTime = null) : this() { Result = result; ExpiryTime = expiryTime; } public T? Result { get; set; } public DateTime? ExpiryTime { get; set; } = DateTime.Now; }