Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

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

Abierto
#264 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
3/5
Tiempo estimado
1-2 días
Aptitud para principiantes
76/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
lua
Área
backend

Línea de trabajo

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.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

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.

Lenguaje dominante
Lua
Estrellas
244
Forks
56
Merge medio
6 d 8 h
PR fusionados (30 d)
1

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de tarantool/queue

Todos los issues de tarantool/queue

Issues similares

Más issues de Lua

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.