Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(dependencies): skip doing any work when sub dependant is already cached #11323

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 11 additions & 7 deletions fastapi/dependencies/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -542,13 +542,21 @@ async def solve_dependencies(
response = Response()
del response.headers["content-length"]
response.status_code = None # type: ignore
dependency_cache = dependency_cache or {}
if dependency_cache is None:
dependency_cache = {}
sub_dependant: Dependant
for sub_dependant in dependant.dependencies:
sub_dependant.call = cast(Callable[..., Any], sub_dependant.call)
sub_dependant.cache_key = cast(
Tuple[Callable[..., Any], Tuple[str]], sub_dependant.cache_key
)

# If the dependant is already cached, skip doing any more work
if sub_dependant.use_cache and sub_dependant.cache_key in dependency_cache:
if sub_dependant.name is not None:
values[sub_dependant.name] = dependency_cache[sub_dependant.cache_key]
continue

call = sub_dependant.call
use_sub_dependant = sub_dependant
if (
Expand Down Expand Up @@ -581,16 +589,12 @@ async def solve_dependencies(
sub_values,
sub_errors,
background_tasks,
_, # the subdependency returns the same response we have
sub_dependency_cache,
*_, # the subdependency returns the same response and cache we already have
) = solved_result
dependency_cache.update(sub_dependency_cache)
if sub_errors:
errors.extend(sub_errors)
continue
if sub_dependant.use_cache and sub_dependant.cache_key in dependency_cache:
solved = dependency_cache[sub_dependant.cache_key]
elif is_gen_callable(call) or is_async_gen_callable(call):
if is_gen_callable(call) or is_async_gen_callable(call):
solved = await solve_generator(
call=call, stack=async_exit_stack, sub_values=sub_values
)
Expand Down