diff --git a/docs/becomingbig.rst b/docs/becomingbig.rst index 8ad125de..916aa324 100644 --- a/docs/becomingbig.rst +++ b/docs/becomingbig.rst @@ -3,54 +3,74 @@ Becoming Big ============ -Your application is becoming more and more complex? Flask is really not -designed for large scale applications and does not attempt to do so, but -that does not mean you picked the wrong tool in the first place. +Your application is becoming more and more complex? If you suddenly +realize that Flask does things in a way that does not work out for your +application there are ways to deal with that. Flask is powered by Werkzeug and Jinja2, two libraries that are in use at a number of large websites out there and all Flask does is bring those -two together. Being a microframework, Flask is literally a single file. -What that means for large applications is that it's probably a good idea -to take the code from Flask and put it into a new module within the -applications and expand on that. +two together. Being a microframework Flask does not do much more than +combinding existing libraries - there is not a lot of code involved. +What that means for large applications is that it's very easy to take the +code from Flask and put it into a new module within the applications and +expand on that. -What Could Be Improved? ------------------------ +Flask is designed to be extended and modified in a couple of different +ways: -For instance it makes a lot of sense to change the way endpoints (the -names of the functions / URL rules) are handled to also take the module -name into account. Right now the function name is the URL name, but -imagine you have a large application consisting of multiple components. -In that case, it makes a lot of sense to use dotted names for the URL -endpoints. +- Subclassing. The majority of functionality can be changed by creating + a new subclass of the :class:`~flask.Flask` class and overriding + some methods. -Here are some suggestions for how Flask can be modified to better -accommodate large-scale applications: +- Flask extensions. For a lot of reusable functionality you can create + extensions. -- get rid of the decorator function registering which causes a lot - of troubles for applications that have circular dependencies. It - also requires that the whole application is imported when the system - initializes or certain URLs will not be available right away. A - better solution would be to have one module with all URLs in there and - specifying the target functions explicitly or by name and importing - them when needed. -- switch to explicit request object passing. This requires more typing - (because you now have something to pass around) but it makes it a - whole lot easier to debug hairy situations and to test the code. -- integrate the `Babel`_ i18n package or `SQLAlchemy`_ directly into the - core framework. +- Forking. If nothing else works out you can just take the Flask + codebase at a given point and copy/paste it into your application + and change it. Flask is designed with that in mind and makes this + incredible easy. You just have to take the package and copy it + into your application's code and rename it (for example to + `framework`). Then you can start modifying the code in there. -.. _Babel: http://babel.edgewall.org/ -.. _SQLAlchemy: http://www.sqlalchemy.org/ +Why consider Forking? +--------------------- -Why does Flask not do all that by Default? ------------------------------------------- +The majority of code of Flask is within Werkzeug and Jinja2. These +libraries do the majority of the work. Flask is just the paste that glues +those together. For every project there is the point where the underlying +framework gets in the way (due to assumptions the original developers +had). This is natural because if this would not be the case, the +framework would be a very complex system to begin with which causes a +steep learning curve and a lot of user frustration. -There is a huge difference between a small application that only has to -handle a couple of requests per second and with an overall code complexity -of less than 4000 lines of code and something of larger scale. At some -point it becomes important to integrate external systems, different -storage backends and more. +This is not unique to Flask. Many people use patched and modified +versions of their framework to counter shortcomings. This idea is also +reflected in the license of Flask. You don't have to contribute any +changes back if you decide to modify the framework. -If Flask was designed with all these contingencies in mind, it would be a -much more complex framework and harder to get started with. +The downside of forking is of course that Flask extensions will most +likely break because the new framework has a different import name and +because of that forking should be the last resort. + +Scaling like a Pro +------------------ + +For many web applications the complexity of the code is less an issue than +the scaling for the number of users or data entries expected. Flask by +itself is only limited in terms of scaling by your application code, the +data store you want to use and the Python implementation and webserver you +are running on. + +Scaling well means for example that if you double the amount of servers +you get about twice the performance. Scaling bad means that if you add a +new server the application won't perform any better or would not even +support a second server. + +There is only one limiting factor regarding scaling in Flask which are +the context local proxies. They depend on context which in Flask is +defined as being either a thread or a greenlet. Separate processes are +fine as well. If your server uses some kind of concurrency that is not +based on threads or greenlets, Flask will no longer be able to support +these global proxies. However the majority of servers are using either +threads, greenlets or separate processes to achieve concurrency which are +all methods well supported by the underlying Werkzeug library. diff --git a/docs/foreword.rst b/docs/foreword.rst index de6b4980..6b9d99b2 100644 --- a/docs/foreword.rst +++ b/docs/foreword.rst @@ -17,24 +17,20 @@ may be necessary in larger or more complex applications. For example, Flask uses thread-local objects internally so that you don't have to pass objects around from function to function within a request in order to stay threadsafe. While this is a really easy approach and saves -you a lot of time, it also does not scale well to large applications. -It's especially painful for more complex unittests, and when you suddenly -have to deal with code being executed outside of the context of a request, -such as in cron jobs. +you a lot of time, it might also cause some troubles for very large +applications because changes on these thread-local objects can happen +anywhere in the same thread. -Flask provides some tools to deal with the downsides of this approach, but -the core problem remains. Flask is also based on convention over -configuration, which means that many things are preconfigured and will -work well for smaller applications but not so well for larger ones. For -example, by convention, templates and static files are in subdirectories -within the Python source tree of the application. +Flask provides some tools to deal with the downsides of this approach but +it might be an issue for larger applications. Flask is also based on +convention over configuration, which means that many things are +preconfigured and will work well for smaller applications but not so well +for larger ones. For example, by convention, templates and static files +are in subdirectories within the Python source tree of the application. -But don't worry if your application suddenly grows larger -and you're afraid Flask might not grow with it. Even with -larger frameworks, you'll eventually discover that you need -something the framework just cannot do for you without modification. -If you are ever in that situation, check out the :ref:`becomingbig` -chapter. +However Flask is not much code and built in a very solid foundation and +with that very easy to adapt for large applications. If you are +interested in that, check out the :ref:`becomingbig` chapter. A Framework and an Example --------------------------