<div dir="ltr">Hi Roberto!<div><br></div><div>Thanks for picking up this thread. I was afraid that's what I'd hear - we're running on Ubuntu LTS 12.04.1, which is why we are using such an old version. I'll try to upgrade and re-test.</div>

<div><br></div><div>-Clemens</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Apr 1, 2014 at 3:17 PM, Roberto De Ioris <span dir="ltr"><<a href="mailto:roberto@unbit.it" target="_blank">roberto@unbit.it</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5"><br>
> Hi guys,<br>
><br>
> I've been struggling with a weird situation (I have to assume a bug) and<br>
> cannot find any references to this on the Internet. If you could chime in<br>
> with some advice, that'd be wonderful :)<br>
><br>
> Please note that this whole situation is related to python-flask, and I<br>
> have contacted their mailing list to see if anyone has seen this behavior<br>
> before. They didn't and suggested to see if you guys know more :-/<br>
><br>
> The problem is that I'm not sure at what point uwsgi-plugin-python starts<br>
> spawning new threads for handling requests. Maybe it's too early and<br>
> python-flask does some optimizations that result in a bug.<br>
><br>
> Here is the situation: We host a web-service through nginx, serving<br>
> requests to uwsgi-plugin-python (version 1.0.3+dfsg-1ubuntu0.1) to our<br>
> nice<br>
> Python (2.7.3) flask app. Since we had garbage-collection issues with many<br>
> small objects on the heap in the past, we decided to respawn the uwsgi<br>
> service every few k requests and use multiple processes to avoid a<br>
> down-time in the respawn phase (and every process has multiple threads of<br>
> course).<br>
><br>
> Another important note is that we use the "lazy" option, because we use<br>
> MySQL connections which cannot be forked after Python initialization<br>
> (because all DB connections would share the same connection ID, which is<br>
> not supported by the MySQL client).<br>
><br>
> Now, it seems like each time the Python process respawns, that flask sets<br>
> up our blueprints (mappings between Python handlers and URLs in case<br>
> you're<br>
> not familiar with flask) and then starts accepting requests, but<br>
> *sometimes* responds with a 404 to clients early during this phase. This<br>
> happens very rarely, but since there is considerable load on the server,<br>
> it<br>
> actually starts adding up so that we need to something about it.<br>
><br>
> I have spent quite some time debugging the flask blueprints, and my<br>
> findings - so far - show that at app creation time, only one thread is<br>
> running in Python *after* the blueprints have been registered. However,<br>
> when I add code to log details about the blueprints / URL-rules when the<br>
> 404 happens, then the blueprints are not all/fully loaded yet.<br>
><br>
> It seems to me like new threads are created and start accepting<br>
> connections<br>
> before all blueprints/rules have been fully registered. Here is some code<br>
> to show what I mean:<br>
><br>
> def create_app(...):<br>
>     app = flask.Flask(__name__)<br>
>     [...]<br>
><br>
>     @app.after_request<br>
>     def after_request(response):<br>
>         if response.status_code == 404:<br>
>             # DBG2<br>
>             print 'dbg', response.status_code, request.base_url<br>
>             print threading.active_count(), "active threads"<br>
>             print app.url_map.__dict__.get('foo/mytesturl')<br>
>         return response<br>
><br>
>     app.register_blueprint(mymodel, url_prefix="/foo")<br>
>     # DBG1<br>
>     print 'done loading', app.url_map.__dict__<br>
>     print threading.active_count(), "active threads"<br>
>     return app<br>
><br>
> While the DBG1 code shows everything correctly, the DBG2 code shows a<br>
> sub-set of my URL-handlers (which is why the 404 gets executed).<br>
><br>
> BTW, at DBG1 point, the logs usually show "1 active threads", while at<br>
> DBG2<br>
> many more threads are loaded, making me assume there is some sort of<br>
> lazy/on-demand loading of the rules within flask.<br>
><br>
> Again, the code works, it's just that there is this race where I get 404s.<br>
><br>
> Is this a known bug in uwsgi / uwsgi-plugin-python? If so, it'd be worth<br>
> investigating on a newer version, or is there a specific way to tell flask<br>
> to fully load all blueprints/rules before accepting connections?<br>
><br>
> Sorry for the overly long email, I wanted to get all the details right :)<br>
><br>
> Thanks!<br>
> -Clemens<br>
><br>
> --<br>
> Clemens Kolbitsch<br>
> Security Researcher<br>
> <a href="mailto:kolbitsch@lastline.com">kolbitsch@lastline.com</a><br>
> Mobile <a href="tel:%2B1%20%28206%29%20356-7745" value="+12063567745">+1 (206) 356-7745</a><br>
> Land <a href="tel:%2B1%20%28805%29%20456-7076" value="+18054567076">+1 (805) 456-7076</a><br>
><br>
> Lastline, Inc.<br>
> 6950 Hollister Avenue, Suite 101<br>
> Goleta, CA 93117<br>
><br>
><br>
<br>
</div></div>Hi Clemens, sorry but uWSGI 1.0 is unsupported since 2012 and know to be<br>
broken (as well as 1.2). Only 1.4.x and 2.0.x are supported and actively<br>
maintained.<br>
<br>
Upgrade to a stable version, and if you still have problems feel free to<br>
repost.<br>
<span class="HOEnZb"><font color="#888888"><br>
<br>
--<br>
Roberto De Ioris<br>
<a href="http://unbit.it" target="_blank">http://unbit.it</a><br>
_______________________________________________<br>
uWSGI mailing list<br>
<a href="mailto:uWSGI@lists.unbit.it">uWSGI@lists.unbit.it</a><br>
<a href="http://lists.unbit.it/cgi-bin/mailman/listinfo/uwsgi" target="_blank">http://lists.unbit.it/cgi-bin/mailman/listinfo/uwsgi</a><br>
</font></span></blockquote></div><br><br clear="all"><div><br></div>-- <br><div dir="ltr"><div>Clemens Kolbitsch</div><div>Security Researcher</div><div><a href="mailto:kolbitsch@lastline.com" target="_blank">kolbitsch@lastline.com</a></div>

<div>Mobile +1 (206) 356-7745</div><div>Land +1 (805) 456-7076<br></div><div><br></div><div>Lastline, Inc.</div><div>6950 Hollister Avenue, Suite 101</div><div>Goleta, CA 93117</div><div><br></div><div><a href="http://www.lastline.com" target="_blank">www.lastline.com</a></div>

</div>
</div>