Skip to content

docs: update aiogram, celery, flask and grpc pages for shutdown changes - #705

Merged
lesnik512 merged 1 commit into
mainfrom
docs/shutdown-order-2
Oct 17, 2026
Merged

lesnik512 merged 1 commit into
mainfrom
docs/shutdown-order-2

Conversation

@lesnik512

Copy link
Copy Markdown
Member

Docs for modern-di-aiogram 4.3.0, modern-di-celery 4.2.0, modern-di-flask 4.2.0 and modern-di-grpc 4.1.1.

aiogram: the root lifecycle section describes the 4.3.0 shutdown order. The plugin waits for updates in flight, then the dispatcher's and sub-routers' shutdown handlers run, then the root closes. It adds shutdown_timeout with a runnable example, says that manage_lifespan=False skips the wait, and links the README for what can close before the wait (the bot session in webhook mode). The API row has the new signature. The page does not quote the timeout warning text, because that text changed on main after 4.3.0.

celery: since 4.2.0 the root closes after every other worker_shutdown and worker_process_shutdown receiver, including ones connected after setup_di. The plugin moves its receiver to the end when the worker or child process starts, so the page says a receiver connected after that runs after the close. A warm shutdown lets running tasks finish before these signals are sent (WorkController.stop joins the blueprint before worker_shutdown). The API row is updated to match.

flask: since 4.2.0 every request hook can use the request container whatever its registration order. The child is built on first use, and the close runs after every teardown_appcontext handler. A warning covers the stream_with_context issue on Flask 3.1.2 and later, which 4.1.0 has too.

grpc: the sync example now ends with try/finally, server.stop(grace=5).wait() and container.close_sync(), as the 4.1.1 README does. The root lifecycle section explains that in prose and gives the grpc.aio calls, in place of the separate code block. The invisible blocks reopen the container after the example's finally, and they drop the aio server before closing the loop, which avoids a __dealloc__ warning at exit.

writing-integrations: the lifecycle bullet now names aiogram (close registered at startup) and Celery (close moved to the end when the worker starts) next to FastStream and taskiq.

just test-docs-integrations passes locally (350 passed, 1 Redis skip, with modern-di-grpc 4.1.0 from PyPI), and so do just test-docs, just lint-ci and just docs-build.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Details
Benchmark suite Current: 4f0fd10 Previous: 473ce2a Ratio
benchmarks/test_guard_by_type.py::test_g16_resolve_by_type 4688002.861562378 iter/sec (stddev: 2.00681760183571e-8) 3306313.5876401127 iter/sec (stddev: 1.363832323993736e-8) 0.71
benchmarks/test_guard_by_type.py::test_g17_resolve_by_type_large_registry 4594797.237573117 iter/sec (stddev: 1.733558287584451e-8) 3290170.5726431306 iter/sec (stddev: 1.245716783206272e-8) 0.72
benchmarks/test_guard_cold.py::test_g8_cold_first_resolve 16277.791242449037 iter/sec (stddev: 0.00004987461108126796) 15965.707850068778 iter/sec (stddev: 0.00005209286000183595) 0.98
benchmarks/test_guard_cold.py::test_g8b_cold_first_resolve_cached 12908.55494586518 iter/sec (stddev: 0.00021562808497603764) 12748.713863393781 iter/sec (stddev: 0.00015782064921049429) 0.99
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[1] 607.7365767094717 iter/sec (stddev: 0.00009976789815936418) 469.2026502820484 iter/sec (stddev: 0.00002904538918022763) 0.77
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[2] 546.2477249153837 iter/sec (stddev: 0.00018321690075261425) 445.95057470512546 iter/sec (stddev: 0.00018510381859139507) 0.82
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[4] 539.6763810499874 iter/sec (stddev: 0.00014796341915545208) 425.09866476193685 iter/sec (stddev: 0.0000922646022815044) 0.79
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[1] 12175.04920498054 iter/sec (stddev: 0.00006009209838562434) 12738.995498481541 iter/sec (stddev: 0.000010788629740426835) 1.05
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[2] 5615.86316612287 iter/sec (stddev: 0.00003196966765197569) 6346.906351224864 iter/sec (stddev: 0.00002396378419399379) 1.13
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[4] 2812.949940135329 iter/sec (stddev: 0.00008171431172071381) 3340.461878976739 iter/sec (stddev: 0.00004049783778627639) 1.19
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[1] 9995.837566682836 iter/sec (stddev: 0.000026333358578859944) 9886.641417264167 iter/sec (stddev: 0.000032336704102086494) 0.99
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[2] 3808.284364086082 iter/sec (stddev: 0.00004551067261946136) 4246.398549760259 iter/sec (stddev: 0.00002173285875373579) 1.12
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[4] 1857.8048837020365 iter/sec (stddev: 0.00007797155933326683) 2040.6772273087477 iter/sec (stddev: 0.00004446136971593872) 1.10
benchmarks/test_guard_concurrency.py::test_g15c_worker_pool_floor_control[1] 27457.610597536703 iter/sec (stddev: 0.000006032958363017834) 39484.022790313305 iter/sec (stddev: 0.000005794165969942003) 1.44
benchmarks/test_guard_concurrency.py::test_g15c_worker_pool_floor_control[2] 11882.072803832885 iter/sec (stddev: 0.000026361005645571007) 13054.300559826146 iter/sec (stddev: 0.00001575653884903998) 1.10
benchmarks/test_guard_concurrency.py::test_g15c_worker_pool_floor_control[4] 4865.4028863717585 iter/sec (stddev: 0.00005149172220170167) 5734.621501364212 iter/sec (stddev: 0.000037174285777289115) 1.18
benchmarks/test_guard_lifecycle.py::test_g6_build_child_container 1819903.6952397937 iter/sec (stddev: 3.3931486629247486e-8) 1556683.537098241 iter/sec (stddev: 3.610577407779314e-8) 0.86
benchmarks/test_guard_lifecycle.py::test_g6b_build_child_container_auto_scope 1973806.1125316918 iter/sec (stddev: 3.284983086180829e-8) 1684453.655038017 iter/sec (stddev: 3.0601432496059574e-8) 0.85
benchmarks/test_guard_lifecycle.py::test_g7_request_lifecycle_batch 3262.588446553242 iter/sec (stddev: 0.000018327081013444514) 3076.7184921090825 iter/sec (stddev: 0.000019264600405964594) 0.94
benchmarks/test_guard_lifecycle.py::test_g7c_event_loop_floor_control 65395.6794987435 iter/sec (stddev: 0.000004674715227973849) 57818.79923978496 iter/sec (stddev: 0.000002003373975733297) 0.88
benchmarks/test_guard_lifecycle.py::test_g7b_request_cycle_sync 441902.36670992547 iter/sec (stddev: 3.3418974040690575e-7) 415907.1854870392 iter/sec (stddev: 9.48408832149831e-8) 0.94
benchmarks/test_guard_lifecycle.py::test_g13_teardown_at_scale 69640.13749788058 iter/sec (stddev: 0.0000029870932309065145) 66163.66159558618 iter/sec (stddev: 0.000001627993476182581) 0.95
benchmarks/test_guard_lifecycle.py::test_g13b_teardown_at_scale_async_no_finalizers 578.9182270882461 iter/sec (stddev: 0.002390619626174563) 578.0378173953227 iter/sec (stddev: 0.0010370644307746168) 1.00
benchmarks/test_guard_resolve.py::test_g1_transient_resolve 2525920.363292689 iter/sec (stddev: 4.874846472991459e-8) 2100357.8274718635 iter/sec (stddev: 3.40696064900045e-8) 0.83
benchmarks/test_guard_resolve.py::test_g2_cached_resolve 4238983.369717536 iter/sec (stddev: 2.2844153810130447e-8) 3628831.7651131107 iter/sec (stddev: 9.800472544776706e-9) 0.86
benchmarks/test_guard_resolve.py::test_g3_deep_chain 938288.682952525 iter/sec (stddev: 9.498432230400872e-8) 787171.6525010447 iter/sec (stddev: 5.6806999235885994e-8) 0.84
benchmarks/test_guard_resolve.py::test_g4_wide_resolve 528229.816311895 iter/sec (stddev: 5.522486470994673e-7) 462301.02708213235 iter/sec (stddev: 4.152095888121524e-7) 0.88
benchmarks/test_guard_resolve.py::test_g5_cross_scope 2317539.5331712617 iter/sec (stddev: 4.284668210744367e-8) 1934146.4710765027 iter/sec (stddev: 7.575212020867067e-8) 0.83
benchmarks/test_guard_resolve.py::test_g9_context_resolve 1592582.0078167387 iter/sec (stddev: 2.1288748673995862e-7) 1403135.685536876 iter/sec (stddev: 1.4498941435338622e-7) 0.88
benchmarks/test_guard_resolve.py::test_g12_override_active_resolve 933064.5174473806 iter/sec (stddev: 7.533707541766586e-8) 803722.8119166028 iter/sec (stddev: 8.047027814524048e-8) 0.86
benchmarks/test_guard_resolve.py::test_g18_alias_hop 4322852.217895701 iter/sec (stddev: 2.5549220068926062e-8) 3607311.009369332 iter/sec (stddev: 1.1417843635988504e-8) 0.83
benchmarks/test_guard_validate.py::test_g10_validate_deep_chain 34344.389811365465 iter/sec (stddev: 0.000021045560063806576) 35368.59475337941 iter/sec (stddev: 0.000018463558597572165) 1.03
benchmarks/test_guard_validate.py::test_g11_validate_wide 21252.262356443855 iter/sec (stddev: 0.000025037331330226064) 19358.528195402458 iter/sec (stddev: 0.00024073783096245922) 0.91

This comment was automatically generated by workflow using github-action-benchmark.

@lesnik512
lesnik512 merged commit bad4b78 into main Oct 17, 2026
12 checks passed
@lesnik512
lesnik512 deleted the docs/shutdown-order-2 branch October 17, 2026 14:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant