initial checkin
authorClaus Gittinger <cg@exept.de>
Wed, 31 Oct 2012 12:59:16 +0100
changeset 2835 88ddcdf93432
parent 2834 6b92fee1b8af
child 2836 ed492f0aabe7
initial checkin
CachedValue.st
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CachedValue.st	Wed Oct 31 12:59:16 2012 +0100
@@ -0,0 +1,205 @@
+"
+ COPYRIGHT (c) 2012 by eXept Software AG
+              All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice.   This software may not
+ be provided or otherwise made available to, or used by, any
+ other person.  No title to or ownership of the software is
+ hereby transferred.
+"
+"{ Package: 'stx:libbasic2' }"
+
+Object subclass:#CachedValue
+	instanceVariableNames:'value expirationTime computation validityDuration'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Kernel-Processes'
+!
+
+NotFoundError subclass:#ValueExpiredException
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CachedValue
+!
+
+!CachedValue class methodsFor:'documentation'!
+
+copyright
+"
+ COPYRIGHT (c) 2012 by eXept Software AG
+              All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice.   This software may not
+ be provided or otherwise made available to, or used by, any
+ other person.  No title to or ownership of the software is
+ hereby transferred.
+"
+!
+
+documentation
+"
+    Instances of CachedValue can be used for values which are costly to evaluate,
+    but which can be cached for some time. 
+    For example, when asking a source code repository for the set of symbolic names,
+    this query takes a few seconds (a CVS roundtrip). However, this information can easily
+    be cached and remembered for some time (say 30seconds or so), to speed up followup
+    repository operations.
+    You may find more similar uses of this class.
+
+    [author:]
+        Claus Gittinger
+
+    [instance variables:]
+        value ..................... the computed (cached value)
+        expirationTime ............ timeStamp, when this value becomes obsolete
+        validDuration ............. timeDuration, how long a computed value remains valid
+        computation ............... a computation block, to recompute the value.
+
+    [class variables:]
+
+    [see also:]
+
+"
+!
+
+examples
+"
+                                                                        [exBegin]
+        |cv exceptionRaised didCompute|
+
+        didCompute := false.
+        cv := CachedValue compute:[didCompute := true. Date today dayOfWeek] validityDuration:(2 seconds).
+        self assert:(cv isValid not).
+        self assert:(didCompute not).
+        self assert:(cv value = Date today dayOfWeek).
+        self assert:(cv isValid).
+        self assert:(didCompute).
+
+        Delay waitForSeconds:3.
+        didCompute := false.
+        self assert:(cv isValid not).
+        self assert:(didCompute not).
+        self assert:(cv value = Date today dayOfWeek).
+        self assert:(cv isValid).
+        self assert:(didCompute).
+                                                                        [exEnd]
+                                                                        [exBegin]
+        |cv exceptionRaised|
+
+        cv := CachedValue value:123 expirationTime:(Timestamp now + 2 seconds).
+        self assert:(cv isValid).
+        Delay waitForSeconds:3.
+        self assert:(cv isValid not).
+
+        exceptionRaised := false.
+        ValueExpiredException handle:[:ex |
+            exceptionRaised := true.
+        ] do:[
+            cv value
+        ].
+        self assert:exceptionRaised.
+                                                                        [exEnd]
+"
+! !
+
+!CachedValue class methodsFor:'instance creation'!
+
+compute:actionBlock validityDuration:aTimeduration
+    "return a 'self computing' cachedvalue, which ceases to be valid aTimeduration after
+     it has computed its value. 
+     If asked again for a value, it will automatically recompute the value."
+
+    ^ self new 
+        compute:actionBlock validityDuration:aTimeduration
+!
+
+value:valueArg expirationTime:aTimestamp
+    "return a 'one shot' cachedValue, which ceases to be valid at expirationTime.
+     If asked for the value after that, an exception is raised
+     (i.e. it does not automatically recompute a value)"
+
+    ^ self new 
+        value:valueArg expirationTime:aTimestamp
+! !
+
+!CachedValue methodsFor:'accessing'!
+
+compute:computationBlock validityDuration:aTimeduration
+    computation := computationBlock.
+    validityDuration := aTimeduration
+!
+
+expirationTime:something
+    expirationTime := something.
+!
+
+value
+    "return my value. If not yet computed or expired, recompute using the computation block.
+     Otherwise return the cacehdValue"
+
+    self isValid ifFalse:[
+        validityDuration isNil ifTrue:[
+            ValueExpiredException raiseRequestWith:self.
+            ^ nil
+        ].
+        self computeCachedValue
+    ].
+    ^ value
+!
+
+value:valueArg expirationTime:aTimestamp
+    value := valueArg.
+    expirationTime := aTimestamp
+! !
+
+!CachedValue methodsFor:'private'!
+
+computeCachedValue
+    expirationTime := Timestamp now + validityDuration.
+    value := computation value.
+! !
+
+!CachedValue methodsFor:'queries'!
+
+isValid
+    "true if the cached value is still valid"
+
+    expirationTime notNil ifTrue:[
+        expirationTime > Timestamp now ifTrue:[
+            ^ true
+        ].
+        expirationTime := nil.
+    ].
+    ^ false
+! !
+
+!CachedValue::ValueExpiredException class methodsFor:'documentation'!
+
+documentation
+"
+    raised when a cachedValue has expired
+"
+! !
+
+!CachedValue::ValueExpiredException class methodsFor:'initialization'!
+
+initialize
+    NotifierString := 'value expired'.
+! !
+
+!CachedValue class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/libbasic2/CachedValue.st,v 1.1 2012-10-31 11:59:16 cg Exp $'
+!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/libbasic2/CachedValue.st,v 1.1 2012-10-31 11:59:16 cg Exp $'
+! !
+
+CachedValue::ValueExpiredException initialize!