cache: decay after some time to allow for dhcp-changing addresses
authorClaus Gittinger <cg@exept.de>
Thu, 26 Apr 2007 11:29:37 +0200
changeset 1877 d143433fd007
parent 1876 366e9c8181dd
child 1878 07b7aa1394c6
cache: decay after some time to allow for dhcp-changing addresses
IPSocketAddress.st
--- a/IPSocketAddress.st	Wed Mar 28 15:08:20 2007 +0200
+++ b/IPSocketAddress.st	Thu Apr 26 11:29:37 2007 +0200
@@ -9,12 +9,11 @@
  other person.  No title to or ownership of the software is
  hereby transferred.
 "
-
 "{ Package: 'stx:libbasic2' }"
 
 SocketAddress variableByteSubclass:#IPSocketAddress
 	instanceVariableNames:''
-	classVariableNames:''
+	classVariableNames:'CacheInvalidationTimeInterval AddressCacheSize NameCacheSize'
 	poolDictionaries:''
 	category:'OS-Sockets'
 !
@@ -47,26 +46,18 @@
     Instances of IPSocketAddress represent tcp/ip-domain socket addresses.
     These consist of an ip address (4 bytes) and a port number.
 
-    ST-80 compatibility class.
-    This may be required when existing code has to be ported to ST/X;
-    however, it may not be complete and more protocol may be added in the future.
-    The code here was created when public domain code (Manchester) had to
-    be ported to ST/X and missing classes/methods were encountered, and code added
-    by reasoning 'what the original class could probably do there'.
-
-    This is an additional goody class; therefore:
+    Notice that for performance, name and address translations are cached here
+    for some time, in order to speed up heavy lookup such as when operating a webserver or similar
+    application which does many address-to-hostname translations.
 
-    THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTOR ``AS IS'' AND
-    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-    ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTOR BE LIABLE
-    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-    SUCH DAMAGE.
+    For systems, when the name translation is fast (unix), you may want to disable it,
+    as it prevents new addresses to be detected for some time (for example, if the own address
+    changes due to a new dhcp address being aquired).
+    You can also change the cacheing-interval time 
+    (see caching protocol, flush*Cache, cachingIntervalTime, *CacheSize).
+
+    [author:]
+        Claus Gittinger
 "
 ! !
 
@@ -118,6 +109,13 @@
     "get a new instance representing the local-host address"
 
     ^ self hostAddress:(self local) port:self anyPort
+
+    "
+     self localHost hostName
+     (self hostName:(OperatingSystem getHostName))      
+    "
+
+    "Modified: / 26-04-2007 / 11:17:52 / cg"
 ! !
 
 !IPSocketAddress class methodsFor:'addressing'!
@@ -167,18 +165,55 @@
 !IPSocketAddress class methodsFor:'caching'!
 
 addressCacheAt:aHostName
+    |addrAndTime addr time|
+
     addrCache notNil ifTrue:[
-        ^ addrCache at:aHostName ifAbsent:nil.
+        addrAndTime := addrCache at:aHostName ifAbsent:nil.
+        addrAndTime notNil ifTrue:[
+            addr := addrAndTime key.
+            time := addrAndTime value.
+            ((Timestamp now) secondDeltaFrom:time) > self cacheInvalidationTimeInterval ifFalse:[
+                ^ addr.
+            ]
+        ].
     ].
     ^ nil
+
+    "Modified: / 26-04-2007 / 11:21:37 / cg"
 !
 
 addressCacheAt:aName put:aHostAddress
-    (addrCache isNil or:[addrCache size > 30]) ifTrue:[
+    (addrCache isNil or:[addrCache size > self addressCacheSize]) ifTrue:[
         addrCache := Dictionary new.
     ].
     
-    addrCache at:aName put:aHostAddress.
+    addrCache at:aName put:(aHostAddress -> Timestamp now).
+
+    "Modified: / 26-04-2007 / 11:23:26 / cg"
+!
+
+addressCacheSize
+    ^ AddressCacheSize ? 50
+
+    "Created: / 26-04-2007 / 11:22:40 / cg"
+!
+
+addressCacheSize:aNumber
+    AddressCacheSize := aNumber
+
+    "Created: / 26-04-2007 / 11:24:05 / cg"
+!
+
+cacheInvalidationTimeInterval
+    ^ CacheInvalidationTimeInterval ? 30
+
+    "Created: / 26-04-2007 / 11:21:31 / cg"
+!
+
+cacheInvalidationTimeInterval:seconds
+    CacheInvalidationTimeInterval := seconds
+
+    "Created: / 26-04-2007 / 11:29:28 / cg"
 !
 
 flushAddressCache
@@ -191,21 +226,52 @@
 
 flushNameCache
     nameCache := Dictionary new.
+
+    "
+     self flushNameCache
+    "
+
+    "Modified: / 26-04-2007 / 11:25:32 / cg"
 !
 
 nameCacheAt:aHostAddress
+    |nameAndTime name time|
+
     nameCache notNil ifTrue:[
-        ^ nameCache at:aHostAddress ifAbsent:nil.
+        nameAndTime := nameCache at:aHostAddress ifAbsent:nil.
+        nameAndTime notNil ifTrue:[
+            name := nameAndTime key.
+            time := nameAndTime value.
+            ((Timestamp now) secondDeltaFrom:time) > self cacheInvalidationTimeInterval ifFalse:[
+                ^ name.
+            ]
+        ].
     ].
     ^ nil
+
+    "Modified: / 26-04-2007 / 11:25:11 / cg"
 !
 
 nameCacheAt:aHostAddress put:aName
-    (nameCache isNil or:[nameCache size > 30]) ifTrue:[
+    (nameCache isNil or:[nameCache size > self nameCacheSize]) ifTrue:[
         nameCache := Dictionary new.
     ].
     
-    nameCache at:aHostAddress put:aName.
+    nameCache at:aHostAddress put:(aName -> Timestamp now).
+
+    "Modified: / 26-04-2007 / 11:23:35 / cg"
+!
+
+nameCacheSize
+    ^ NameCacheSize ? 50
+
+    "Created: / 26-04-2007 / 11:22:44 / cg"
+!
+
+nameCacheSize:aNumber
+    NameCacheSize := aNumber
+
+    "Created: / 26-04-2007 / 11:23:49 / cg"
 ! !
 
 !IPSocketAddress class methodsFor:'conversion'!
@@ -369,5 +435,5 @@
 !IPSocketAddress class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic2/IPSocketAddress.st,v 1.29 2006-01-14 15:08:55 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/IPSocketAddress.st,v 1.30 2007-04-26 09:29:37 cg Exp $'
 ! !