Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> No need for forkingFire up a few processes

First, forking is "firing up a few processes". Yes, you can do that prior to launching your process, and then let gevent just have the process, but you have to be able to do that, and it just doesn't make sense in all contexts. This is what I meant by gevent fights composability.

> or threads

There's a limit to what a single CPU can do, and eventually multiple hardware threads can buy you actual tangible results.

> Yeah there's limitations when CPU bound, but that's python.

My point being that it's very difficult to get to CPU bound when your greenlet library prevents you from taking advantage of threads or processes. "but that's python" implies to me that you think Python is hamstrung to a single thread, and that's not the case: Python is quite capable of not only hardware threads, but performing computation on hardware threads in parallel, simply because not all of my code is in Python. Sometimes, a component knows it needs an honest-to-god HW thread, and the monkey patching fights that.

HW threads additionally lets you run multiple-long running computations; even if they're mutually bound to a single CPU, preemptive multitasking at the OS level (and Python's interpreter occasionally releasing the GIL) will ensure they all get time. In a cooperative greenlet, if you do not yield, you starve the other threads. A library making a long running computation again needs intimate knowledge that at the higher level, greenlets are in use: this breaks layers and mixes responsibilities (greenlets) in where it doesn't belong (some library calculating a thing). Greenlets do not compose.

> We've switched to pure python versions of a few libraries.

And you pretty much have to; if the library called out to C, it would block. But this fights good engineering practices: you can't just implement your library once in the language of choice, and then bind it into another language.

> When not available use a pool of instances.

This depends on what the library does; a "pool" does not necessarily save you. For example, if the library blocks, you need a threadpool (a real one) to process inputs to it.

Libraries exposing an event loop, perhaps with some basic primitives, have a hope of communicating across things like language barriers.



Excellent points, thanks for the thoughtful response. I suppose it depends on the use case and certainly there are limits to gevent, but for our use case--serving and routing web requests, they rarely come up and are easily worked around. In some cases these pain points can be avoided by only patching the libraries you need rather than monkey.patch_all(), other times we can just spawn another process to do the work. I can appreciate that there are workloads where asyncio is better suited than gevent, but gevent is just so easy.

We communicate across languages quite a bit using sockets. A given system may have 20 processes that communicate with each other and the outside world. Most but not all of the python processes use gevent. Composing software with sockets scales well and avoids compatibility issues. It's rare for our python processes to be cpu (or core) bound, but it's easy to be IO bound and that's what gevent solves.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: