Skip to content

drivers: fix utube kick in the ready buffer mode - #258

Open
bigbes wants to merge 1 commit into
masterfrom
bigbes/gh-256-utube-kick-ready-buffer
Open

drivers: fix utube kick in the ready buffer mode#258
bigbes wants to merge 1 commit into
masterfrom
bigbes/gh-256-utube-kick-ready-buffer

Conversation

@bigbes

@bigbes bigbes commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Two defects in method.kick() of the utube driver, both in the 'ready_buffer' storage mode. utubettl does the same thing correctly via update_ready().

  1. When the utube had no entry in the ready buffer, kick() called put_ready(self, task[3]) while the helper is put_ready(self, id, utube). The utube name was passed as the task id and the utube became nil, so the insert failed on the space format and the error was swallowed by the pcall inside put_ready(). The kicked task stayed READY but was never returned by take(), because take_ready() only looks at the ready buffer.

  2. When the utube already had a younger task in the buffer, kick() replaced it with insert({task[1], task[2]}), that is {id, status} instead of {id, utube}. The status string landed in the utube field, so the buffer no longer had an entry under the real utube name and a later put() added a second one. With two entries for one utube the driver could take two tasks of the same utube at once, which breaks the main utube guarantee, and take_ready() could spin forever on an entry whose utube already had a TAKEN task.

Introduce update_ready() mirroring the utubettl helper and use it in kick().

Also commit the transaction before the early returns of kick(): with no buried tasks kick() returned while the transaction opened by begin_if_not_in_txn() was still running, and it leaked into whatever the caller fiber did next. This part is within the scope of #231.

Closes #256

Two defects in method.kick() of the utube driver, both in the
'ready_buffer' storage mode. utubettl does the same thing correctly via
update_ready().

1. When the utube had no entry in the ready buffer, kick() called

       put_ready(self, task[3])

   while the helper is put_ready(self, id, utube). The utube name was
   passed as the task id and the utube became nil, so the insert failed
   on the space format and the error was swallowed by the pcall inside
   put_ready(). The kicked task stayed READY but was never returned by
   take(), because take_ready() only looks at the ready buffer.

2. When the utube already had a younger task in the buffer, kick()
   replaced it with

       self.space_ready_buffer:insert({task[1], task[2]})

   that is {id, status} instead of {id, utube}. The status string landed
   in the utube field, so the buffer no longer had an entry under the
   real utube name and a later put() added a second one. With two entries
   for one utube the driver could take two tasks of the same utube at
   once, which breaks the main utube guarantee, and take_ready() could
   spin forever on an entry whose utube already had a TAKEN task.

Introduce update_ready() mirroring the utubettl helper and use it in
kick().

Also commit the transaction before the early returns of kick(): with no
buried tasks kick() returned while the transaction opened by
begin_if_not_in_txn() was still running, and it leaked into whatever the
caller fiber did next. This part is within the scope of #231.

Closes #256
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.

utube: kick() corrupts the ready buffer in the ready_buffer storage mode

1 participant