*ttl drivers: TTL branch dereferences delete() result without a nil check, killing the fiber
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 76/100
Direzione di ricerca
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.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
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.
- Lingua principale
- Lua
- Stelle
- 244
- Fork
- 56
- Merge medio
- 6g 8h
- PR unite (30g)
- 1
Guida per i contributori
Nessuna guida per i contributori indicizzata per questo repository
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di tarantool/queue
-
documentation good first issue
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 85/100
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 55/100
-
1sp bug teamE
Difficoltà 4/5 3-5 giorni Idoneità per principianti 25/100
-
bug
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
Tutte le issue di tarantool/queue
Issue simili
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
LandSandBoat/server#11579 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
ArchiveTeam/sinavideo-grab#7 · 3 reazioni ·
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
mailcow/mailcow-dockerized#7480 ·
-
mapper bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100