PageRenderTime 68ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/SobekCM_Library/MemoryMgmt/AppFabric_Manager.cs

http://github.com/MarkVSullivan/SobekCM-Web-Application
C# | 329 lines | 239 code | 44 blank | 46 comment | 55 complexity | 70844fe55a27c0166498effbfb6096dc MD5 | raw file
Possible License(s): LGPL-2.1, MIT, GPL-3.0, LGPL-2.0
  1. #region Using directives
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Collections.ObjectModel;
  5. using System.Linq;
  6. using Microsoft.ApplicationServer.Caching;
  7. using SobekCM.Bib_Package;
  8. using SobekCM.Library.Aggregations;
  9. using SobekCM.Library.Skins;
  10. #endregion
  11. namespace SobekCM.Library.MemoryMgmt
  12. {
  13. /// <summary> Class manages all interactions with the AppFabric Caching server and keeps track
  14. /// of the keys for all the items on the remote cache which have not been expired </summary>
  15. public class AppFabric_Manager
  16. {
  17. private static DataCacheFactory myCacheFactory;
  18. private static DataCache myDefaultCache;
  19. private const string regionName = "SobekCM";
  20. private static Expiring_Item_Typed_List<string> keys;
  21. private static DateTime? lastErrorTime;
  22. private static string lastErrorMessage;
  23. private static readonly bool enabled;
  24. /// <summary> Static constructor initialized this class for use </summary>
  25. static AppFabric_Manager()
  26. {
  27. lastErrorMessage = String.Empty;
  28. if (SobekCM_Library_Settings.Caching_Server.Length > 0)
  29. {
  30. enabled = true;
  31. }
  32. if (enabled)
  33. {
  34. if (PrepareClient(SobekCM_Library_Settings.Caching_Server))
  35. {
  36. keys = new Expiring_Item_Typed_List<string>(30);
  37. }
  38. else
  39. {
  40. lastErrorTime = DateTime.Now;
  41. }
  42. }
  43. }
  44. /// <summary> Gets the list of all items which are currently cached and in the list of non-expired keys </summary>
  45. public static ReadOnlyCollection<Cached_Object_Info> Cached_Items
  46. {
  47. get
  48. {
  49. List<Cached_Object_Info> returnValue = new List<Cached_Object_Info>();
  50. if (keys != null)
  51. {
  52. returnValue.AddRange(keys.Select(item => new Cached_Object_Info(item.Key, item.DataType)));
  53. }
  54. return new ReadOnlyCollection<Cached_Object_Info>(returnValue);
  55. }
  56. }
  57. /// <summary> Adds an object to the remote cache and provides a key for retrieving later </summary>
  58. /// <param name="Key"> Key for this item for later retrieval </param>
  59. /// <param name="Object_For_Caching"> Object to cache </param>
  60. /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering</param>
  61. /// <returns> TRUE if successful, otherwise FALSE </returns>
  62. public static bool Add(string Key, object Object_For_Caching, Custom_Tracer Tracer )
  63. {
  64. if (Configure(Tracer))
  65. {
  66. try
  67. {
  68. myDefaultCache.Put(Key, Object_For_Caching, regionName);
  69. keys.Add(Key, Object_For_Caching.GetType());
  70. return true;
  71. }
  72. catch
  73. {
  74. return false;
  75. }
  76. }
  77. return false;
  78. }
  79. /// <summary> Checks to see if the provided key is in the list of keys for items remotely cached </summary>
  80. /// <param name="Key"> Key to check for existence </param>
  81. /// <returns> TRUE if the key exists, otherwise FALSE </returns>
  82. public static bool Contains(string Key)
  83. {
  84. return keys != null && keys.Contains(Key);
  85. }
  86. /// <summary> Gets an object from the remote cache by key </summary>
  87. /// <param name="Key"> Key for the object to retrieve </param>
  88. /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering</param>
  89. /// <returns> Retrieved object, or NULL </returns>
  90. public static object Get(string Key, Custom_Tracer Tracer)
  91. {
  92. try
  93. {
  94. if (( keys != null ) && ( keys.Contains(Key)))
  95. {
  96. object returnValue = myDefaultCache.Get(Key, regionName);
  97. if (returnValue == null)
  98. keys.Remove(Key);
  99. else
  100. return returnValue;
  101. }
  102. }
  103. catch
  104. {
  105. }
  106. return null;
  107. }
  108. /// <summary> Clears the list of all keys, which in effect, causes any remaining items on the
  109. /// cache to be ignored </summary>
  110. public static void Clear_All_Keys()
  111. {
  112. if ( keys != null )
  113. keys.Clear();
  114. }
  115. /// <summary> Expires an item by removing it from the list of remotely cached items </summary>
  116. /// <param name="Key"> Key to remove from the list of remotely cached items </param>
  117. public static void Expire_Item(string Key)
  118. {
  119. if ( keys != null )
  120. keys.Remove(Key);
  121. }
  122. /// <summary> Expires a number of items whose key begins with the provided start </summary>
  123. /// <param name="Key_Start"> Beginning of all matching keys to be epxired </param>
  124. public static void Expire_Items(string Key_Start)
  125. {
  126. if (keys != null)
  127. {
  128. List<string> keys_to_expire = (from thisKey in keys where thisKey.Key.IndexOf(Key_Start) == 0 select thisKey.Key).ToList();
  129. foreach (string expireKey in keys_to_expire)
  130. {
  131. keys.Remove(expireKey);
  132. }
  133. }
  134. }
  135. private static bool Configure( Custom_Tracer Tracer )
  136. {
  137. if ( !enabled )
  138. return false;
  139. if (( lastErrorTime.HasValue ) && ( DateTime.Now.Subtract( lastErrorTime.Value ).TotalMinutes < 15 ))
  140. {
  141. if (lastErrorMessage.Length > 0)
  142. {
  143. Tracer.Add_Trace("AppFabric_Manager.configure", "Network cache temporarily disabled due to previous error ( " + lastErrorTime.Value.ToShortTimeString() + " )<br />" + lastErrorMessage, Custom_Trace_Type_Enum.Error);
  144. }
  145. else
  146. {
  147. Tracer.Add_Trace("AppFabric_Manager.configure", "Network cache temporarily disabled due to previous error ( " + lastErrorTime.Value.ToShortTimeString() + " )", Custom_Trace_Type_Enum.Error);
  148. }
  149. return false;
  150. }
  151. if ( keys == null )
  152. {
  153. if (PrepareClient(SobekCM_Library_Settings.Caching_Server))
  154. {
  155. keys = new Expiring_Item_Typed_List<string>(30);
  156. return true;
  157. }
  158. if (lastErrorMessage.Length > 0)
  159. {
  160. Tracer.Add_Trace("AppFabric_Manager.configure", "Unable to prepare the caching client<br />" + lastErrorMessage, Custom_Trace_Type_Enum.Error);
  161. }
  162. else
  163. {
  164. Tracer.Add_Trace("AppFabric_Manager.configure", "Unable to prepare the caching client", Custom_Trace_Type_Enum.Error);
  165. }
  166. lastErrorTime = DateTime.Now;
  167. return false;
  168. }
  169. bool returnValue = true;
  170. try
  171. {
  172. lastErrorMessage = String.Empty;
  173. myDefaultCache.CreateRegion(regionName);
  174. }
  175. catch (Exception ee )
  176. {
  177. lastErrorMessage = ee.Message;
  178. returnValue = false;
  179. }
  180. if (!returnValue)
  181. {
  182. lastErrorTime = DateTime.Now;
  183. keys = null;
  184. if (lastErrorMessage.Length > 0)
  185. {
  186. Tracer.Add_Trace("AppFabric_Manager.configure", "Unable to create the region on the cache server<br />" + lastErrorMessage, Custom_Trace_Type_Enum.Error);
  187. }
  188. else
  189. {
  190. Tracer.Add_Trace("AppFabric_Manager.configure", "Unable to create the region on the cache server", Custom_Trace_Type_Enum.Error);
  191. }
  192. return false;
  193. }
  194. return true;
  195. }
  196. private static bool PrepareClient(string server_name)
  197. {
  198. lastErrorMessage = String.Empty;
  199. try
  200. {
  201. //-------------------------
  202. // Configure Cache Client
  203. //-------------------------
  204. //Define Array for 1 Cache Host
  205. List<DataCacheServerEndpoint> servers = new List<DataCacheServerEndpoint>(1)
  206. {new DataCacheServerEndpoint(server_name, 22233)};
  207. //Specify Cache Host Details
  208. // Parameter 1 = host name
  209. // Parameter 2 = cache port number
  210. //Create cache configuration
  211. DataCacheFactoryConfiguration configuration = new DataCacheFactoryConfiguration
  212. {
  213. Servers = servers,
  214. SecurityProperties =new DataCacheSecurity( DataCacheSecurityMode.None, DataCacheProtectionLevel.None),
  215. LocalCacheProperties = new DataCacheLocalCacheProperties()
  216. };
  217. //Disable exception messages since this sample works on a cache aside
  218. //DataCacheClientLogManager.ChangeLogLevel(System.Diagnostics.TraceLevel.Off);
  219. //Pass configuration settings to cacheFactory constructor
  220. myCacheFactory = new DataCacheFactory(configuration);
  221. //Get reference to named cache called "default"
  222. myDefaultCache = myCacheFactory.GetCache("default");
  223. //specify all possible item and region operations
  224. const DataCacheOperations itemCacheOperations = DataCacheOperations.AddItem |
  225. DataCacheOperations.ReplaceItem |
  226. DataCacheOperations.RemoveItem |
  227. DataCacheOperations.ClearRegion |
  228. DataCacheOperations.CreateRegion;
  229. //add cache-level notification callback
  230. //all cache operations from a notifications-enabled cache
  231. DataCacheNotificationDescriptor ndCacheLvlAllOps = myDefaultCache.AddRegionLevelCallback("SobekCM", itemCacheOperations, myCacheLvlDelegate);
  232. myDefaultCache.CreateRegion(regionName);
  233. return true;
  234. }
  235. catch ( Exception ee )
  236. {
  237. lastErrorMessage = ee.Message;
  238. return false;
  239. }
  240. }
  241. //method invoked by notification "ndCacheLvlAllOps"
  242. private static void myCacheLvlDelegate(string myCacheName,
  243. string myRegion,
  244. string myKey,
  245. DataCacheItemVersion itemVersion,
  246. DataCacheOperations OperationId,
  247. DataCacheNotificationDescriptor nd)
  248. {
  249. //try
  250. //{
  251. // update the key list
  252. if (keys != null)
  253. {
  254. if (OperationId == DataCacheOperations.RemoveItem)
  255. keys.Remove(myKey);
  256. if ((OperationId == DataCacheOperations.AddItem) && (!keys.Contains(myKey)))
  257. {
  258. // This is where we can try to guess the TYPE, based on how our system works
  259. Type thisType = null;
  260. if (((myKey.IndexOf("ITEM_") == 0) || (myKey.IndexOf("USERITEM") == 0)))
  261. {
  262. thisType = typeof(SobekCM_Item);
  263. }
  264. if ((thisType == null) && ((myKey.IndexOf("ITEMSEARCH_") == 0) || ( myKey.IndexOf("BROWSEBY_") == 0 )))
  265. {
  266. thisType = typeof(List<string>);
  267. }
  268. if ((thisType == null) && (myKey.IndexOf("SKIN_") == 0))
  269. {
  270. thisType = typeof(SobekCM_Skin_Object);
  271. }
  272. if ((thisType == null) && (myKey.IndexOf("AGGR_") == 0))
  273. {
  274. thisType = typeof(Item_Aggregation);
  275. }
  276. keys.Add(myKey, thisType);
  277. }
  278. }
  279. //}
  280. //catch
  281. //{
  282. //}
  283. }
  284. }
  285. }