1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import stat
19
20 from twisted.internet import defer
21
22 from flumotion.common import log
23
24 from flumotion.component.misc.httpserver import fileprovider
25 from flumotion.component.misc.httpserver import cachestats
26 from flumotion.component.misc.httpserver.httpcached import common
27 from flumotion.component.misc.httpserver.httpcached import strategy_base
28
29 LOG_CATEGORY = "basic-caching"
30
31 EXPIRE_CHECK_TTL = 3
32
33
35 """
36 Simplistic caching strategy where all requested streams
37 are cached when requested.
38
39 On each cache-miss, a caching session is created and started right away.
40
41 When a cached file expire, a new session is created with the condition
42 that it has been modified. If not the cached file is used
43 and keep alive, if it succeed the cached file is deleted
44 and a new caching session is created and started.
45
46 Updates the caching statistics.
47 """
48
49 logCategory = LOG_CATEGORY
50
51 - def __init__(self, cachemgr, reqmgr, ttl):
53
61
63 self.log("Checking if resource is outdated '%s'", url)
64 mtime = cachedFile.stat.st_mtime
65 sess = strategy_base.CachingSession(self, url,
66 self.cachemgr.stats, ifModifiedSince=mtime)
67 sess.cache()
68 sess.checkModified = True
69 d = sess.waitStarted()
70 args = (url, identifier, cachedFile, stats)
71 d.addCallbacks(self._reallyOutdated, self._maybeNotOutdated,
72 callbackArgs=args, errbackArgs=args)
73 return d
74
83
85 if failure.check(strategy_base.ConditionError):
86
87 self.log("Resource not outdated, keep using "
88 "the cached one for '%s'", url)
89 self.keepCacheAlive(identifier)
90 stats.onStarted(cachedFile.stat[stat.ST_SIZE],
91 cachestats.CACHE_HIT)
92 return strategy_base.CachedSource(identifier, url,
93 cachedFile, stats)
94
95 if failure.check(fileprovider.NotFoundError, fileprovider.AccessError):
96
97 self.debug("Resource deleted or forbidden, removing cached file")
98 cachedFile.close()
99 return failure
100
101 if failure.check(fileprovider.FileError):
102 self.warning("Cached file expiration check fail, "
103 "using cached file anyway: %s",
104 failure.getErrorMessage())
105
106
107 self.keepCacheAlive(identifier, EXPIRE_CHECK_TTL)
108 stats.onStarted(cachedFile.stat[stat.ST_SIZE],
109 cachestats.CACHE_HIT)
110 return strategy_base.CachedSource(identifier, url,
111 cachedFile, stats)
112
113 cachedFile.close()
114 return failure
115
120
124