<div dir="ltr"><div>On Tue, Jun 7, 2016 at 4:26 PM, Ben Meyer <span dir="ltr"><<a href="mailto:ben.meyer@rackspace.com" target="_blank">ben.meyer@rackspace.com</a>></span> wrote:<br></div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><span class="">On 06/07/2016 06:09 PM, Samuel Merritt wrote:<br>
> On 6/7/16 12:00 PM, Monty Taylor wrote:<br>
>> [snip]<br>
> ><br>
>> I'd rather see us focus energy on Python3, asyncio and its pluggable<br>
>> event loops. The work in:<br>
>><br>
>> <a href="http://magic.io/blog/uvloop-blazing-fast-python-networking/" rel="noreferrer" target="_blank">http://magic.io/blog/uvloop-blazing-fast-python-networking/</a><br>
>><br>
>> is a great indication in an actual apples-to-apples comparison of what<br>
>> can be accomplished in python doing IO-bound activities by using modern<br>
>> Python techniques. I think that comparing python2+eventlet to a fresh<br>
>> rewrite in Go isn't 100% of the story. A TON of work has gone in to<br>
>> Python that we're not taking advantage of because we're still supporting<br>
>> Python2. So what I've love to see in the realm of comparative<br>
>> experimentation is to see if the existing Python we already have can be<br>
>> leveraged as we adopt newer and more modern things.<br>
><br>
> Asyncio, eventlet, and other similar libraries are all very good for<br>
> performing asynchronous IO on sockets and pipes. However, none of them<br>
> help for filesystem IO. That's why Swift needs a golang object server:<br>
> the go runtime will keep some goroutines running even though some<br>
> other goroutines are performing filesystem IO, whereas filesystem IO<br>
> in Python blocks the entire process, asyncio or no asyncio.<br>
<br>
</span>That can be modified. gevent has a tool<br>
(<a href="http://www.gevent.org/gevent.fileobject.html" rel="noreferrer" target="_blank">http://www.gevent.org/gevent.fileobject.html</a>) that enables the File IO<br>
to be async  as well by putting the file into non-blocking mode. I've<br>
used it, and it works and scales well.<br>
<br>
Sadly, Python doesn't offer this by default; perhaps OpenStack can get<br>
that changed.<br>
<br>
$0.02<br>
<span class=""><font color="#888888"><br>
Ben<br>
</font></span><div class=""><div class="h5"><br></div></div></blockquote><div><br></div>The uvloop library is very new, but libuv itself uses a thread pool, so it should work just fine with files once this functionality is implemented; see <a href="https://github.com/MagicStack/uvloop/issues/1">https://github.com/MagicStack/uvloop/issues/1</a> and <a href="https://nikhilm.github.io/uvbook/filesystem.html">https://nikhilm.github.io/uvbook/filesystem.html</a><div><br></div><div>I don't see any difference here with how Golang would implement such async support, in terms of mapping goroutines against its own thread pool. With respect to latency, there could even be better performance for certain workloads with uvloop than Go. This is because of CPython's refcounting, vs Go's GC - even with all the recent improvements in Go (<a href="https://blog.golang.org/go15gc">https://blog.golang.org/go15gc</a>), Go still does stop the world.<div><div><br></div><div>A key piece here is that uvloop does not hold the GIL in these ops - a big advantage that Python C extensions enjoy, including libraries they wrap, and Cython explicitly enables with nogil support. So in particular we have the following code in the the core uvloop function, which in turn is just calling into libuv with its own core function, uv_run:</div><div><br></div><div>```</div><div><div>        # Although every UVHandle holds a reference to the loop,</div><div>        # we want to do everything to ensure that the loop will</div><div>        # never deallocate during the run -- so we do some</div><div>        # manual refs management.</div><div>        Py_INCREF(self)</div><div>        with nogil:</div><div>            err = uv.uv_run(self.uvloop, mode)</div><div>        Py_DECREF(self)</div></div><div>```</div><div><br></div></div></div><div>More here on nogil support in Cython: <a href="http://docs.cython.org/src/userguide/external_C_code.html#declaring-a-function-as-callable-without-the-gil">http://docs.cython.org/src/userguide/external_C_code.html#declaring-a-function-as-callable-without-the-gil</a></div><div><br></div><div>- Jim</div></div></div></div>