Skip to content

docs: say a cancelled sync stream on the grpc aio server is never closed - #715

Merged
lesnik512 merged 1 commit into
mainfrom
docs/grpc-sync-stream-cancel
Oct 17, 2026
Merged

lesnik512 merged 1 commit into
mainfrom
docs/grpc-sync-stream-cancel

Conversation

@lesnik512

Copy link
Copy Markdown
Member

The gRPC page says a streaming RPC's child container closes "including on the error and client-cancellation paths". That isn't true for a sync server-streaming method on the aio server. When the client cancels, gRPC never closes the method's generator, so the child stays open and its REQUEST finalizers don't run.

I reproduced this with grpcio 1.83.1: an aio server with migration_thread_pool, a sync generator method, and a client that cancels after 50 messages. Nothing closed the generator, not even after gc.collect() and server.stop(None). The same server without DIAioInterceptor also never closes the generator, so this is gRPC's behavior and the integration can't fix it.

The page now notes the exception under "Sync methods on the aio server", points to it from the Scopes paragraph, and recommends async generators for server-streaming methods on the aio server.

@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: edf0c28 Previous: 8d65b82 Ratio
benchmarks/test_guard_by_type.py::test_g16_resolve_by_type 3347660.7634594277 iter/sec (stddev: 1.267466071305793e-8) 5207624.879395973 iter/sec (stddev: 4.422159057643991e-9) 1.56
benchmarks/test_guard_by_type.py::test_g17_resolve_by_type_large_registry 3279433.5473860865 iter/sec (stddev: 1.222020236711822e-8) 5168088.726594587 iter/sec (stddev: 4.781647299895506e-9) 1.58
benchmarks/test_guard_cold.py::test_g8_cold_first_resolve 15863.951918054503 iter/sec (stddev: 0.00005380475463946579) 23628.19070196022 iter/sec (stddev: 0.00004039376643586871) 1.49
benchmarks/test_guard_cold.py::test_g8b_cold_first_resolve_cached 12511.943035151822 iter/sec (stddev: 0.00014398463253914988) 19134.80119638614 iter/sec (stddev: 0.0001193993124271674) 1.53
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[1] 475.49200262367845 iter/sec (stddev: 0.000051545078856669474) 666.2592676599052 iter/sec (stddev: 0.000012924342633707238) 1.40
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[2] 466.4051942166521 iter/sec (stddev: 0.00004849646959937377) 655.7194903760679 iter/sec (stddev: 0.000018904224087385384) 1.41
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[4] 436.9047615625634 iter/sec (stddev: 0.00010817470248097882) 609.7487859412679 iter/sec (stddev: 0.000038548176323114195) 1.40
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[1] 13784.30684238778 iter/sec (stddev: 0.000008700149210177655) 20193.415903129564 iter/sec (stddev: 0.0000069170550806580505) 1.46
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[2] 6498.936692719779 iter/sec (stddev: 0.00003188496853681227) 10036.22491746852 iter/sec (stddev: 0.000014422367684005223) 1.54
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[4] 3360.699227077766 iter/sec (stddev: 0.00005693475599659083) 5082.107588967101 iter/sec (stddev: 0.000023913387650034583) 1.51
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[1] 10019.820875670273 iter/sec (stddev: 0.000011898010069579172) 14948.582481949954 iter/sec (stddev: 0.000008128327180134387) 1.49
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[2] 4293.903372861109 iter/sec (stddev: 0.000024003048958773806) 6694.738075363169 iter/sec (stddev: 0.000031449092563561894) 1.56
benchmarks/test_guard_concurrency.py::test_g15b_concurrent_first_resolve_sibling_children[4] 1994.271753528122 iter/sec (stddev: 0.00005722418660360306) 2998.3652163220872 iter/sec (stddev: 0.00006602595010218243) 1.50
benchmarks/test_guard_concurrency.py::test_g15c_worker_pool_floor_control[1] 41219.80391636404 iter/sec (stddev: 0.000004703908958923942) 53679.722618307234 iter/sec (stddev: 0.000002382081574854876) 1.30
benchmarks/test_guard_concurrency.py::test_g15c_worker_pool_floor_control[2] 14729.122236511766 iter/sec (stddev: 0.00001335879548321561) 22144.401055924835 iter/sec (stddev: 0.000012264206910576056) 1.50
benchmarks/test_guard_concurrency.py::test_g15c_worker_pool_floor_control[4] 5724.512965592087 iter/sec (stddev: 0.00003166703073701503) 8466.8669974301 iter/sec (stddev: 0.00002283730672218584) 1.48
benchmarks/test_guard_lifecycle.py::test_g6_build_child_container 1555605.7497652718 iter/sec (stddev: 3.657003731634727e-8) 2182285.905204642 iter/sec (stddev: 1.6447288664983594e-8) 1.40
benchmarks/test_guard_lifecycle.py::test_g6b_build_child_container_auto_scope 1629538.1823610573 iter/sec (stddev: 3.5562318651335884e-8) 2349469.627803676 iter/sec (stddev: 1.2193021062756913e-8) 1.44
benchmarks/test_guard_lifecycle.py::test_g7_request_lifecycle_batch 2767.029256659732 iter/sec (stddev: 0.00006149248624417038) 4467.393473049489 iter/sec (stddev: 0.00000578247716313059) 1.61
benchmarks/test_guard_lifecycle.py::test_g7c_event_loop_floor_control 53640.236435547966 iter/sec (stddev: 0.000004558986493727937) 75319.26558529767 iter/sec (stddev: 0.0000011074264186992304) 1.40
benchmarks/test_guard_lifecycle.py::test_g7b_request_cycle_sync 326654.4956290002 iter/sec (stddev: 0.0000012146405262629968) 558692.7862637975 iter/sec (stddev: 7.87233976051635e-8) 1.71
benchmarks/test_guard_lifecycle.py::test_g13_teardown_at_scale 63230.77936532353 iter/sec (stddev: 0.0000035847045686135693) 94135.55361841661 iter/sec (stddev: 8.82100415283153e-7) 1.49
benchmarks/test_guard_lifecycle.py::test_g13b_teardown_at_scale_async_no_finalizers 565.8268730134523 iter/sec (stddev: 0.0013354036700138994) 845.8107276334767 iter/sec (stddev: 0.0011624587860086162) 1.49
benchmarks/test_guard_resolve.py::test_g1_transient_resolve 2108110.3273235573 iter/sec (stddev: 3.754778957399345e-8) 2992119.5052336133 iter/sec (stddev: 2.5957980314098157e-8) 1.42
benchmarks/test_guard_resolve.py::test_g2_cached_resolve 3558909.2185266516 iter/sec (stddev: 1.8590518201050585e-8) 5017892.046789965 iter/sec (stddev: 9.942813016470202e-9) 1.41
benchmarks/test_guard_resolve.py::test_g3_deep_chain 801744.8854982682 iter/sec (stddev: 5.8019350885589044e-8) 1129944.5242452216 iter/sec (stddev: 3.456660694189994e-8) 1.41
benchmarks/test_guard_resolve.py::test_g4_wide_resolve 475538.28675197443 iter/sec (stddev: 4.3349110906165055e-7) 626963.2963774503 iter/sec (stddev: 3.4622589683535066e-7) 1.32
benchmarks/test_guard_resolve.py::test_g5_cross_scope 2000948.4495565246 iter/sec (stddev: 2.5727179188869498e-8) 2738637.137789074 iter/sec (stddev: 2.1131133306282963e-8) 1.37
benchmarks/test_guard_resolve.py::test_g9_context_resolve 1434862.3776874093 iter/sec (stddev: 1.6380087742871482e-7) 2094789.4312317702 iter/sec (stddev: 1.3719602822209977e-7) 1.46
benchmarks/test_guard_resolve.py::test_g12_override_active_resolve 844303.6164806461 iter/sec (stddev: 4.487553442441456e-8) 1190303.9506583095 iter/sec (stddev: 3.036097176209324e-8) 1.41
benchmarks/test_guard_resolve.py::test_g18_alias_hop 3654537.7188981534 iter/sec (stddev: 8.948342081413205e-9) 5024835.500716828 iter/sec (stddev: 6.256074503338818e-9) 1.37
benchmarks/test_guard_validate.py::test_g10_validate_deep_chain 35219.42181118025 iter/sec (stddev: 0.000019286908350246628) 44164.270889953026 iter/sec (stddev: 0.00023983450027027081) 1.25
benchmarks/test_guard_validate.py::test_g11_validate_wide 20574.82254714512 iter/sec (stddev: 0.000025407238617823057) 31861.053859160158 iter/sec (stddev: 0.00001882407319522186) 1.55

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

@lesnik512
lesnik512 merged commit 54ed599 into main Oct 17, 2026
12 checks passed
@lesnik512
lesnik512 deleted the docs/grpc-sync-stream-cancel branch October 17, 2026 19:17
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