00001 /******************************************************************************* 00002 00003 @file CacheInvalidatee.d 00004 00005 Copyright (c) 2004 Kris Bell 00006 00007 This software is provided 'as-is', without any express or implied 00008 warranty. In no event will the authors be held liable for damages 00009 of any kind arising from the use of this software. 00010 00011 Permission is hereby granted to anyone to use this software for any 00012 purpose, including commercial applications, and to alter it and/or 00013 redistribute it freely, subject to the following restrictions: 00014 00015 1. The origin of this software must not be misrepresented; you must 00016 not claim that you wrote the original software. If you use this 00017 software in a product, an acknowledgment within documentation of 00018 said product would be appreciated but is not required. 00019 00020 2. Altered source versions must be plainly marked as such, and must 00021 not be misrepresented as being the original software. 00022 00023 3. This notice may not be removed or altered from any distribution 00024 of the source. 00025 00026 4. Derivative works are permitted, but they must carry this notice 00027 in full and credit the original source. 00028 00029 00030 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00031 00032 00033 @version Initial version, July 2004 00034 @author Kris 00035 00036 00037 *******************************************************************************/ 00038 00039 module mango.cluster.CacheInvalidatee; 00040 00041 private import mango.log.Logger; 00042 00043 private import mango.cache.Payload; 00044 00045 private import mango.cache.model.ICache; 00046 00047 private import mango.cluster.model.ICluster; 00048 00049 private import mango.cluster.Client, 00050 mango.cluster.CacheInvalidator; 00051 00052 /******************************************************************************* 00053 00054 Wrapper around an ICache instance that attaches it to the network, 00055 and ensures the former complies with cache invalidation requests. 00056 Use this in conjunction with CacheInvalidator or NetworkCombo. The 00057 ICache provided should typically be synchronized against thread 00058 contention since it will potentially have entries removed from a 00059 listener thread (you won't need synchronization if you're using 00060 the concurrent hash-map ICache implementation). 00061 00062 *******************************************************************************/ 00063 00064 class CacheInvalidatee : Client, IEventListener 00065 { 00066 private IMutableCache cache; 00067 private ILogger logger; 00068 private IConsumer consumer; 00069 00070 /*********************************************************************** 00071 00072 Construct a CacheInvalidatee upon the given cache, using 00073 the named channel. This channel should be a name that's 00074 common to both the receiver and the sender. 00075 00076 ***********************************************************************/ 00077 00078 this (ICluster cluster, char[] channel, IMutableCache cache) 00079 in { 00080 assert (cache); 00081 } 00082 body 00083 { 00084 super (cluster, channel); 00085 00086 this.cache = cache; 00087 this.logger = cluster.getLogger; 00088 00089 // make sure we have a logger configured 00090 if (this.logger is null) 00091 throw new ClusterException ("CacheInvalidatee requires the " 00092 "cluster to have a logger configured"); 00093 00094 // start listening for invalidation requests 00095 consumer = getCluster.createConsumer (getChannel(), IEvent.Style.Bulletin, this); 00096 } 00097 00098 /*********************************************************************** 00099 00100 Detach from the network. The CacheInvalidatee is disabled 00101 from this point forward. 00102 00103 ***********************************************************************/ 00104 00105 void cancel () 00106 { 00107 consumer.cancel (); 00108 } 00109 00110 /*********************************************************************** 00111 00112 Return the IMutableCache instance provided during construction 00113 00114 ***********************************************************************/ 00115 00116 IMutableCache getCache () 00117 { 00118 return cache; 00119 } 00120 00121 /*********************************************************************** 00122 00123 Notification callback from the listener. We remove the 00124 indicated entry from our cache and destroy the payload 00125 immediately in case it belongs on a freelist. 00126 00127 ***********************************************************************/ 00128 00129 protected void notify (IEvent event, IPayload payload) 00130 { 00131 assert (payload); 00132 00133 try { 00134 InvalidatorPayload p = cast(InvalidatorPayload) payload; 00135 00136 // remove entry from our cache 00137 if (cache.extract (p.getText, p.getTimeout)) 00138 if (logger.isEnabled (logger.Level.Trace)) 00139 logger.trace ("removed cache entry '"~p.getText~ 00140 "' on channel '"~event.getChannel.getName~"'"); 00141 } finally 00142 // place payload back on freelist? 00143 payload.destroy (); 00144 } 00145 } 00146