Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

*ttl drivers: TTL branch dereferences delete() result without a nil check, killing the fiber

Aperta
#264 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
76/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
lua
Ambito
backend

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() and get(); I could not reproduce it there.
  • vinyl (fifottl supports engine = 'vinyl'): reads may yield on disk I/O, so a concurrent ack()/delete() of the same expired task between min() and delete() hits it.
  • memtx with MVCC: delete() may also raise Transaction has been aborted by conflict with 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

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di tarantool/queue

Tutte le issue di tarantool/queue

Issue simili

Altre issue su Lua

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.