RuntimeCache.cs (4107B)
1 using MatrixRoomUtils.Core.Extensions; 2 using MatrixRoomUtils.Core.Responses; 3 4 namespace MatrixRoomUtils.Core; 5 6 public class RuntimeCache 7 { 8 public static bool WasLoaded = false; 9 public static string? LastUsedToken { get; set; } 10 public static AuthenticatedHomeServer CurrentHomeServer { get; set; } 11 public static Dictionary<string, UserInfo> LoginSessions { get; set; } = new(); 12 13 public static Dictionary<string, HomeServerResolutionResult> HomeserverResolutionCache { get; set; } = new(); 14 // public static Dictionary<string, (DateTime cachedAt, ProfileResponse response)> ProfileCache { get; set; } = new(); 15 16 public static Dictionary<string, ObjectCache<object>> GenericResponseCache { get; set; } = new(); 17 18 public static Action Save { get; set; } = () => 19 { 20 Console.WriteLine("RuntimeCache.Save() was called, but no callback was set!"); 21 }; 22 public static Action<string, object> SaveObject { get; set; } = (key, value) => 23 { 24 Console.WriteLine($"RuntimeCache.SaveObject({key}, {value}) was called, but no callback was set!"); 25 }; 26 27 static RuntimeCache() 28 { 29 Task.Run(async () => 30 { 31 while (true) 32 { 33 await Task.Delay(1000); 34 foreach (var (key, value) in RuntimeCache.GenericResponseCache) 35 { 36 SaveObject("rory.matrixroomutils.generic_cache:" + key, value); 37 } 38 } 39 }); 40 } 41 } 42 43 44 public class UserInfo 45 { 46 public ProfileResponse Profile { get; set; } = new(); 47 public LoginResponse LoginResponse { get; set; } 48 public string AccessToken { get => LoginResponse.AccessToken; } 49 } 50 51 public class HomeServerResolutionResult 52 { 53 public string Result { get; set; } 54 public DateTime ResolutionTime { get; set; } 55 } 56 public class ObjectCache<T> where T : class 57 { 58 public Dictionary<string, GenericResult<T>> Cache { get; set; } = new(); 59 public string Name { get; set; } = null!; 60 public GenericResult<T> this[string key] 61 { 62 get 63 { 64 if (Cache.ContainsKey(key)) 65 { 66 // Console.WriteLine($"cache.get({key}): hit"); 67 // Console.WriteLine($"Found item in cache: {key} - {Cache[key].Result.ToJson(indent: false)}"); 68 if(Cache[key].ExpiryTime < DateTime.Now) 69 Console.WriteLine($"WARNING: item {key} in cache {Name} expired at {Cache[key].ExpiryTime}:\n{Cache[key].Result.ToJson(indent: false)}"); 70 return Cache[key]; 71 72 } 73 Console.WriteLine($"cache.get({key}): miss"); 74 return null; 75 } 76 set 77 { 78 Cache[key] = value; 79 // Console.WriteLine($"set({key}) = {Cache[key].Result.ToJson(indent:false)}"); 80 // Console.WriteLine($"new_state: {this.ToJson(indent:false)}"); 81 // Console.WriteLine($"New item in cache: {key} - {Cache[key].Result.ToJson(indent: false)}"); 82 // Console.Error.WriteLine("Full cache: " + Cache.ToJson()); 83 } 84 } 85 86 public ObjectCache() 87 { 88 //expiry timer 89 Task.Run(async () => 90 { 91 while (true) 92 { 93 await Task.Delay(1000); 94 foreach (var x in Cache.Where(x => x.Value.ExpiryTime < DateTime.Now).OrderBy(x => x.Value.ExpiryTime).Take(15).ToList()) 95 { 96 // Console.WriteLine($"Removing {x.Key} from cache"); 97 Cache.Remove(x.Key); 98 } 99 //RuntimeCache.SaveObject("rory.matrixroomutils.generic_cache:" + Name, this); 100 } 101 }); 102 } 103 104 public bool ContainsKey(string key) => Cache.ContainsKey(key); 105 } 106 public class GenericResult<T> 107 { 108 public T? Result { get; set; } 109 public DateTime? ExpiryTime { get; set; } = DateTime.Now; 110 111 public GenericResult() 112 { 113 //expiry timer 114 115 } 116 public GenericResult(T? result, DateTime? expiryTime = null) : this() 117 { 118 Result = result; 119 ExpiryTime = expiryTime; 120 } 121 }