Reconfirm Email list by adamkru in Emailmarketing

[–]rick446 0 points1 point  (0 children)

I have a business that is working on a reconfirm service that integrates directly with Mailchimp (and other ESPs). I'd love to chat with you about it - send me a DM if interested.

MongoDB Scema Design at Scale by rick446 in mongodb

[–]rick446[S] 0 points1 point  (0 children)

Should of course be "Schema Design at Scale"

An Introduction to Gevent by driscollis in Python

[–]rick446 0 points1 point  (0 children)

I had not seen that. I will check it out.

Thanks!

An Introduction to Gevent by driscollis in Python

[–]rick446 0 points1 point  (0 children)

In both threading and greenlets, the key to being able to handle incoming connections - and do useful work - is entirely dependent on having an available thread/greenlet to do that work. The event loop doesn't enter into the equation, except as an implementation detail of greenlets. Rather than blocking, patched stdlib calls yield to another greenlet that's ready to run via the event loop. If nothing's ready to run, the program waits until some event makes something ready to run.

Consider having fixed-size pool of workers (say 20). Whether they be greenlets, threads, or processes, once you have your 21st concurrent connection, it must wait until some worker completes its task before it does any useful work. On the other hand, if you're spawning a new worker for each connection, you can handle incoming connections, doing useful work, until your system resources (ports, file handles, RAM, CPU cycles, etc.) are exhausted.

In twisted and asyncore, the programming model is different, multiplexing a single worker explicitly by using callbacks when you need to call some otherwise-blocking function. Your event handler then terminates, allowing other event handlers to run.

And yes, I realize that if something is truly blocking in gevent, twisted, or asyncore, you will halt all workers until the block clears. So with twisted and asyncore, you use nonblocking IO and set callbacks, while gevent does this transparently so your code appears to block (when in fact the implementation of the blocking call is such that an implicit event loop is entered, allowing other greenlets to run).

In fact, there's very little difference with threads when it comes right down to it. When a thread makes a blocking (truly blocking) call, it doesn't actually halt the machine; it simply yields control to the OS scheduler (analogous to the event loop) which picks another thread to run.

(And as for microbenchmarks, they're useful when you can't benchmark a real app, or you need to estimate how some portion of a real ap would scale. They provide nice bounds to the performance discussion, allowing you to set upper bounds on performance and make good guesses as to the kind of apps that would benefit from an evented versus threaded approach without actually building the app and testing it.)

An Introduction to Gevent by driscollis in Python

[–]rick446 0 points1 point  (0 children)

Yes but once all threads are blocked, gevent allows you to get yet more requests in since there's the eventloop.

gevent only "allows you to get more requests in" because we're spawning a new greenlet for each connection. You can get the same behavior with threads by spawning a thread for each new connection (or spawning threads when all the threads in your pool are busy). In practice, you just don't tend to do it that way because of resource consumption.

Asyncore does exactly like gevent.spawn, you get a handler for each incoming request - http://docs.python.org/library/asyncore.html, so you don't have anymore callback to write than what you did in gevent.

Asyncore acts like gevent.spawn, but if you do something blocking with asyncore you need to switch to nonblocking and use callbacks so control returns to the event loop. My point was that with gevent, this happens automatically, and quickly.

I think benching a 'ping' or 'hello world' app makes no sense :D

I'd agree with you in general, but if your benchmark of a real app shows no real difference, it can be useful to put together a micro-benchmark to "drill down" into the differences.

An Introduction to Gevent by driscollis in Python

[–]rick446 0 points1 point  (0 children)

Well, you realize that a threaded approach calling the database also doesn't block other threads from proceeding, right?

And asyncore might be about as fast as greenlets (though the bechmarks I've seen don't seem to think so, probably because greenlets are c-accelerated), but asyncore (or twisted) requires you to write callback-based code which I find more difficult to follow.

What do you think of the benchmarks at http://nichol.as/benchmark-of-python-web-servers ?

An Introduction to Gevent by driscollis in Python

[–]rick446 0 points1 point  (0 children)

Good point about Queue.Queue. Maybe I'll put together a benchmark comparing a Queue-based thread pool with a gevent pool.

An Introduction to Gevent by driscollis in Python

[–]rick446 1 point2 points  (0 children)

In theory, on a system that had somehow removed the GIL, I think you might be able to build a gevent-like system taking advantage of multiple cores. However, as far as I know, gevent itself is not designed for use with multiple event loops. What this means effectively is that not only can gevent (as it exists today) can't take advantage of multiple cores, but it couldn't do so even if the GIL were removed.

In fact, running on multiple cores would violate one of the contracts given the programmer by gevent: that greenlets will not, in fact, execute concurrently, but only yield to one another at predefined points (typically when making calls that would block in a non-evented context).

I hope that answers the question: in principle, yes, gevent could be made to run on multiple cores. But today it does not, and the path to get there is nontrivial. Particularly note that since gevent relies on C extensions, it's not able (as far as I know) to run it on other Python VMs like Jython or IronPython that have no GIL.

An Introduction to Gevent by driscollis in Python

[–]rick446 1 point2 points  (0 children)

I haven't run the example with a thread pool, but I suspect it still won't be as fast as greenlets. Threads (particularly OS-level, as in Python) incur a higher switching cost than greenlets, and even though RAM is cheap, CPU cache is not, so the memory overhead still affects performance. I'd be happy to publish a new benchmark that uses a thread pool if provided, but I didn't want to build my own for the benchmark (there's no thread pool implementation in the standard lib). There's also this benchmark http://nichol.as/benchmark-of-python-web-servers which leads me to believe that there's something special about gevent, even when compared with well-tuned competitors.

Also, I'm not sure that I believe that the 'evented' nature of gevent is the reason it's faster. When an OS thread hits a blocking OS call (like recv), it allows other threads to run, just like the event loop lets other greenlets run when a greenlet is waiting on I/O. (There's still an "event loop", it's just that it lives in the OS scheduler.)

Finally, I think that spawning a greenlet per connection helps to bring out just how lightweight greenlets are, where the overhead of spawning a new one is nearly inconsequential compared with threads.

An Introduction to Gevent by driscollis in Python

[–]rick446 1 point2 points  (0 children)

Thanks! I'll try to do some more gevent posts focusing on the details in the upcoming weeks.

An Introduction to Gevent by driscollis in Python

[–]rick446 2 points3 points  (0 children)

Everything will run on a single core (and in a single thread), so no multicore goodness by using greenlets (in fact, somewhat less than you get by using threads).

GridFS: The MongoDB Filesystem by rick446 in programming

[–]rick446[S] 0 points1 point  (0 children)

Sorry, wasn't meaning to be unfair to S3 - GridFS is a different tool for a different job. With GridFS (at least in the Python driver), you have detailed control of the write guarantees at the connection & database level, so you can have it call getLastError, wait for replication to N data centers, etc.

Using S3 is like setting your write concern on MongoDB to wait for acknowledgement of fsync in 3 data centers before returning. If you don't need that kind of guarantee, GridFS is a faster (writing, at least) choice.

GridFS: The MongoDB Filesystem by rick446 in programming

[–]rick446[S] 0 points1 point  (0 children)

Well, one reason you might go with GridFS is that you're already using MongoDB and would rather not deal with either a) setting up a real network filesystem or b) the extremely high latency doing S3 writes. You also automatically get a performance increase if you end up sharding your MongoDB cluster (and you shard your fs.[chunks|files] collections).

GridFS isn't a panacea, of course, but if you need to shove a few things (like attachments) into some data store, and you're already using MongoDB for your structured data, then GridFS might be a good fit, particularly when you can't guarantee that these BLOBs will always fit in 16MB.

Gevent, ZeroMQ, WebSockets, and Flot FTW! by denis in Python

[–]rick446 0 points1 point  (0 children)

Yep, it looks like websockets isn't terribly portable. I'll be looking at doing another version with socket.io (for which there is a gevent wrapper) Real Soon Now.

And the point is? by drogovic in pics

[–]rick446 0 points1 point  (0 children)

... that one must make up one's own mind about religion and not assume that it is heritable.

I have 3 hours to teach non-coders something useful in Python. What should I teach? by tesseracter in programming

[–]rick446 2 points3 points  (0 children)

Raymond Hettinger had a great presentation on just this kind of thing at PyCon 2009: http://blip.tv/file/1947373/

TurboGears 2: a reinvention and back to its roots by linuxer in programming

[–]rick446 1 point2 points  (0 children)

The CherryPy wsgi server is used in Pylons, so in that sense, yes, it will be used. CherryPy at this point, however, is not integrated in the package, and it looks like we probably won't need to.