test and documentation
This commit is contained in:
parent
f4e700c1f3
commit
1fc69bd3f4
4 changed files with 48 additions and 0 deletions
|
|
@ -3,6 +3,8 @@ Version 3.2.0
|
||||||
|
|
||||||
Unreleased
|
Unreleased
|
||||||
|
|
||||||
|
- Optimize request dispatching by caching the result of ``ensure_sync`` for view
|
||||||
|
functions in ``_sync_view_functions``, reducing CPU overhead. :issue:`9999`
|
||||||
- Drop support for Python 3.9. :pr:`5730`
|
- Drop support for Python 3.9. :pr:`5730`
|
||||||
- Remove previously deprecated code: ``__version__``. :pr:`5648`
|
- Remove previously deprecated code: ``__version__``. :pr:`5648`
|
||||||
- ``RequestContext`` has merged with ``AppContext``. ``RequestContext`` is now
|
- ``RequestContext`` has merged with ``AppContext``. ``RequestContext`` is now
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,10 @@ the decorated function,
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
To improve performance, consider caching the result of ``ensure_sync`` if your
|
||||||
|
extension calls it frequently on the same function. This is how Flask internally
|
||||||
|
optimizes request dispatching.
|
||||||
|
|
||||||
Check the changelog of the extension you want to use to see if they've
|
Check the changelog of the extension you want to use to see if they've
|
||||||
implemented async support, or make a feature request or PR to them.
|
implemented async support, or make a feature request or PR to them.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -971,6 +971,10 @@ class Flask(App):
|
||||||
be a response object. In order to convert the return value to a
|
be a response object. In order to convert the return value to a
|
||||||
proper response object, call :func:`make_response`.
|
proper response object, call :func:`make_response`.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.2
|
||||||
|
The result of ``ensure_sync`` is cached in ``_sync_view_functions``
|
||||||
|
to improve performance.
|
||||||
|
|
||||||
.. versionchanged:: 0.7
|
.. versionchanged:: 0.7
|
||||||
This no longer does the exception handling, this code was
|
This no longer does the exception handling, this code was
|
||||||
moved to the new :meth:`full_dispatch_request`.
|
moved to the new :meth:`full_dispatch_request`.
|
||||||
|
|
@ -1077,6 +1081,10 @@ class Flask(App):
|
||||||
|
|
||||||
Override this method to change how the app runs async views.
|
Override this method to change how the app runs async views.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.2
|
||||||
|
The result of this method is cached during request dispatching
|
||||||
|
to improve performance.
|
||||||
|
|
||||||
.. versionadded:: 2.0
|
.. versionadded:: 2.0
|
||||||
"""
|
"""
|
||||||
if iscoroutinefunction(func):
|
if iscoroutinefunction(func):
|
||||||
|
|
|
||||||
|
|
@ -1968,3 +1968,37 @@ def test_app_freed_on_zero_refcount():
|
||||||
assert weak() is None
|
assert weak() is None
|
||||||
finally:
|
finally:
|
||||||
gc.enable()
|
gc.enable()
|
||||||
|
|
||||||
|
|
||||||
|
def test_sync_view_functions_cache(app, client):
|
||||||
|
"""Test that the _sync_view_functions cache is populated and used."""
|
||||||
|
@app.route("/test")
|
||||||
|
def test_view():
|
||||||
|
return "Hello"
|
||||||
|
|
||||||
|
import unittest.mock
|
||||||
|
|
||||||
|
with unittest.mock.patch.object(app, 'ensure_sync', wraps=app.ensure_sync) as mock_ensure_sync:
|
||||||
|
# First request should call ensure_sync
|
||||||
|
response = client.get("/test")
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert mock_ensure_sync.call_count == 1
|
||||||
|
|
||||||
|
# Second request should hit the cache and not call ensure_sync
|
||||||
|
response = client.get("/test")
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert mock_ensure_sync.call_count == 1
|
||||||
|
|
||||||
|
# Direct mutation test (to verify the cache is bound to endpoint)
|
||||||
|
def new_view():
|
||||||
|
return "World"
|
||||||
|
|
||||||
|
# Simulating a user directly updating the view functions after setup
|
||||||
|
# Because it's already cached, this mutation won't affect _sync_view_functions
|
||||||
|
app.view_functions["test"] = new_view
|
||||||
|
|
||||||
|
# Ensure that it still returns the old result due to the cache
|
||||||
|
response = client.get("/test")
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert response.data == b"Hello"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue