no longer use sfa.util.storage.SimpleStorage for caching list of instantiated slices...
[sfa.git] / sfa / util / cache.py
1 #
2 # This module implements general purpose caching system
3 #
4 from __future__ import with_statement
5 import time
6 import threading
7 from datetime import datetime
8
9 # maximum lifetime of cached data (in seconds) 
10 MAX_CACHE_TTL = 60 * 60
11
12 class CacheData:
13
14     data = None
15     created = None
16     expires = None
17     lock = None
18
19     def __init__(self, data, ttl = MAX_CACHE_TTL):
20         self.lock = threading.RLock()
21         self.data = data
22         self.renew(ttl)
23
24     def is_expired(self):
25         return time.time() > self.expires
26
27     def get_created_date(self):
28         return str(datetime.fromtimestamp(self.created))
29
30     def get_expires_date(self):
31         return str(datetime.fromtimestamp(self.expires))
32
33     def renew(self, ttl = MAX_CACHE_TTL):
34         self.created = time.time()
35         self.expires = self.created + ttl   
36        
37     def set_data(self, data, renew=True, ttl = MAX_CACHE_TTL):
38         with self.lock: 
39             self.data = data
40             if renew:
41                 self.renew(ttl)
42     
43     def get_data(self):
44         return self.data
45
46 class Cache:
47
48     cache  = {}
49     lock = threading.RLock()
50    
51     def add(self, key, value, ttl = MAX_CACHE_TTL):
52         with self.lock:
53             if self.cache.has_key(key):
54                 self.cache[key].set_data(value, ttl=ttl)
55             else:
56                 self.cache[key] = CacheData(value, ttl)
57            
58     def get(self, key):
59         data = self.cache.get(key)
60         if not data or data.is_expired():
61             return None 
62         return data.get_data()