Show More
@@ -64,11 +64,11 b' def connect_pyro4(server_and_port):' | |||||
64 | from rhodecode.lib.vcs import connection, client |
|
64 | from rhodecode.lib.vcs import connection, client | |
65 | from rhodecode.lib.middleware.utils import scm_app |
|
65 | from rhodecode.lib.middleware.utils import scm_app | |
66 |
|
66 | |||
67 |
git_remote = client. |
|
67 | git_remote = client.RequestScopeProxyFactory( | |
68 | settings.pyro_remote(settings.PYRO_GIT, server_and_port)) |
|
68 | settings.pyro_remote(settings.PYRO_GIT, server_and_port)) | |
69 |
hg_remote = client. |
|
69 | hg_remote = client.RequestScopeProxyFactory( | |
70 | settings.pyro_remote(settings.PYRO_HG, server_and_port)) |
|
70 | settings.pyro_remote(settings.PYRO_HG, server_and_port)) | |
71 |
svn_remote = client. |
|
71 | svn_remote = client.RequestScopeProxyFactory( | |
72 | settings.pyro_remote(settings.PYRO_SVN, server_and_port)) |
|
72 | settings.pyro_remote(settings.PYRO_SVN, server_and_port)) | |
73 |
|
73 | |||
74 | connection.Git = client.RepoMaker(proxy_factory=git_remote) |
|
74 | connection.Git = client.RepoMaker(proxy_factory=git_remote) |
@@ -34,6 +34,7 b' from urllib2 import URLError' | |||||
34 | import msgpack |
|
34 | import msgpack | |
35 | import Pyro4 |
|
35 | import Pyro4 | |
36 | import requests |
|
36 | import requests | |
|
37 | from pyramid.threadlocal import get_current_request | |||
37 | from Pyro4.errors import CommunicationError, ConnectionClosedError, DaemonError |
|
38 | from Pyro4.errors import CommunicationError, ConnectionClosedError, DaemonError | |
38 |
|
39 | |||
39 | from rhodecode.lib.vcs import exceptions |
|
40 | from rhodecode.lib.vcs import exceptions | |
@@ -190,19 +191,61 b' class RepoMaker(object):' | |||||
190 | return _wrap_remote_call(remote_proxy, func) |
|
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 | def __init__(self, remote_uri): |
|
201 | def __init__(self, remote_uri): | |
199 | self._remote_uri = remote_uri |
|
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): |
|
223 | # Get proxy from pool or create new instance. | |
203 | if not hasattr(self._thread_local, 'proxy'): |
|
224 | try: | |
204 | self._thread_local.proxy = Pyro4.Proxy(self._remote_uri) |
|
225 | proxy = self._proxy_pool.pop() | |
205 | return self._thread_local.proxy |
|
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 | class RemoteRepo(object): |
|
251 | class RemoteRepo(object): |
General Comments 0
You need to be logged in to leave comments.
Login now