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