Show More
@@ -64,11 +64,11 b' def connect_pyro4(server_and_port):' | |||
|
64 | 64 | from rhodecode.lib.vcs import connection, client |
|
65 | 65 | from rhodecode.lib.middleware.utils import scm_app |
|
66 | 66 | |
|
67 |
git_remote = client. |
|
|
67 | git_remote = client.RequestScopeProxyFactory( | |
|
68 | 68 | settings.pyro_remote(settings.PYRO_GIT, server_and_port)) |
|
69 |
hg_remote = client. |
|
|
69 | hg_remote = client.RequestScopeProxyFactory( | |
|
70 | 70 | settings.pyro_remote(settings.PYRO_HG, server_and_port)) |
|
71 |
svn_remote = client. |
|
|
71 | svn_remote = client.RequestScopeProxyFactory( | |
|
72 | 72 | settings.pyro_remote(settings.PYRO_SVN, server_and_port)) |
|
73 | 73 | |
|
74 | 74 | connection.Git = client.RepoMaker(proxy_factory=git_remote) |
@@ -34,6 +34,7 b' from urllib2 import URLError' | |||
|
34 | 34 | import msgpack |
|
35 | 35 | import Pyro4 |
|
36 | 36 | import requests |
|
37 | from pyramid.threadlocal import get_current_request | |
|
37 | 38 | from Pyro4.errors import CommunicationError, ConnectionClosedError, DaemonError |
|
38 | 39 | |
|
39 | 40 | from rhodecode.lib.vcs import exceptions |
@@ -190,19 +191,61 b' class RepoMaker(object):' | |||
|
190 | 191 | return _wrap_remote_call(remote_proxy, func) |
|
191 | 192 | |
|
192 | 193 | |
|
193 |
class |
|
|
194 | class RequestScopeProxyFactory(object): | |
|
194 | 195 | """ |
|
195 | Creates one Pyro4 proxy per thread on demand. | |
|
196 | This factory returns pyro proxy instances based on a per request scope. | |
|
197 | It returns the same instance if called from within the same request and | |
|
198 | different instances if called from different requests. | |
|
196 | 199 | """ |
|
197 | 200 | |
|
198 | 201 | def __init__(self, remote_uri): |
|
199 | 202 | self._remote_uri = remote_uri |
|
200 | self._thread_local = threading.local() | |
|
203 | self._proxy_pool = [] | |
|
204 | self._borrowed_proxies = {} | |
|
205 | ||
|
206 | def __call__(self, request=None): | |
|
207 | """ | |
|
208 | Wrapper around `getProxy`. | |
|
209 | """ | |
|
210 | request = request or get_current_request() | |
|
211 | return self.getProxy(request) | |
|
212 | ||
|
213 | def getProxy(self, request=None): | |
|
214 | """ | |
|
215 | Call this to get the pyro proxy instance for the request. | |
|
216 | """ | |
|
217 | request = request or get_current_request() | |
|
218 | ||
|
219 | # Return already borrowed proxy for this request | |
|
220 | if request in self._borrowed_proxies: | |
|
221 | return self._borrowed_proxies[request] | |
|
201 | 222 | |
|
202 | def __call__(self): | |
|
203 | if not hasattr(self._thread_local, 'proxy'): | |
|
204 | self._thread_local.proxy = Pyro4.Proxy(self._remote_uri) | |
|
205 | return self._thread_local.proxy | |
|
223 | # Get proxy from pool or create new instance. | |
|
224 | try: | |
|
225 | proxy = self._proxy_pool.pop() | |
|
226 | except IndexError: | |
|
227 | log.info('Creating new proxy for remote_uri=%s', self._remote_uri) | |
|
228 | proxy = Pyro4.Proxy(self._remote_uri) | |
|
229 | ||
|
230 | # Store proxy instance as borrowed and add request callback. | |
|
231 | self._borrowed_proxies[request] = proxy | |
|
232 | request.add_finished_callback(self._returnProxy) | |
|
233 | ||
|
234 | return proxy | |
|
235 | ||
|
236 | def _returnProxy(self, request=None): | |
|
237 | """ | |
|
238 | Callback that gets called by pyramid when the request is finished. | |
|
239 | It puts the proxy back into the pool. | |
|
240 | """ | |
|
241 | request = request or get_current_request() | |
|
242 | ||
|
243 | if request in self._borrowed_proxies: | |
|
244 | proxy = self._borrowed_proxies.pop(request) | |
|
245 | self._proxy_pool.append(proxy) | |
|
246 | else: | |
|
247 | log.warn('Return proxy for remote_uri=%s but no proxy borrowed ' | |
|
248 | 'for this request.', self._remote_uri) | |
|
206 | 249 | |
|
207 | 250 | |
|
208 | 251 | class RemoteRepo(object): |
General Comments 0
You need to be logged in to leave comments.
Login now