Live data from Hacker News

Write Fast Apps Using Async Python 3.6 and Redis

eng.paxos.com

41–50 of 134 posts

Re: Write Fast Apps Using Async Python 3.6 and Redis

#41
post #3

We've just recently started using Sanic[0] paired with Redis to great effect for a very high throughput web service. It also uses Python 3 asyncio/uvloop at its core. So far very happy with it. [0] https://github.com/channelcat/sanic

problem with Sanic that it does not implement streaming properly. so it is very easy to kill any Sanic process, 10-20 seconds. again any.

Would you mind elaborating?

Re: Write Fast Apps Using Async Python 3.6 and Redis

#42
post #22

> we make heavy use of asyncio because it’s more performant more performant than....what exactly? If I need to load 1000 rows from a database and splash them on a webpage, will my response time go from the 300ms it takes without asyncio to something "more performant", like 50ms? Answer: no. async only gives you throughput, it has nothing to do with "faster" as far as the Python interpreter / GIL / anything like that.…

well it can also make things faster. well in your example it won't. but consider you need to load 4 requests and do operations on each of them. if you schedule them in an async fashion you can begin operating on the first one that's ready and not the first one you defined. and this is also often the case. a website does not just do one request to the database. mostly it runs multiple ones and often they don't interfere. like getting 20 rows and the count as a whole, there is just no need to start the first and wait till you have 20 rows and then start the second. you should always start both and wait till you have both.

yes it does not magically make your fetching 100 rows faster or your pbkdf2()/bcrypt() function. you still need to wait for those.

Re: Write Fast Apps Using Async Python 3.6 and Redis

#43
post #29

Earlier quoted context omitted.

Those benchmarks aren't any more standard than anything else.

Yes but you can see the most number of frameworks there running on the same hardware and same settings doing the same job. Also you can see the configuration how to achieve that.

except that various frameworks highly depend on their configuration/version/coding style/linux configuration/memory used/cpu's used/use case. it's also important that some frameworks behave better when they are warm. also some code behave's differently when you connect with a single client to make requests via wrk, vs a aggregate of multiple clients. they still use wrk and not wrk2, their error rate is pretty high and their framework is well not always well behaving.

besides all that, it's just simple cases that they are testing. I would never ever trust this site or any result they got.

Re: Write Fast Apps Using Async Python 3.6 and Redis

#45

Earlier quoted context omitted.

I have never found a good example of a Python web server that provides some mechanism for statefulness. Is it just fundamentally not possible to have shared state among requests handled by the threads of a process? Sanic's examples seem to be the same as Flask's: self-contained function calls attached to endpoints. I keep hitting a wall with Python when I want to do something like: 1. subscribe to a websocket connect…

You normally use something like redis to store the state. If you were going to share state in memory between threads, how would you handle the case where the second request goes to a different server or that the process has restarted? You'd need redis anyway, so you might as well just use it in all cases.

I get that everyone's responses are thinking some big public thing. I'm thinking small toy implementation for my home network.

The toy experiment is how to do what's trivial in Node with Python. Mainly because I like working with python. I think the answer might be: Python is the wrong tool for the job.

Re: Write Fast Apps Using Async Python 3.6 and Redis

#46
post #30

It seems strange that they would claim that Python's libuv based event loop is twice as fast as Node.js's libuv based event loop. There's some context missing to that statement or it's flat out false.

What does it even mean. The event loop is only used when there is nothing going on. Is it faster at doing nothing ?

> The event loop is only used when there is nothing going on.

In async applications event loop is what actually executes your code and performs IO. In essence, event loops are under load all the time.

Re: Write Fast Apps Using Async Python 3.6 and Redis

#47

Earlier quoted context omitted.

You normally use something like redis to store the state. If you were going to share state in memory between threads, how would you handle the case where the second request goes to a different server or that the process has restarted? You'd need redis anyway, so you might as well just use it in all cases.

I get that everyone's responses are thinking some big public thing. I'm thinking small toy implementation for my home network. The toy experiment is how to do what's trivial in Node with Python. Mainly because I like working with python. I think the answer might be: Python is the wrong tool for the job.

Erm, no. You can do shared thread storage, in Python, it's just that it doesn't really scale. I've done it for small daemons without significant hassle, and even wrote my own Go-like CSP helper: https://github.com/rcarmo/python-utils/blob/master/taskkit.p...

Re: Write Fast Apps Using Async Python 3.6 and Redis

#48
post #42
post #22

> we make heavy use of asyncio because it’s more performant more performant than....what exactly? If I need to load 1000 rows from a database and splash them on a webpage, will my response time go from the 300ms it takes without asyncio to something "more performant", like 50ms? Answer: no. async only gives you throughput, it has nothing to do with "faster" as far as the Python interpreter / GIL / anything like that.…

well it can also make things faster. well in your example it won't. but consider you need to load 4 requests and do operations on each of them. if you schedule them in an async fashion you can begin operating on the first one that's ready and not the first one you defined. and this is also often the case. a website does not just do one request to the database. mostly it runs multiple ones and often they don't interfe…

> if you schedule them in an async fashion you can begin operating on the first one that's ready and not the first one you defined.

This type of operation is a given in any production quality webserver, whether it runs with multiple threads and blocking IO or using a non-blocking approach with greenlets. For a web application, this is an implementation detail that should not be explicit within the request handling code (a request handled in the context of a web container after all is a package of data in, a package of data out. no network reading/writing is usually exposed to the web application unless it's trying to expose IO handles to the app, which is unusual). Easy enough with something like Gunicorn.

Re: Write Fast Apps Using Async Python 3.6 and Redis

#49
post #3

We've just recently started using Sanic[0] paired with Redis to great effect for a very high throughput web service. It also uses Python 3 asyncio/uvloop at its core. So far very happy with it. [0] https://github.com/channelcat/sanic

I have never found a good example of a Python web server that provides some mechanism for statefulness. Is it just fundamentally not possible to have shared state among requests handled by the threads of a process? Sanic's examples seem to be the same as Flask's: self-contained function calls attached to endpoints. I keep hitting a wall with Python when I want to do something like: 1. subscribe to a websocket connect…

Flask lets you share state between requests; just have the route methods reference some global variable. You could also apply the route decorator to an instance method (although probably not using the decorator syntax).

Re: Write Fast Apps Using Async Python 3.6 and Redis

#50

Earlier quoted context omitted.

You normally use something like redis to store the state. If you were going to share state in memory between threads, how would you handle the case where the second request goes to a different server or that the process has restarted? You'd need redis anyway, so you might as well just use it in all cases.

I get that everyone's responses are thinking some big public thing. I'm thinking small toy implementation for my home network. The toy experiment is how to do what's trivial in Node with Python. Mainly because I like working with python. I think the answer might be: Python is the wrong tool for the job.

The problem is that accessing shared state concurrently in a multi-process context is a non-trivial problem, so specific software emerged that handles these problems for you.

The simplest solution is to use a small DB system like sqlite. It is built into Python (import sqlite3) performs reasonably well and you do not have to run an additional service.

Now if a small DB like sqlite already feels overblown to you (and it really is simple and small) you might not need concurrent access either, so the simplest solution is to just use a file where you store your state.

Post reply on HN