diff --git a/MatrixRoomUtils.Core/Room.cs b/MatrixRoomUtils.Core/Room.cs
index be470fa..3ef6ffa 100644
--- a/MatrixRoomUtils.Core/Room.cs
+++ b/MatrixRoomUtils.Core/Room.cs
@@ -16,17 +16,52 @@ public class Room
public async Task<JsonElement?> GetStateAsync(string type, string state_key="", bool logOnFailure = false)
{
- var url = $"/_matrix/client/r0/rooms/{RoomId}/state";
+ var url = $"/_matrix/client/v3/rooms/{RoomId}/state";
if (!string.IsNullOrEmpty(state_key)) url += $"/{type}/{state_key}";
else if (!string.IsNullOrEmpty(type)) url += $"/{type}";
-
+ var cache_key = "room_states_"+type;
+ if (!RuntimeCache.GenericResponseCache.ContainsKey(cache_key))
+ {
+ Console.WriteLine($"[!!] No cache for {cache_key}, creating...");
+ RuntimeCache.GenericResponseCache.Add(cache_key, new ObjectCache<object?>()
+ {
+ DefaultExpiry = type switch
+ {
+ "m.room.name" => TimeSpan.FromMinutes(15),
+ _ => TimeSpan.FromMinutes(5)
+ }
+ });
+ }
+
+ if (RuntimeCache.GenericResponseCache[cache_key][url] != null)
+ {
+ if(RuntimeCache.GenericResponseCache[cache_key][url].ExpiryTime > DateTime.Now)
+ {
+ Console.WriteLine($"[:3] Found cached state: {RuntimeCache.GenericResponseCache[cache_key][url].Result}");
+ return (JsonElement?)RuntimeCache.GenericResponseCache[cache_key][url].Result;
+ }
+ else
+ {
+ Console.WriteLine($"[!!] Cached state expired at {RuntimeCache.GenericResponseCache[cache_key][url].ExpiryTime}: {RuntimeCache.GenericResponseCache[cache_key][url].Result}");
+ }
+ }
+ else
+ {
+ Console.WriteLine($"[!!] No cached state for {url}");
+ }
+
var res = await _httpClient.GetAsync(url);
if (!res.IsSuccessStatusCode)
{
if(logOnFailure) Console.WriteLine($"{RoomId}/{state_key}/{type} - got status: {res.StatusCode}");
return null;
}
- return await res.Content.ReadFromJsonAsync<JsonElement>();
+ var result = await res.Content.ReadFromJsonAsync<JsonElement>();
+ RuntimeCache.GenericResponseCache[cache_key][url] = new GenericResult<object>()
+ {
+ Result = result
+ };
+ return result;
}
public async Task<string?> GetNameAsync()
{
diff --git a/MatrixRoomUtils.Core/RuntimeCache.cs b/MatrixRoomUtils.Core/RuntimeCache.cs
index 586cf88..affbd94 100644
--- a/MatrixRoomUtils.Core/RuntimeCache.cs
+++ b/MatrixRoomUtils.Core/RuntimeCache.cs
@@ -1,3 +1,7 @@
+using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.JavaScript;
+using System.Xml.Schema;
+using MatrixRoomUtils.Core.Extensions;
using MatrixRoomUtils.Core.Responses;
namespace MatrixRoomUtils.Core;
@@ -11,6 +15,8 @@ public class RuntimeCache
public static Dictionary<string, HomeServerResolutionResult> HomeserverResolutionCache { get; set; } = new();
// public static Dictionary<string, (DateTime cachedAt, ProfileResponse response)> ProfileCache { get; set; } = new();
+
+ public static Dictionary<string, ObjectCache<object>> GenericResponseCache { get; set; } = new();
}
@@ -26,3 +32,54 @@ public class HomeServerResolutionResult
public string Result { get; set; }
public DateTime ResolutionTime { get; set; }
}
+public class ObjectCache<T> where T : class
+{
+ public Dictionary<string, GenericResult<T>> Cache { get; set; } = new();
+ public TimeSpan DefaultExpiry { get; set; } = new(0, 5, 0);
+ public GenericResult<T> this[string key]
+ {
+ get
+ {
+ if (Random.Shared.Next(100) == 1)
+ {
+ // Console.WriteLine("Cleaning cache...");
+ // foreach (var x in Cache.Where(x => x.Value.ExpiryTime < DateTime.Now).OrderBy(x => x.Value.ExpiryTime).Take(3).ToList())
+ // {
+ // Console.WriteLine($"Removing {x.Key} from cache");
+ // Cache.Remove(x.Key);
+ // }
+ }
+
+
+ if (Cache.ContainsKey(key))
+ {
+ // Console.WriteLine($"Found item in cache: {key} - {Cache[key].Result.ToJson(indent: false)}");
+ if(Cache[key].ExpiryTime > DateTime.Now)
+ return Cache[key];
+
+ Console.WriteLine($"Expired item in cache: {key} - {Cache[key].Result.ToJson(indent: false)}");
+ try
+ {
+ Cache.Remove(key);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine($"Failed to remove {key} from cache: {e.Message}");
+ }
+ }
+ return null;
+ }
+ set
+ {
+ Cache[key] = value;
+ if(Cache[key].ExpiryTime == null) Cache[key].ExpiryTime = DateTime.Now.Add(DefaultExpiry);
+ Console.WriteLine($"New item in cache: {key} - {Cache[key].Result.ToJson(indent: false)}");
+ // Console.Error.WriteLine("Full cache: " + Cache.ToJson());
+ }
+ }
+}
+public class GenericResult<T>
+{
+ public T? Result { get; set; }
+ public DateTime? ExpiryTime { get; set; }
+}
|