diff --git a/CHANGELOG.md b/CHANGELOG.md index ae8bf02..a2d7a4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/queue/init.lua b/queue/init.lua index 40b9268..575dda1 100644 --- a/queue/init.lua +++ b/queue/init.lua @@ -1,3 +1,5 @@ +local fiber = require('fiber') + local abstract = require('queue.abstract') local queue_state = require('queue.abstract.queue_state') local queue = nil @@ -62,6 +64,19 @@ local orig_call = nil local wrapper_impl +local function orphan_waiter() + local wait_cond = fiber.cond() + local w = box.watch('box.status', function(_, new_status) + fiber.yield() + if new_status.status ~= 'orphan' then + wait_cond:signal() + end + end) + wait_cond:wait() + w:unregister() + return wrapper_impl() +end + local function cfg_wrapper(...) box.cfg = orig_cfg return wrapper_impl(...) @@ -79,10 +94,15 @@ local function wrap_box_cfg() orig_cfg = box.cfg box.cfg = cfg_wrapper elseif type(box.cfg) == 'table' then - -- box.cfg after the first box.cfg call - local cfg_mt = getmetatable(box.cfg) - orig_call = cfg_mt.__call - cfg_mt.__call = cfg_call_wrapper + if box.info.ro_reason == 'orphan' then + -- Wait for the orphan instance. + fiber.new(orphan_waiter) + else + -- box.cfg after the first box.cfg call + local cfg_mt = getmetatable(box.cfg) + orig_call = cfg_mt.__call + cfg_mt.__call = cfg_call_wrapper + end else error('The box.cfg type is unexpected: ' .. type(box.cfg)) end