CacheManager.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. using InABox.Core;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Diagnostics.CodeAnalysis;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. namespace InABox.Avalonia;
  9. public static class CacheManager
  10. {
  11. private static Dictionary<string, DateTime> _expiries = new();
  12. private static Timer? _timer;
  13. private static void StartTimer()
  14. {
  15. if (_timer is not null) return;
  16. // _timer = new Timer(ProcessCache, null, TimeSpan.Zero, TimeSpan.FromMinutes(5));
  17. }
  18. private static void ProcessCache(object? state)
  19. {
  20. var now = DateTime.Now;
  21. var toDelete = _expiries.Where(x => x.Value < now).Select(x => x.Key).ToArray();
  22. foreach (var item in toDelete)
  23. {
  24. try
  25. {
  26. File.Delete(CacheFileName(item));
  27. }
  28. catch(Exception e)
  29. {
  30. MobileLogging.Log(e);
  31. }
  32. }
  33. lock (_expiries)
  34. {
  35. foreach (var item in toDelete)
  36. {
  37. _expiries.Remove(item);
  38. }
  39. }
  40. }
  41. private static void AddExpiry(string key, DateTime expiry)
  42. {
  43. // lock (_expiries)
  44. // {
  45. // _expiries[key] = expiry;
  46. // }
  47. // SaveExpiries();
  48. }
  49. private static Guid CacheID { get; set; }
  50. private static bool IsCached(string key) => File.Exists(CacheFileName(key));
  51. private static string CacheFileName(string key) =>
  52. Path.Combine(CacheFolder(), key);
  53. private static string CacheFolder()
  54. {
  55. var result = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
  56. if (OperatingSystem.IsWindows())
  57. {
  58. var assembly = Path.GetFileNameWithoutExtension(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName);
  59. result = Path.Combine(result, assembly);
  60. }
  61. if (CacheID != Guid.Empty)
  62. result = Path.Combine(result, CacheID.ToString());
  63. if (!Directory.Exists(result))
  64. Directory.CreateDirectory(result);
  65. return result;
  66. }
  67. private const string EXPIRY_FILE = "cache_expiry.json";
  68. private static void LoadExpiries()
  69. {
  70. var filename = CacheFileName(EXPIRY_FILE);
  71. if (File.Exists(filename))
  72. {
  73. var json = File.ReadAllText(filename);
  74. lock (_expiries)
  75. {
  76. _expiries = Serialization.Deserialize<Dictionary<string, DateTime>>(json) ?? [];
  77. }
  78. }
  79. else
  80. {
  81. lock (_expiries)
  82. {
  83. _expiries = [];
  84. }
  85. }
  86. }
  87. private static void SaveExpiries()
  88. {
  89. try
  90. {
  91. lock (_expiries)
  92. {
  93. var file = CacheFileName(EXPIRY_FILE);
  94. var json = Serialization.Serialize(_expiries);
  95. File.WriteAllText(file, json);
  96. }
  97. }
  98. catch (Exception e)
  99. {
  100. MobileLogging.Log(e);
  101. }
  102. }
  103. #region Public Interface
  104. public static void Initialise(Guid cacheID)
  105. {
  106. CacheID = cacheID;
  107. // LoadExpiries();
  108. StartTimer();
  109. }
  110. public static bool TryLoadBinary<T>(string key, [NotNullWhen(true)] out T? value, out DateTime lastUpdated)
  111. where T : class, ISerializeBinary, new()
  112. {
  113. var filename = CacheFileName(key);
  114. if (File.Exists(filename))
  115. {
  116. lastUpdated = File.GetLastWriteTime(filename);
  117. using var stream = new FileStream(filename, FileMode.Open);
  118. value = Serialization.ReadBinary<T>(stream, BinarySerializationSettings.Latest);
  119. return true;
  120. }
  121. else
  122. {
  123. lastUpdated = default;
  124. value = null;
  125. return false;
  126. }
  127. }
  128. public static void SaveBinary<T>(string key, T value, DateTime expiry)
  129. where T : class, ISerializeBinary, new()
  130. {
  131. var data = value.WriteBinary(BinarySerializationSettings.Latest);
  132. try
  133. {
  134. var file = CacheFileName(key);
  135. File.WriteAllBytes(file, data);
  136. AddExpiry(key, expiry);
  137. }
  138. catch (Exception e)
  139. {
  140. MobileLogging.Log(e);
  141. }
  142. }
  143. public static bool TryLoadJSON<T>(string key, [NotNullWhen(true)] out T? value, out DateTime lastUpdated)
  144. where T : class, new()
  145. {
  146. var filename = CacheFileName(key);
  147. if (File.Exists(filename))
  148. {
  149. lastUpdated = File.GetLastWriteTime(filename);
  150. var json = File.ReadAllText(filename);
  151. value = Serialization.Deserialize<T>(json);
  152. return value is not null;
  153. }
  154. else
  155. {
  156. lastUpdated = default;
  157. value = null;
  158. return false;
  159. }
  160. }
  161. public static void SaveJSON<T>(string key, T value, DateTime expiry)
  162. where T : class, new()
  163. {
  164. try
  165. {
  166. var file = CacheFileName(key);
  167. var json = Serialization.Serialize(value);
  168. File.WriteAllText(file, json);
  169. AddExpiry(key, expiry);
  170. }
  171. catch (Exception e)
  172. {
  173. MobileLogging.Log(e);
  174. }
  175. }
  176. #endregion
  177. }