That said, with no offense intended to mirman, I'd really hesitate before using this for anything serious enough to reach that scale in the first place. Gevent, frankly, visibly pushes Python to the limits (and occasionally a bit beyond), trying to also tack on some preemption on an environment not fundamentally expecting it would scare me another notch.
There is a version in the history that used Greenlet instead of gevent which was potentially a bit less delicate, but it required wrapping of the main file and didn't work with time.sleep, and I didn't feel like it was worth writing my own locks, semaphores, mutexes, pipes and whatnot.
http://hackage.haskell.org/packages/archive/forkable-monad/0...
Also, this doesn't implement some stuff from gevent, it implements some stuff over and using gevent.
Version negative one? I don't think I've ever seen that before. Usually, the very earliest versions of software are numbered like 0.0.1 or something like that.
The disillusionment caused by having so many options for non-parallel "concurrency" in Python is, I believe, feeding the high defection rate from Python to Go.
Many of the people complaining about this issue don't have a demonstrated problem and could try any simple approach first (if the point is not just to slam Python in favor of something else, from the beginning).
Yes, you absolutely can use all your cores by combining multiprocess, gevent and custom C code. But, debugging that stack of a level of hell I will never return too, ever.
Different kind of user, but... just sayin
If I'd had the option to switch us to stackless easily, and I could guarantee it was as fast, worked with all the libraries, and was as stable, I probably wouldn't have written this. I imagine that there are a lot of people in the same boat, where switching interpreters isn't really an option.
This isn't true concurrency. Scaling to 20 million requests per second over 40 cores on a single machine is true concurrency.
[1] http://en.wikipedia.org/wiki/Concurrency_(computer_science)
As someone who has had to ship stuff using multiprocess & gevent to actually meet real world scaling needs -- and integrating them with C code and communicating to a C++ application via ZMQ (inprocess by sharing the object) ... the sad fact is once we started to tackle really hard problems in Python that aren't pre-solved via a nice library all those early advantages fell away and we craved the blessed simplicity of C++ (note: sarcasm, C++ isn't simple, but it was far simpler than the Frankenstein's monster we built).
I am not really a Go proponent. I'm a Haskell user, personally, and Haskell, like Python, has three or four options that require understanding to choose and apply. The difference there being that in Haskell, each one of them actually gets you real parallelism, no fine print necessary. I bring it up to point out that the situation with Python is not a good example of what you might call "intrinsic complexity" (as you seem to be implying) or the Go solution would not be so much simpler, nor is it really an example of there being many better higher-level abstractions, or more of them would resemble Haskell's many high-level options. It is simply a bad situation that produces many poor kludges, and the mentality that everything is fine is (in my opinion) feeding a substantial defection rate to Go.
Why should somebody who wants to use threading have to know how to write a preemptive scheduler? If you want a tutorial in addition to the library thats fine, but many good tutorials also release their code as libraries. In open source world, releasing code as a library does not mean having to keep people from understanding the workings of that code. Why should people HAVE to learn how the code works to use it though?
You can hack around many of them, but you eventually hit a wall, and the effort of the hack increases rapidly.
Note I didn't really use gevent in this reply, this is just about cooperative scheduling. There's a reason why we've all but completely abandoned it at the OS level for things we'd call "computers" (as opposed to "embedded systems" or "microcontrollers", etc). I tend to consider cooperative scheduling an enormous red flag in any system that uses it... and yes, that completely and fully includes the currently-popular runtimes that use it.
This library is probably nice for the places I would otherwise use threads.
But what a "thing" and how long a period is are up for grabs. If we choose period to be anything longer than 1 millisecond, then this library will finish executing both things in that time period.
http://stackoverflow.com/questions/1050222/concurrency-vs-pa...
If one of them should mean one thing and the other the other why not have the one that literally means at the same time for the term that means at the same time. And have the one that means non intersecting mean threads of execution that are beside each other but not touching without lots of pain and suffering. Sorry, rant bit off.
That's called a lingo or a jargon (in this case, programmer lingo), and it involves making up words or having a different definition for a given word in the correct context.
I'm not sure why it is difficult to do this sort of thing correctly. The scheduler does next to nothing in the "server with connections managed in coroutines" case and probably makes matters worse in the "storing game state in execution states" case. It could have a positive impact in the server application if one routine is secretly going to crash or run forever, in the sense that the other routines will continue running while the problematic feature is fenced off or fixed.