concurrent.interpreters.Queue.get()/put() mishandle the timeout argument
Chưa có ai nhận issue này.
- Ngôn ngữ chính
- Python
- Star
- 77.2k
- Fork
- 35.9k
- Chỉ số merge pull request
- Chỉ số pull request đang chờ
Mô tả
concurrent.interpreters.Queue.get() and Queue.put() mishandle their
timeout argument in three related ways.
-
The value is converted with
int(timeout), which truncates a floating-point
timeout to whole seconds. A timeout in the interval[0, 1)becomes a
non-blocking call, and e.g.timeout=1.9waits for only about one second.
queue.Queue, which this queue is meant to be compatible with, accepts a
floating-point number of seconds. -
Because of the same
int()conversion, a small negative float such as
timeout=-0.5is truncated to0and passes thetimeout < 0check
instead of raisingValueError. -
The deadline is computed with
time.time()(the wall clock), while
queue.Queueusestime.monotonic(). The timeout can therefore over- or
under-wait if the system clock is adjusted (NTP step, manual change) during
the call.
Reproducer (3.14.5)
import time
from concurrent.interpreters import create_queue
q = create_queue(maxsize=1)
q.put(b"x") # fill it
start = time.perf_counter()
try:
q.put(b"y", timeout=0.5) # expected: block ~0.5s, then QueueFull
except Exception as exc:
print(type(exc).__name__, f"{(time.perf_counter() - start) * 1000:.1f} ms")
# -> QueueFull 0.0 ms (expected ~500 ms)
q2 = create_queue()
start = time.perf_counter()
try:
q2.get(timeout=0.9) # expected: block ~0.9s, then QueueEmpty
except Exception as exc:
print(type(exc).__name__, f"{(time.perf_counter() - start) * 1000:.1f} ms")
# -> QueueEmpty 0.0 ms (expected ~900 ms)
For comparison, queue.Queue().get(timeout=0.5) blocks for about 500 ms.
The fix is to use the timeout value as given, reject a negative or NaN timeout
with ValueError, and base the deadline on time.monotonic().
Linked PRs
- gh-153006
- gh-154156
- gh-155967
- gh-156018
- gh-156019
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Hướng nghiên cứu
Bắt đầu với concurrent.interpreters.Queue.get() và Queue.put(), sau đó so sánh cách xử lý timeout của chúng với queue.Queue như được mô tả trong issue. Xác nhận hành vi đối với các timeout dạng phân số, âm và NaN, cũng như đối với việc điều chỉnh đồng hồ; hoàn tất nghĩa là vẫn giữ nguyên thời gian chờ dạng phân số, phát sinh ValueError ở nơi được chỉ định và sử dụng deadline đơn điệu. Kiểm tra các PR được liên kết trước khi bắt đầu vì công việc đã được tiến hành.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- python
- Lĩnh vực
- backend
- Loại issue
- Lỗi
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức độ hoạt động
- Đình trệ
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức phù hợp với người mới
- 25/100