Skip to content

drivers: tolerate a concurrently deleted task on ttl - #267

Open
maksimuimin wants to merge 1 commit into
tarantool:masterfrom
maksimuimin:fix-ttl-delete-nil
Open

maksimuimin wants to merge 1 commit into
tarantool:masterfrom
maksimuimin:fix-ttl-delete-nil

Conversation

@maksimuimin

Copy link
Copy Markdown

Closes #264

Independent of #265 and #266 (based on master).

Problem

The ttl branch of the fiber iteration in fifottl and utubettl, and the expired-task path of utubettl take() in the ready buffer mode, did

task = self:delete(task[i_id]):transform(2, 1, state.DONE)

delete() returns nil when the task is already gone, so a task deleted concurrently between min() and delete() raised attempt to index a nil value and killed the ttl fiber. Reachable with vinyl (yielding reads) or MVCC; the delayed and ttr branches already tolerate a nil from update().

Fix

Check the result of delete() before reporting the ttl event. delete() already returns the task with the DONE status, so the extra transform() is dropped.

New test t/280-ttl-delete-nil.t emulates the concurrent delete through the driver's delete() and checks that the fiber survives and keeps processing. The test fails on master. Full suite passes locally (Tarantool 3.8, memtx and vinyl).

The ttl branch of the fiber iteration in fifottl and utubettl (and the
expired-task path of utubettl take() in the ready buffer mode) called
:transform() on the result of delete(), which is nil when the task has
been deleted concurrently between min() and delete(). With vinyl
(yielding reads) or MVCC this killed the ttl fiber. The delayed and
ttr branches already tolerate a nil from update().

delete() already returns the task with the DONE status, so the extra
transform is dropped as well.

Closes tarantool#264

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

1 participant