Repository navigation
docs: share a container with manage_lifespan=False and one owner - #702
Merged
Merged
Conversation
There was a problem hiding this comment.
Benchmark
Details
| Benchmark suite | Current: 533b813 | Previous: d5d167e | Ratio |
|---|---|---|---|
benchmarks/test_guard_by_type.py::test_g16_resolve_by_type |
3259300.1768232496 iter/sec (stddev: 1.1719772210567866e-8) |
6614892.345319018 iter/sec (stddev: 1.0929152659504707e-8) |
2.03 |
benchmarks/test_guard_by_type.py::test_g17_resolve_by_type_large_registry |
3257169.632932509 iter/sec (stddev: 1.2026941281055951e-8) |
6234973.324590048 iter/sec (stddev: 1.5000817187998557e-8) |
1.91 |
benchmarks/test_guard_cold.py::test_g8_cold_first_resolve |
16043.618361941204 iter/sec (stddev: 0.000053905631977389955) |
22188.514415505066 iter/sec (stddev: 0.000035116159669307494) |
1.38 |
benchmarks/test_guard_cold.py::test_g8b_cold_first_resolve_cached |
12719.789967340052 iter/sec (stddev: 0.00013230822904484915) |
17848.38733805733 iter/sec (stddev: 0.00012983775205901163) |
1.40 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[1] |
480.6872461432672 iter/sec (stddev: 0.00003921777607523051) |
882.4458447040489 iter/sec (stddev: 0.00005007895117263565) |
1.84 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[2] |
467.6135557646355 iter/sec (stddev: 0.000051572333286011216) |
815.1451369162148 iter/sec (stddev: 0.00006205129290350007) |
1.74 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[4] |
438.0726997417211 iter/sec (stddev: 0.00005835652527176934) |
771.9224829291804 iter/sec (stddev: 0.000051560288745671776) |
1.76 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[1] |
13414.01265768367 iter/sec (stddev: 0.000008120819925014643) |
10718.050429434346 iter/sec (stddev: 0.00001405952819628994) |
0.80 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[2] |
6308.629511387363 iter/sec (stddev: 0.000011799316533338899) |
5194.4762113398365 iter/sec (stddev: 0.000055616411227824346) |
0.82 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[4] |
3403.9139621161685 iter/sec (stddev: 0.000038623879832138995) |
2766.1713199048672 iter/sec (stddev: 0.00006770754223448173) |
0.81 |
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[1] |
8627.038461471422 iter/sec (stddev: 0.00003102300534651064) |
10006.776255353865 iter/sec (stddev: 0.000012485493400864475) |
1.16 |
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[2] |
4391.261871833296 iter/sec (stddev: 0.00002488832729008276) |
3966.2898415947802 iter/sec (stddev: 0.000021012149128388896) |
0.90 |
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[4] |
2046.054469545547 iter/sec (stddev: 0.000045198401763239224) |
1990.070113983001 iter/sec (stddev: 0.00007702623055312865) |
0.97 |
benchmarks/test_guard_concurrency.py::test_g15c_worker_pool_floor_control[1] |
41467.03457175756 iter/sec (stddev: 0.000004899712713012755) |
18289.568681821627 iter/sec (stddev: 0.000003670232355104127) |
0.44 |
benchmarks/test_guard_concurrency.py::test_g15c_worker_pool_floor_control[2] |
14047.378764223864 iter/sec (stddev: 0.00001286433936985704) |
12746.041079554532 iter/sec (stddev: 0.000013321275657479497) |
0.91 |
benchmarks/test_guard_concurrency.py::test_g15c_worker_pool_floor_control[4] |
5721.764332720986 iter/sec (stddev: 0.00003848276870980056) |
5414.373265965316 iter/sec (stddev: 0.00004619088497537116) |
0.95 |
benchmarks/test_guard_lifecycle.py::test_g6_build_child_container |
1514014.1120381148 iter/sec (stddev: 3.079944351938926e-8) |
2557016.6775028585 iter/sec (stddev: 2.249113177769194e-8) |
1.69 |
benchmarks/test_guard_lifecycle.py::test_g6b_build_child_container_auto_scope |
1654528.8363356777 iter/sec (stddev: 2.852479804880834e-8) |
2864672.8543470814 iter/sec (stddev: 2.0401720220810464e-8) |
1.73 |
benchmarks/test_guard_lifecycle.py::test_g7_request_lifecycle_batch |
3092.0122701103733 iter/sec (stddev: 0.00001790983371216991) |
4668.377147152932 iter/sec (stddev: 0.000006594970554881534) |
1.51 |
benchmarks/test_guard_lifecycle.py::test_g7c_event_loop_floor_control |
57543.04051602528 iter/sec (stddev: 0.0000027482937998829485) |
90763.94329114971 iter/sec (stddev: 0.000001244606839229857) |
1.58 |
benchmarks/test_guard_lifecycle.py::test_g7b_request_cycle_sync |
410995.6713360705 iter/sec (stddev: 1.1715315346288843e-7) |
627221.9140280918 iter/sec (stddev: 8.339147924090178e-8) |
1.53 |
benchmarks/test_guard_lifecycle.py::test_g13_teardown_at_scale |
65028.907015270845 iter/sec (stddev: 0.00000201470169427272) |
98973.4349339857 iter/sec (stddev: 9.675758960576356e-7) |
1.52 |
benchmarks/test_guard_lifecycle.py::test_g13b_teardown_at_scale_async_no_finalizers |
582.8698334351706 iter/sec (stddev: 0.000977979433943244) |
891.6048760363765 iter/sec (stddev: 0.0009891898261389358) |
1.53 |
benchmarks/test_guard_resolve.py::test_g1_transient_resolve |
2108443.8008126174 iter/sec (stddev: 3.643590676888671e-8) |
3829164.872535829 iter/sec (stddev: 2.4671036532409833e-8) |
1.82 |
benchmarks/test_guard_resolve.py::test_g2_cached_resolve |
3613779.746849006 iter/sec (stddev: 1.2500530253088961e-8) |
6472059.600973104 iter/sec (stddev: 1.4100226005685917e-8) |
1.79 |
benchmarks/test_guard_resolve.py::test_g3_deep_chain |
802555.9802833487 iter/sec (stddev: 4.1555770256427324e-8) |
1393881.1128142371 iter/sec (stddev: 4.6755047461464293e-8) |
1.74 |
benchmarks/test_guard_resolve.py::test_g4_wide_resolve |
476283.60097498784 iter/sec (stddev: 4.0725578228055595e-7) |
761653.8658615567 iter/sec (stddev: 3.247565662466623e-7) |
1.60 |
benchmarks/test_guard_resolve.py::test_g5_cross_scope |
1956331.2626113317 iter/sec (stddev: 4.0088335496065334e-8) |
3182317.263195788 iter/sec (stddev: 2.2342043632675758e-8) |
1.63 |
benchmarks/test_guard_resolve.py::test_g9_context_resolve |
1393082.1144191835 iter/sec (stddev: 1.4438867520740004e-7) |
2475931.316943801 iter/sec (stddev: 1.132751206586173e-7) |
1.78 |
benchmarks/test_guard_resolve.py::test_g12_override_active_resolve |
823986.1715401643 iter/sec (stddev: 6.172730512737653e-8) |
1409484.491617221 iter/sec (stddev: 2.9863822030957385e-8) |
1.71 |
benchmarks/test_guard_resolve.py::test_g18_alias_hop |
3422156.8986208234 iter/sec (stddev: 1.8967016775463708e-8) |
6193888.403586523 iter/sec (stddev: 1.247957913272508e-8) |
1.81 |
benchmarks/test_guard_validate.py::test_g10_validate_deep_chain |
35400.750120318604 iter/sec (stddev: 0.00001891294545171517) |
40436.505063159784 iter/sec (stddev: 0.00025723935944531166) |
1.14 |
benchmarks/test_guard_validate.py::test_g11_validate_wide |
21474.10404489243 iter/sec (stddev: 0.00002358850422808318) |
30723.64444381395 iter/sec (stddev: 0.000017359402832119415) |
1.43 |
This comment was automatically generated by workflow using github-action-benchmark.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #701
Documents the decision in #701: no counted lifespan. Every integration that opens and closes the root has a keyword-only
manage_lifespan: bool = True, and withFalsethe user owns the root.Changes
providers/lifecycle.md: the docs: warn that apps sharing a root container close it for each other #700 caution now says a shared container needs one owner. Passmanage_lifespan=Falseto every integration that shares it and wrap the apps inasync with container:. Flask, gRPC and Typer never touch the root. Links the recipe.recipes/shared-container.md: a FastAPI app and a FastStream app on one container, both with the flag off. It covers the side-by-side case (asyncio.gatherofstream.run()and a uvicorn server) and the case where FastStream starts inside the FastAPI lifespan. APP finalizers run once, at the owner's exit. Hidden blocks check both cases withTestClient,TestNatsBrokerandTestApp.troubleshooting/container-closed-error.mdandproviders/context.md: the shared-container sentences name the flag and link the recipe.worker_process_shutdownhandler.conftest.py:faststreamanduvicornjoin the packages that skip injust test-docs. uvicorn comes in through modern-di-fastmcp injust test-docs-integrations, so the extras list is unchanged.The gather order differs from the issue
The issue shows
asyncio.gather(server.serve(), stream.run()). With both flags off, that order hangs on SIGTERM: FastStream'sloop.add_signal_handlerreplaces uvicorn's handler, so FastStream stops and uvicorn keeps serving. Withgather(stream.run(), server.serve()), uvicorn stops first, restores the earlier handler and raises the signal again, so FastStream stops after it. The container then closes once. I checked both orders with modern-di-fastapi 4.1.0, modern-di-faststream 4.1.0, uvicorn 0.54.0 and faststream 0.7.7. The recipe uses the working order and explains why.