*ttl drivers: TTL branch dereferences delete() result without a nil check, killing the fiber
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 76/100
Hướng nghiên cứu
Start with the TTL branches in queue/abstract/driver/fifottl.lua and utubettl.lua at the referenced lines, then read the delete implementation around fifottl.lua#L334-L342 and compare the handling in subqueuettl from #259. Verify the chosen fix for a task deleted between selection and deletion, including vinyl and MVCC cases, and ensure TTL processing continues instead of the fiber dying.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Environment: queue master (07fd732), also 1.5.0. Found by code review while porting the subqueuettl driver (#259), which copies the same loop.
Summary
In the TTL branch of the fiber iteration the result of delete() is dereferenced unconditionally:
-- fifottl.lua#L113-L117, same in utubettl.lua#L243 and #L521
task = self.space.index.watch:min{ task_state }
if task ~= nil and task[i_status] == task_state then
if now >= task[i_next_event] then
task = self:delete(task[i_id]):transform(2, 1, state.DONE)
self:on_task_change(task, 'ttl')
but method.delete() returns nil when the task is already gone (fifottl.lua#L334-L342), so a task that disappears between min() and delete() produces attempt to index a nil value, the fiber dies, and TTL processing stops for good (see #263). The delayed and TTR branches tolerate a nil from update() because abstract.lua ignores on_task_change(nil, ...); only the TTL branch does not.
When it is reachable
- memtx without MVCC: not reachable, there is no yield between
min()andget(); I could not reproduce it there. - vinyl (
fifottlsupportsengine = 'vinyl'): reads may yield on disk I/O, so a concurrentack()/delete()of the same expired task betweenmin()anddelete()hits it. - memtx with MVCC:
delete()may also raiseTransaction has been aborted by conflictwith a concurrent write on the same task, which kills the fiber the same way.
Suggested fix
Either guard the result:
task = self:delete(task[i_id])
if task ~= nil then
self:on_task_change(task, 'ttl')
end
or do min() + delete() inside one box.atomic() so the selection and the delete see the same state. The subqueuettl driver in #259 does the former for the fork we run.
- Ngôn ngữ chính
- Lua
- Star
- 244
- Fork
- 56
- Merge trung bình
- 6 ngày 8 giờ
- Pull request đã merge (30 ngày)
- 1
Hướng dẫn đóng góp
Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này
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.
Issue khác của tarantool/queue
-
tube:grant() is not documented Đang mởdocumentation good first issue
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 85/100
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 48/100
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 55/100
-
1sp bug teamE
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 25/100
-
bug
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 35/100
Tất cả issue của tarantool/queue
Issue tương tự
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
LandSandBoat/server#11579 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
ArchiveTeam/sinavideo-grab#7 · 3 reaction ·
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
mailcow/mailcow-dockerized#7480 ·
-
Mapper: a failed area image export crashes Mudlet if the profile closed while it was running Đang mởmapper bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100