Commit e02c9e7
committed
End a listen stream's keepalive thread when its slot is freed
## Motivation and Context
Each `subscriptions/listen` stream has a keepalive thread that sleeps for the configured interval
and then writes a comment frame, so a silently dropped peer is noticed and its slot freed.
The thread checked for its entry only between sleeps, so when another path removed the entry,
a failed notification write or the transport closing, the thread slept out the rest of its interval,
up to 15 seconds by default, before it noticed and exited.
How many such threads existed therefore depended on how quickly clients opened and dropped listen streams,
not on `max_listen_subscriptions`, which bounds only the entries. The TypeScript SDK stops its keepalive timer
the moment it tears a stream down.
The wait between pings is now a condition variable wait under the registry lock, and whatever removes
an entry signals it under the same lock. The presence check and the wait cannot be separated by a removal,
so a thread waiting out its interval wakes and exits as soon as its entry goes, whichever path removed it;
one already past the wait, in a ping, finishes that write first. Pings still happen outside the lock,
and a dropped peer is still detected by the ping's write failure as before.
The ping itself is now written under the stream's write mutex, as notification delivery and the closing result are,
and skipped once the transport has marked the entry closed. It used to be written outside that mutex,
so a comment frame could follow the closing result, or land between the bytes of a notification on a stream
that does not serialize its writes itself.
## How Has This Been Tested?
New tests in `test/mcp/server/transports/streamable_http_transport_test.rb` open listen streams with a 30 second interval,
free their slots through a failed delivery write and through `close`, and check that every keepalive thread ends within
a bound far below that interval. Against the previous library the threads are still alive at that bound.
Two more tests hold a stream's write mutex and check that the ping waits for it, and mark an entry closed
and check that the ping writes nothing.
## Breaking Changes
None.1 parent 6da3009 commit e02c9e7
2 files changed
Lines changed: 159 additions & 20 deletions
File tree
- lib/mcp/server/transports
- test/mcp/server/transports
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
171 | 171 | | |
172 | 172 | | |
173 | 173 | | |
174 | | - | |
175 | | - | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
176 | 178 | | |
177 | 179 | | |
178 | 180 | | |
| |||
944 | 946 | | |
945 | 947 | | |
946 | 948 | | |
947 | | - | |
| 949 | + | |
948 | 950 | | |
949 | 951 | | |
950 | 952 | | |
| |||
986 | 988 | | |
987 | 989 | | |
988 | 990 | | |
| 991 | + | |
| 992 | + | |
| 993 | + | |
| 994 | + | |
| 995 | + | |
| 996 | + | |
989 | 997 | | |
990 | 998 | | |
991 | 999 | | |
992 | 1000 | | |
993 | | - | |
994 | | - | |
| 1001 | + | |
| 1002 | + | |
| 1003 | + | |
| 1004 | + | |
| 1005 | + | |
| 1006 | + | |
| 1007 | + | |
| 1008 | + | |
| 1009 | + | |
| 1010 | + | |
| 1011 | + | |
995 | 1012 | | |
996 | 1013 | | |
997 | 1014 | | |
| |||
1010 | 1027 | | |
1011 | 1028 | | |
1012 | 1029 | | |
1013 | | - | |
1014 | | - | |
1015 | | - | |
1016 | | - | |
1017 | | - | |
1018 | | - | |
| 1030 | + | |
| 1031 | + | |
| 1032 | + | |
| 1033 | + | |
| 1034 | + | |
1019 | 1035 | | |
1020 | | - | |
1021 | | - | |
1022 | | - | |
1023 | | - | |
1024 | | - | |
| 1036 | + | |
| 1037 | + | |
1025 | 1038 | | |
1026 | | - | |
| 1039 | + | |
| 1040 | + | |
| 1041 | + | |
| 1042 | + | |
| 1043 | + | |
1027 | 1044 | | |
1028 | 1045 | | |
1029 | 1046 | | |
| |||
1108 | 1125 | | |
1109 | 1126 | | |
1110 | 1127 | | |
1111 | | - | |
| 1128 | + | |
| 1129 | + | |
| 1130 | + | |
| 1131 | + | |
| 1132 | + | |
| 1133 | + | |
1112 | 1134 | | |
1113 | 1135 | | |
1114 | 1136 | | |
| |||
1117 | 1139 | | |
1118 | 1140 | | |
1119 | 1141 | | |
| 1142 | + | |
| 1143 | + | |
| 1144 | + | |
| 1145 | + | |
| 1146 | + | |
1120 | 1147 | | |
1121 | 1148 | | |
1122 | 1149 | | |
| |||
Lines changed: 114 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6113 | 6113 | | |
6114 | 6114 | | |
6115 | 6115 | | |
6116 | | - | |
| 6116 | + | |
| 6117 | + | |
| 6118 | + | |
| 6119 | + | |
| 6120 | + | |
| 6121 | + | |
6117 | 6122 | | |
6118 | 6123 | | |
6119 | 6124 | | |
| |||
6321 | 6326 | | |
6322 | 6327 | | |
6323 | 6328 | | |
6324 | | - | |
| 6329 | + | |
6325 | 6330 | | |
6326 | 6331 | | |
6327 | 6332 | | |
| |||
6347 | 6352 | | |
6348 | 6353 | | |
6349 | 6354 | | |
| 6355 | + | |
| 6356 | + | |
| 6357 | + | |
| 6358 | + | |
| 6359 | + | |
| 6360 | + | |
| 6361 | + | |
| 6362 | + | |
| 6363 | + | |
| 6364 | + | |
| 6365 | + | |
| 6366 | + | |
| 6367 | + | |
| 6368 | + | |
| 6369 | + | |
| 6370 | + | |
| 6371 | + | |
| 6372 | + | |
| 6373 | + | |
| 6374 | + | |
| 6375 | + | |
| 6376 | + | |
| 6377 | + | |
| 6378 | + | |
| 6379 | + | |
| 6380 | + | |
| 6381 | + | |
| 6382 | + | |
| 6383 | + | |
| 6384 | + | |
| 6385 | + | |
| 6386 | + | |
| 6387 | + | |
| 6388 | + | |
| 6389 | + | |
| 6390 | + | |
| 6391 | + | |
| 6392 | + | |
| 6393 | + | |
| 6394 | + | |
| 6395 | + | |
| 6396 | + | |
| 6397 | + | |
| 6398 | + | |
| 6399 | + | |
| 6400 | + | |
| 6401 | + | |
| 6402 | + | |
| 6403 | + | |
| 6404 | + | |
| 6405 | + | |
| 6406 | + | |
| 6407 | + | |
| 6408 | + | |
| 6409 | + | |
| 6410 | + | |
| 6411 | + | |
| 6412 | + | |
| 6413 | + | |
| 6414 | + | |
| 6415 | + | |
| 6416 | + | |
| 6417 | + | |
| 6418 | + | |
| 6419 | + | |
| 6420 | + | |
| 6421 | + | |
| 6422 | + | |
| 6423 | + | |
| 6424 | + | |
| 6425 | + | |
| 6426 | + | |
| 6427 | + | |
| 6428 | + | |
| 6429 | + | |
| 6430 | + | |
| 6431 | + | |
| 6432 | + | |
| 6433 | + | |
| 6434 | + | |
| 6435 | + | |
| 6436 | + | |
| 6437 | + | |
| 6438 | + | |
| 6439 | + | |
| 6440 | + | |
| 6441 | + | |
| 6442 | + | |
| 6443 | + | |
| 6444 | + | |
| 6445 | + | |
| 6446 | + | |
| 6447 | + | |
| 6448 | + | |
| 6449 | + | |
| 6450 | + | |
| 6451 | + | |
| 6452 | + | |
| 6453 | + | |
| 6454 | + | |
| 6455 | + | |
| 6456 | + | |
| 6457 | + | |
| 6458 | + | |
| 6459 | + | |
| 6460 | + | |
| 6461 | + | |
6350 | 6462 | | |
6351 | 6463 | | |
6352 | 6464 | | |
| |||
0 commit comments