##// END OF EJS Templates
tests: use baseurl instead of advertisedbaseurl...
Gregory Szorc -
r40206:f7ff5b4f default
parent child Browse files
Show More
@@ -1,193 +1,193 b''
1 1 # wireprotosimplecache.py - Extension providing in-memory wire protocol cache
2 2 #
3 3 # Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 from mercurial import (
11 11 extensions,
12 12 registrar,
13 13 repository,
14 14 util,
15 15 wireprotoserver,
16 16 wireprototypes,
17 17 wireprotov2server,
18 18 )
19 19 from mercurial.utils import (
20 20 interfaceutil,
21 21 stringutil,
22 22 )
23 23
24 24 CACHE = None
25 25
26 26 configtable = {}
27 27 configitem = registrar.configitem(configtable)
28 28
29 29 configitem('simplecache', 'cacheapi',
30 30 default=False)
31 31 configitem('simplecache', 'cacheobjects',
32 32 default=False)
33 33 configitem('simplecache', 'redirectsfile',
34 34 default=None)
35 35
36 36 # API handler that makes cached keys available.
37 37 def handlecacherequest(rctx, req, res, checkperm, urlparts):
38 38 if rctx.repo.ui.configbool('simplecache', 'cacheobjects'):
39 39 res.status = b'500 Internal Server Error'
40 40 res.setbodybytes(b'cacheobjects not supported for api server')
41 41 return
42 42
43 43 if not urlparts:
44 44 res.status = b'200 OK'
45 45 res.headers[b'Content-Type'] = b'text/plain'
46 46 res.setbodybytes(b'simple cache server')
47 47 return
48 48
49 49 key = b'/'.join(urlparts)
50 50
51 51 if key not in CACHE:
52 52 res.status = b'404 Not Found'
53 53 res.headers[b'Content-Type'] = b'text/plain'
54 54 res.setbodybytes(b'key not found in cache')
55 55 return
56 56
57 57 res.status = b'200 OK'
58 58 res.headers[b'Content-Type'] = b'application/mercurial-cbor'
59 59 res.setbodybytes(CACHE[key])
60 60
61 61 def cachedescriptor(req, repo):
62 62 return {}
63 63
64 64 wireprotoserver.API_HANDLERS[b'simplecache'] = {
65 65 'config': (b'simplecache', b'cacheapi'),
66 66 'handler': handlecacherequest,
67 67 'apidescriptor': cachedescriptor,
68 68 }
69 69
70 70 @interfaceutil.implementer(repository.iwireprotocolcommandcacher)
71 71 class memorycacher(object):
72 72 def __init__(self, ui, command, encodefn, redirecttargets, redirecthashes,
73 73 req):
74 74 self.ui = ui
75 75 self.encodefn = encodefn
76 76 self.redirecttargets = redirecttargets
77 77 self.redirecthashes = redirecthashes
78 78 self.req = req
79 79 self.key = None
80 80 self.cacheobjects = ui.configbool('simplecache', 'cacheobjects')
81 81 self.cacheapi = ui.configbool('simplecache', 'cacheapi')
82 82 self.buffered = []
83 83
84 84 ui.log('simplecache', 'cacher constructed for %s\n', command)
85 85
86 86 def __enter__(self):
87 87 return self
88 88
89 89 def __exit__(self, exctype, excvalue, exctb):
90 90 if exctype:
91 91 self.ui.log('simplecache', 'cacher exiting due to error\n')
92 92
93 93 def adjustcachekeystate(self, state):
94 94 # Needed in order to make tests deterministic. Don't copy this
95 95 # pattern for production caches!
96 96 del state[b'repo']
97 97
98 98 def setcachekey(self, key):
99 99 self.key = key
100 100 return True
101 101
102 102 def lookup(self):
103 103 if self.key not in CACHE:
104 104 self.ui.log('simplecache', 'cache miss for %s\n', self.key)
105 105 return None
106 106
107 107 entry = CACHE[self.key]
108 108 self.ui.log('simplecache', 'cache hit for %s\n', self.key)
109 109
110 110 redirectable = True
111 111
112 112 if not self.cacheapi:
113 113 redirectable = False
114 114 elif not self.redirecttargets:
115 115 redirectable = False
116 116 else:
117 117 clienttargets = set(self.redirecttargets)
118 118 ourtargets = set(t[b'name'] for t in loadredirecttargets(self.ui))
119 119
120 120 # We only ever redirect to a single target (for now). So we don't
121 121 # need to store which target matched.
122 122 if not clienttargets & ourtargets:
123 123 redirectable = False
124 124
125 125 if redirectable:
126 126 paths = self.req.dispatchparts[:-3]
127 127 paths.append(b'simplecache')
128 128 paths.append(self.key)
129 129
130 url = b'%s/%s' % (self.req.advertisedbaseurl, b'/'.join(paths))
130 url = b'%s/%s' % (self.req.baseurl, b'/'.join(paths))
131 131
132 132 #url = b'http://example.com/%s' % self.key
133 133 self.ui.log('simplecache', 'sending content redirect for %s to '
134 134 '%s\n', self.key, url)
135 135 response = wireprototypes.alternatelocationresponse(
136 136 url=url,
137 137 mediatype=b'application/mercurial-cbor')
138 138
139 139 return {'objs': [response]}
140 140
141 141 if self.cacheobjects:
142 142 return {
143 143 'objs': entry,
144 144 }
145 145 else:
146 146 return {
147 147 'objs': [wireprototypes.encodedresponse(entry)],
148 148 }
149 149
150 150 def onobject(self, obj):
151 151 if self.cacheobjects:
152 152 self.buffered.append(obj)
153 153 else:
154 154 self.buffered.extend(self.encodefn(obj))
155 155
156 156 yield obj
157 157
158 158 def onfinished(self):
159 159 self.ui.log('simplecache', 'storing cache entry for %s\n', self.key)
160 160 if self.cacheobjects:
161 161 CACHE[self.key] = self.buffered
162 162 else:
163 163 CACHE[self.key] = b''.join(self.buffered)
164 164
165 165 return []
166 166
167 167 def makeresponsecacher(orig, repo, proto, command, args, objencoderfn,
168 168 redirecttargets, redirecthashes):
169 169 return memorycacher(repo.ui, command, objencoderfn, redirecttargets,
170 170 redirecthashes, proto._req)
171 171
172 172 def loadredirecttargets(ui):
173 173 path = ui.config('simplecache', 'redirectsfile')
174 174 if not path:
175 175 return []
176 176
177 177 with open(path, 'rb') as fh:
178 178 s = fh.read()
179 179
180 180 return stringutil.evalpythonliteral(s)
181 181
182 182 def getadvertisedredirecttargets(orig, repo, proto):
183 183 return loadredirecttargets(repo.ui)
184 184
185 185 def extsetup(ui):
186 186 global CACHE
187 187
188 188 CACHE = util.lrucachedict(10000)
189 189
190 190 extensions.wrapfunction(wireprotov2server, 'makeresponsecacher',
191 191 makeresponsecacher)
192 192 extensions.wrapfunction(wireprotov2server, 'getadvertisedredirecttargets',
193 193 getadvertisedredirecttargets)
General Comments 0
You need to be logged in to leave comments. Login now