[PATCH 2 of 2 V2] hgweb: consume generator inside context manager (issue4756)
Pierre-Yves David
pierre-yves.david at ens-lyon.org
Mon Sep 14 23:05:23 UTC 2015
On 09/12/2015 12:18 PM, Gregory Szorc wrote:
> # HG changeset patch
> # User Gregory Szorc <gregory.szorc at gmail.com>
> # Date 1442085399 25200
> # Sat Sep 12 12:16:39 2015 -0700
> # Node ID 5073c7fb4632855becb31dbd315d70c03c8a2309
> # Parent fd8dc94b2bd2c57b0d9669ef9708c655f8a0859c
> hgweb: consume generator inside context manager (issue4756)
patch 1 seems to have been queue from v1, what is the status of this?
> If code inside a context manager returns a generator, the context
> manager exits before the generator is iterated.
>
> hgweb was using a context manager to control thread safe access to a
> localrepository instance. But it was returning a generator, so there was
> a race condition between a previous request streaming a response to the
> client and a new request obtaining the released but in use repository.
> By iterating the generator inside the context manager, we ensure we
> don't release the repo instance until after the response has finished.
>
> With this change, hgweb finally appears to have full localrepository
> isolation between threads. I can no longer reproduce the 2 exceptions
> reported in issue4756.
>
> test-hgweb-non-interactive.t has been modified to consume the output
> of calling into a WSGI application. Without this, execution of the WSGI
> application stalls because of the added yield statement.
>
> diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py
> --- a/mercurial/hgweb/hgweb_mod.py
> +++ b/mercurial/hgweb/hgweb_mod.py
> @@ -274,9 +274,10 @@ class hgweb(object):
> This is typically only called by Mercurial. External consumers
> should be using instances of this class as the WSGI application.
> """
> with self._obtainrepo() as repo:
> - return self._runwsgi(req, repo)
> + for r in self._runwsgi(req, repo):
> + yield r
nice catch, you should probably document it.
>
> def _runwsgi(self, req, repo):
> rctx = requestcontext(self, repo)
>
> diff --git a/tests/test-hgweb-non-interactive.t b/tests/test-hgweb-non-interactive.t
> --- a/tests/test-hgweb-non-interactive.t
> +++ b/tests/test-hgweb-non-interactive.t
> @@ -57,9 +57,10 @@ by the WSGI standard and strictly implem
> > 'SERVER_PROTOCOL': 'HTTP/1.0'
> > }
> >
> > i = hgweb('.')
> - > i(env, startrsp)
> + > for c in i(env, startrsp):
> + > pass
> > print '---- ERRORS'
> > print errors.getvalue()
> > print '---- OS.ENVIRON wsgi variables'
> > print sorted([x for x in os.environ if x.startswith('wsgi')])
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> https://selenic.com/mailman/listinfo/mercurial-devel
>
--
Pierre-Yves David
More information about the Mercurial-devel
mailing list