diff --git a/kallithea/lib/base.py b/kallithea/lib/base.py --- a/kallithea/lib/base.py +++ b/kallithea/lib/base.py @@ -520,3 +520,20 @@ class BaseRepoController(BaseController) log.error(traceback.format_exc()) h.flash(safe_str(e), category='error') raise webob.exc.HTTPBadRequest() + + +class WSGIResultCloseCallback(object): + """Wrap a WSGI result and let close call close after calling the + close method on the result. + """ + def __init__(self, result, close): + self._result = result + self._close = close + + def __iter__(self): + return iter(self._result) + + def close(self): + if hasattr(self._result, 'close'): + self._result.close() + self._close() diff --git a/kallithea/lib/middleware/simplegit.py b/kallithea/lib/middleware/simplegit.py --- a/kallithea/lib/middleware/simplegit.py +++ b/kallithea/lib/middleware/simplegit.py @@ -40,7 +40,7 @@ from kallithea.model.db import User, Ui from kallithea.lib.utils2 import safe_str, fix_PATH, get_server_url,\ _set_extras -from kallithea.lib.base import BaseVCSController +from kallithea.lib.base import BaseVCSController, WSGIResultCloseCallback from kallithea.lib.utils import make_ui, is_valid_repo from kallithea.lib.exceptions import HTTPLockedRC from kallithea.lib.hooks import pre_pull @@ -203,7 +203,11 @@ class SimpleGit(BaseVCSController): log.info('%s action on Git repo "%s" by "%s" from %s', action, str_repo_name, safe_str(username), ip_addr) app = self.__make_app(repo_name, repo_path, extras) - return app(environ, start_response) + result = app(environ, start_response) + if action == 'push': + result = WSGIResultCloseCallback(result, + lambda: self._invalidate_cache(repo_name)) + return result except HTTPLockedRC as e: _code = CONFIG.get('lock_ret_code') log.debug('Repository LOCKED ret code %s!', _code) @@ -211,10 +215,6 @@ class SimpleGit(BaseVCSController): except Exception: log.error(traceback.format_exc()) return HTTPInternalServerError()(environ, start_response) - finally: - # invalidate cache on push - if action == 'push': - self._invalidate_cache(repo_name) def __make_app(self, repo_name, repo_path, extras): """ diff --git a/kallithea/lib/middleware/simplehg.py b/kallithea/lib/middleware/simplehg.py --- a/kallithea/lib/middleware/simplehg.py +++ b/kallithea/lib/middleware/simplehg.py @@ -39,7 +39,7 @@ from kallithea.model.db import User from kallithea.lib.utils2 import safe_str, fix_PATH, get_server_url,\ _set_extras -from kallithea.lib.base import BaseVCSController +from kallithea.lib.base import BaseVCSController, WSGIResultCloseCallback from kallithea.lib.utils import make_ui, is_valid_repo, ui_sections from kallithea.lib.vcs.utils.hgcompat import RepoError, hgweb_mod from kallithea.lib.exceptions import HTTPLockedRC @@ -205,7 +205,11 @@ class SimpleHg(BaseVCSController): log.info('%s action on Mercurial repo "%s" by "%s" from %s', action, str_repo_name, safe_str(username), ip_addr) app = self.__make_app(repo_path, baseui, extras) - return app(environ, start_response) + result = app(environ, start_response) + if action == 'push': + result = WSGIResultCloseCallback(result, + lambda: self._invalidate_cache(repo_name)) + return result except RepoError as e: if str(e).find('not found') != -1: return HTTPNotFound()(environ, start_response) @@ -216,10 +220,6 @@ class SimpleHg(BaseVCSController): except Exception: log.error(traceback.format_exc()) return HTTPInternalServerError()(environ, start_response) - finally: - # invalidate cache on push - if action == 'push': - self._invalidate_cache(repo_name) def __make_app(self, repo_name, baseui, extras): """