Commit 21321e3
fix(upload_file): unstick concurrent uploads stalling at 30s on the server
Customers running many concurrent upload_file calls through a single SDK
instance were hitting 408 "Request timed out waiting for request data"
from mux/Jetty. Triage on 2026-05-14 found the request-body simply wasn't
arriving within Jetty's 30 s data-wait window. Three contributing causes,
all introduced by recent SDK changes:
1. DEFAULT_CONNECTION_LIMITS was lowered from (100, 20) to (20, 10) in
#797. Combined with the new shared process-global pool, parallel
uploads divide bandwidth across far fewer TCP connections than before
and starve each other on multipart bodies. Restore the prior (100, 20).
2. _should_retry blanket-retries 408, including upload_file. Each retry
pushes another large multipart body onto the same exhausted pool and
amplifies the stall instead of recovering from it. Carve out
upload_file 408 — other endpoints still retry 408 as before.
3. _files.py read the entire PathLike into memory via read_bytes() before
the request was built, contradicting the docstring claim of streaming.
Hand httpx an open file handle so the multipart encoder reads lazily
and the pool slot isn't held during disk I/O. Tests updated to assert
IsInstance(io.IOBase) instead of IsBytes() and to close handles.
Also exposes a public connection_limits knob on Runloop / AsyncRunloop
(and copy()) so customers can raise the cap above 100 for upload-heavy
workloads without needing a custom httpx client. Passing
connection_limits implicitly opts out of the shared pool, since the
shared pool is process-global and can't honor per-client limits.
Includes examples/stress_upload_file.py — a standalone repro that fires
N concurrent upload_file calls and reports status-code distribution and
latency percentiles, so the before/after delta is one command away.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>1 parent d5303c2 commit 21321e3
8 files changed
Lines changed: 468 additions & 15 deletions
File tree
- examples
- src/runloop_api_client
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
870 | 870 | | |
871 | 871 | | |
872 | 872 | | |
| 873 | + | |
| 874 | + | |
| 875 | + | |
| 876 | + | |
| 877 | + | |
| 878 | + | |
873 | 879 | | |
874 | 880 | | |
875 | 881 | | |
| |||
931 | 937 | | |
932 | 938 | | |
933 | 939 | | |
| 940 | + | |
934 | 941 | | |
935 | 942 | | |
936 | 943 | | |
| |||
945 | 952 | | |
946 | 953 | | |
947 | 954 | | |
| 955 | + | |
948 | 956 | | |
949 | 957 | | |
950 | 958 | | |
| |||
976 | 984 | | |
977 | 985 | | |
978 | 986 | | |
| 987 | + | |
979 | 988 | | |
980 | 989 | | |
981 | 990 | | |
982 | 991 | | |
| 992 | + | |
| 993 | + | |
| 994 | + | |
| 995 | + | |
| 996 | + | |
| 997 | + | |
| 998 | + | |
| 999 | + | |
| 1000 | + | |
983 | 1001 | | |
984 | 1002 | | |
985 | 1003 | | |
| |||
1563 | 1581 | | |
1564 | 1582 | | |
1565 | 1583 | | |
| 1584 | + | |
1566 | 1585 | | |
1567 | 1586 | | |
1568 | 1587 | | |
| |||
1577 | 1596 | | |
1578 | 1597 | | |
1579 | 1598 | | |
| 1599 | + | |
1580 | 1600 | | |
1581 | 1601 | | |
1582 | 1602 | | |
| |||
1608 | 1628 | | |
1609 | 1629 | | |
1610 | 1630 | | |
| 1631 | + | |
1611 | 1632 | | |
1612 | 1633 | | |
1613 | 1634 | | |
1614 | 1635 | | |
| 1636 | + | |
| 1637 | + | |
| 1638 | + | |
| 1639 | + | |
| 1640 | + | |
| 1641 | + | |
| 1642 | + | |
| 1643 | + | |
| 1644 | + | |
1615 | 1645 | | |
1616 | 1646 | | |
1617 | 1647 | | |
| |||
0 commit comments