Skip to content

Commit

Permalink
api: fix INIT state stuck
Browse files Browse the repository at this point in the history
Sometimes, instance could enter the queue initialization
while still in the orphan mode. This resulted in "lazy
start". But tarantool does not call `box.cfg {}` after
leaving orphan mode, so queue was stuck in the `INIT` state.

Now we wait for all orphan instances on the init stage of the queue.

Closes #226
  • Loading branch information
DerekBum committed Apr 4, 2024
1 parent 5f2b145 commit 20fc849
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 0 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Fixed

- Stuck in `INIT` state if instance failed to leave `orphan` mode in time (#226).

## [1.3.3] - 2023-09-13

### Fixed
Expand Down
23 changes: 23 additions & 0 deletions queue/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,20 @@ local function cfg_call_wrapper(cfg, ...)
return wrapper_impl(...)
end

local function orphan_waiter()
local fiber = require('fiber')
local wait_for_orphan = fiber.new(function()
while true do
if box.info.status ~= 'orphan' then
break
end
fiber.sleep(0.1)
end
end)
wait_for_orphan:set_joinable(true)
wait_for_orphan:join()
end

local function wrap_box_cfg()
if type(box.cfg) == 'function' then
-- box.cfg before the first box.cfg call
Expand All @@ -97,6 +111,11 @@ function wrapper_impl(...)
error(result[2])
end

if box.info.ro_reason == 'orphan' then
-- Wait for the orphan instance.
orphan_waiter()
end

if box.info.ro == false then
local abstract = require 'queue.abstract'
for name, val in pairs(abstract) do
Expand All @@ -121,6 +140,10 @@ end
-- configured with read_only = false. Otherwise, a start is
-- delayed until the instance will be configured with read_only = false.
local function queue_init()
if rawget(box, 'space') ~= nil and box.info.ro_reason == 'orphan' then
-- Wait for the orphan instance.
orphan_waiter()
end
if rawget(box, 'space') ~= nil and box.info.ro == false then
-- The box was configured with read_only = false
queue = require('queue.abstract')
Expand Down

0 comments on commit 20fc849

Please sign in to comment.