Commit 22fb248
committed
Drop abandoned requests when draining the ZeroMQ send queue
`AsyncReqMessageClient.send()` enqueues `(future, message)` on `self._queue`
and arms `_timeout_message()` to complete the future when the caller's timeout
expires. When that fires the caller is released, but the queue entry is not
removed -- it keeps pinning its serialized payload until the drain loop
happens to reach it.
Before 145a06e in-flight requests were tracked in `self._send_future_map`, a
dict, so a timed-out entry could be removed by key. `Queue` has no
removal-from-middle and `self._queue` has no maxsize, so an abandoned entry
becomes unreachable garbage that still occupies the queue.
A REQ socket permits one request/reply in flight, each drain iteration polls
for up to 300ms, and `_send_recv()` restarts from scratch on every reconnect.
Under sustained load the enqueue rate outruns the drain rate and the queue
grows without bound. Observed on a 120-minion master: one process at ~53 GiB,
OOM-killed roughly fortnightly.
Skip requests whose future is already done: the reply can no longer be
delivered to anyone, so there is no reason to spend a round trip on it.
Two existing tests queued a single already-done future and relied on it
reaching the send path to terminate the loop. With the entry now dropped they
fall through to the idle poll branch, which calls `.result()` on the
AsyncMock's coroutine. Both now queue a shutdown sentinel so the loop exits.
Note this makes the #68506 repro structurally unreachable on this path -- a
timed-out future never reaches `socket.send` -- so that test now asserts only
its invariant, that the original timeout exception survives untouched.
Fixes #686601 parent 123f679 commit 22fb248
3 files changed
Lines changed: 92 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1001 | 1001 | | |
1002 | 1002 | | |
1003 | 1003 | | |
| 1004 | + | |
| 1005 | + | |
| 1006 | + | |
| 1007 | + | |
| 1008 | + | |
| 1009 | + | |
| 1010 | + | |
| 1011 | + | |
| 1012 | + | |
| 1013 | + | |
| 1014 | + | |
| 1015 | + | |
| 1016 | + | |
| 1017 | + | |
| 1018 | + | |
| 1019 | + | |
| 1020 | + | |
| 1021 | + | |
| 1022 | + | |
| 1023 | + | |
1004 | 1024 | | |
1005 | 1025 | | |
1006 | 1026 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1825 | 1825 | | |
1826 | 1826 | | |
1827 | 1827 | | |
| 1828 | + | |
| 1829 | + | |
| 1830 | + | |
| 1831 | + | |
| 1832 | + | |
| 1833 | + | |
| 1834 | + | |
| 1835 | + | |
| 1836 | + | |
| 1837 | + | |
1828 | 1838 | | |
1829 | 1839 | | |
1830 | 1840 | | |
| |||
1856 | 1866 | | |
1857 | 1867 | | |
1858 | 1868 | | |
| 1869 | + | |
| 1870 | + | |
| 1871 | + | |
| 1872 | + | |
| 1873 | + | |
| 1874 | + | |
| 1875 | + | |
| 1876 | + | |
| 1877 | + | |
| 1878 | + | |
| 1879 | + | |
1859 | 1880 | | |
1860 | 1881 | | |
1861 | 1882 | | |
| |||
1864 | 1885 | | |
1865 | 1886 | | |
1866 | 1887 | | |
| 1888 | + | |
| 1889 | + | |
| 1890 | + | |
| 1891 | + | |
| 1892 | + | |
| 1893 | + | |
| 1894 | + | |
| 1895 | + | |
| 1896 | + | |
| 1897 | + | |
| 1898 | + | |
| 1899 | + | |
| 1900 | + | |
| 1901 | + | |
| 1902 | + | |
| 1903 | + | |
| 1904 | + | |
| 1905 | + | |
| 1906 | + | |
| 1907 | + | |
| 1908 | + | |
| 1909 | + | |
| 1910 | + | |
| 1911 | + | |
| 1912 | + | |
| 1913 | + | |
| 1914 | + | |
| 1915 | + | |
| 1916 | + | |
| 1917 | + | |
| 1918 | + | |
| 1919 | + | |
| 1920 | + | |
| 1921 | + | |
| 1922 | + | |
| 1923 | + | |
| 1924 | + | |
| 1925 | + | |
| 1926 | + | |
| 1927 | + | |
| 1928 | + | |
| 1929 | + | |
| 1930 | + | |
| 1931 | + | |
| 1932 | + | |
| 1933 | + | |
| 1934 | + | |
1867 | 1935 | | |
1868 | 1936 | | |
1869 | 1937 | | |
| |||
0 commit comments