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

*ttl drivers: a dead TTL fiber cannot be restarted and wedges the queue in ENDING on the next RO switch

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

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
48/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
lua
Ambito
backend

Direzione di ricerca

Start with queue/abstract/driver/fifottl.lua lines 164-167 and 415-427, then compare the buffered-channel behavior in utubettl. Run the reproduction in the issue and inspect queue_state handling during RO/RW switches. Done means a failed TTL iteration does not permanently disable processing or leave the queue stuck in ENDING, and start/stop remain safe.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Environment: queue master (07fd732), Tarantool 3.8.0 (also the same code in 1.5.0). memtx.

Related: #238 asks for an API to restart the TTL fiber. This issue is about what happens today when the fiber dies: it cannot be restarted, and for fifottl/limfifottl the queue state machine gets stuck in ENDING on the next RO switch, so the queue never comes back without an instance restart.

Summary

Any error inside a TTL iteration (a user on_task_change callback raising, an MVCC conflict, a vinyl read error, the nil dereference from the TTL branch, ...) makes the fiber return 1 (fifottl.lua#L164-L167) while self.fiber keeps pointing at the dead fiber. Consequences:

  1. method.start() is a no-op because self.fiber is not nil (fifottl.lua#L415-L420). TTL/TTR/delay processing for the tube is dead.
  2. On the next RO switch the state machine calls stop(), which does self.sync_chan:put(true) (fifottl.lua#L427). The channel is unbuffered and the only reader is dead (same root cause as #262), so the queue_state fiber blocks forever. The queue stays in ENDING, and put/take keep failing with queue is in ENDING state even after the instance is RW again.

For utubettl (buffered fiber.channel(1)) point 2 does not hang, but point 1 still holds until an RO->RW cycle.

Repro

local fiber = require('fiber')
box.cfg{}
local queue = require('queue')

local fired = false
local tube = queue.create_tube('t', 'fifottl', {
    on_task_change = function(task, stat)
        if stat == 'ttl' and not fired then
            fired = true
            error('user callback failed once')
        end
    end,
})

tube:put('a', {ttl = 0.1})
fiber.sleep(0.3)
print('1. fiber after one callback error:', tube.raw.fiber:status())

local b = tube:put('b', {ttl = 0.1})
fiber.sleep(0.3)
print('2. expired task still in space:', tube.raw.space:get(b[1]) ~= nil)

tube.raw:start()
print('3. fiber after start():', tube.raw.fiber:status())

box.cfg{read_only = true}
fiber.sleep(1)
print('4. queue.state() after RO switch:', queue.state())
box.cfg{read_only = false}
fiber.sleep(1)
print('5. queue.state() after RW switch:', queue.state())
print('6. put() after RW switch:', pcall(tube.put, tube, 'c', {ttl = 0.1}))

Output on master:

1. fiber after one callback error:  dead
2. expired task still in space:     true
3. fiber after start():             dead
4. queue.state() after RO switch:   ENDING
5. queue.state() after RW switch:   ENDING
6. put() after RW switch:           true  nil      -- put() returns nil, log: "put: queue is in ENDING state"

Expected

A failed iteration should not permanently kill TTL processing: either the fiber survives the error (log it and continue / restart with backoff), or at least self.fiber is cleared on exit so start() can create a new one, and stop() must never block on a channel nobody reads.

Suggested fix

  • Clear self.fiber in a guaranteed cleanup path when the fiber exits (checking it still points to the current fiber).
  • Make stop() tolerant of a dead fiber (check self.fiber:status() or use a buffered channel / fiber:cancel()).
  • Optionally restart the fiber after an error with a backoff instead of return 1; user callback errors could be pcall-ed in abstract.lua so a user bug cannot take the driver down.
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.