4 ms·
The restart isn't expensive in absolute terms, on a human level it's practically instant. You would only do this during development, hopefully your local machin
by onetoo 3y ago
The restart isn't expensive in absolute terms, on a human level it's practically instant. You would only do this during development, hopefully your local machine isn't the production environment.
It's also very easy, often just adding a CLI flag to your local run command.
edit: Regarding performance, Python today can easily handle at least 1k requests per second. The vast vast vast majority of web applications today don't need anywhere near that kind of performance.
- ubercore 3y agoBeen working with python for the web for over a decade. This is basically a solved issue, and the performance is a non-issue day to day.
- mg 3y agoThe thing is, I don't run my applications locally with a "local run command". I prefer to have a local system set up just like the production server, but in a container. Maybe using WSGI with MaxConnectionsPerChild=1 could be a solution? But that would start a new (for example) Django instance for every request. Not sure how fast Django starts. Another option might be to send a HUP signal to Apache: apachectl -k restart That will only kill the worker threats. And when there are none (because another file save triggered it already), this operation might be almost free in terms of resource usage. This also would require WSGI or similar. Not sure if that is the standard approach for Django+Apache.
- deleted 3y ago[deleted]
- onetoo 3y agoI would still recommend running it properly locally, but whatever. Pseudo-devcontainer it is. I assume the code is properly volume mounted. In production, you would want to run your app through gunicorn/uvicorn/whatever on an internal-only port, and reverse-proxy to it with a public-facing apache or similar. Set up apache to reverse proxy like you would on prod, and run gunicorn/uvicorn l/whatever like you would on prod, except you also add the autoreload flag. E.g. uvicorn main:app --host 0.0.0.0 --port 12345 --reload If production uses containers, you should keep the python image slim and simple, including only gunicorn/uvicorn and have the reverse proxy in another container. Etc.
- traverseda 3y agoIs the problem you're having that you feel the need to expose a WSGI/ASGI interface instead of just a reverse proxy? Take a look at gunicorn, and for static files server you can use whitenoise. With those two you can just stand up an python program in a container that serves html, and put it behind whatever reverse proxy you want.
- edgyquant 3y agoI hate this argument that “most web apps don’t need that kind of performance.” For one thing, with responsive apps that are the norm it wouldn’t be surprising for a session to begin with multiple requests or to even have multiple requests per second. At that point all it takes is a few hundred active users to hit that 1k limit. But even leaving that aside, you never know when your application will be linked somewhere or go semi-viral and not being able to serve 1000 users is all it takes for your app to go down and your one shot at a successful company to die a sad death.
- onetoo 3y agoI didn't say python can handle <=1K, I was saying >=1K. I feel confident that I am orders of magnitude off the real limit you'd meet. The specifics of that aside, any unprepared application is going to buckle at a sudden mega-surge of users. The solution remains largely the same, regardless of technology: Make sure everything that can be cached is cached, scale the hardware vertically until it stops helping, optimize your code, scale horizontally until you run out of money. I imagine the DB will be the actual bottleneck, most of the time. There are other reasons to not choose python for greenfield application, but performance should rarely be one IMO.
- kstrauser 3y agoAt one shop, our load tests targeted 300,000 POST requests per second with a relatively small number of load balanced servers. You wouldn’t want to have a long, complex call path through that code, but just parsing the body and adding it to a Celery queue before returning a 201 Created was perfectly manageable.