|
24 | 24 | queue = setmetatable({
|
25 | 25 | driver = core_drivers,
|
26 | 26 | register_driver = register_driver,
|
27 |
| -}, { __index = function() print(debug.traceback()) error("Please run box.cfg{} first") end }) |
| 27 | +}, { __index = function() |
| 28 | + print(debug.traceback()) |
| 29 | + error('Please configure box.cfg{} in read/write mode first') |
| 30 | + end |
| 31 | +}) |
28 | 32 |
|
29 |
| -local function queue_init() |
30 |
| - if rawget(box, 'space') == nil then |
31 |
| - local orig_cfg = box.cfg |
32 |
| - box.cfg = function(...) |
33 |
| - local result = { orig_cfg(...) } |
34 |
| - |
35 |
| - local abstract = require 'queue.abstract' |
36 |
| - for name, val in pairs(abstract) do |
37 |
| - rawset(queue, name, val) |
38 |
| - end |
39 |
| - abstract.driver = queue.driver |
40 |
| - setmetatable(queue, getmetatable(abstract)) |
41 |
| - queue.start() |
42 |
| - |
43 |
| - return unpack(result) |
| 33 | +-- Used to store the original methods |
| 34 | +local orig_cfg = nil |
| 35 | +local orig_call = nil |
| 36 | + |
| 37 | +local wrapper_impl |
| 38 | + |
| 39 | +local function cfg_wrapper(...) |
| 40 | + box.cfg = orig_cfg |
| 41 | + return wrapper_impl(...) |
| 42 | +end |
| 43 | + |
| 44 | +local function cfg_call_wrapper(cfg, ...) |
| 45 | + local cfg_mt = getmetatable(box.cfg) |
| 46 | + cfg_mt.__call = orig_call |
| 47 | + return wrapper_impl(...) |
| 48 | +end |
| 49 | + |
| 50 | +local function wrap_box_cfg() |
| 51 | + if type(box.cfg) == 'function' then |
| 52 | + -- box.cfg before the first box.cfg call |
| 53 | + orig_cfg = box.cfg |
| 54 | + box.cfg = cfg_wrapper |
| 55 | + elseif type(box.cfg) == 'table' then |
| 56 | + -- box.cfg after the first box.cfg call |
| 57 | + local cfg_mt = getmetatable(box.cfg) |
| 58 | + orig_call = cfg_mt.__call |
| 59 | + cfg_mt.__call = cfg_call_wrapper |
| 60 | + else |
| 61 | + error('The box.cfg type is unexpected: ' .. type(box.cfg)) |
| 62 | + end |
| 63 | +end |
| 64 | + |
| 65 | +function wrapper_impl(...) |
| 66 | + local result = { pcall(box.cfg,...) } |
| 67 | + if result[1] then |
| 68 | + table.remove(result, 1) |
| 69 | + else |
| 70 | + wrap_box_cfg() |
| 71 | + error(result[2]) |
| 72 | + end |
| 73 | + |
| 74 | + if box.info.ro == false then |
| 75 | + local abstract = require 'queue.abstract' |
| 76 | + for name, val in pairs(abstract) do |
| 77 | + rawset(queue, name, val) |
44 | 78 | end
|
| 79 | + abstract.driver = queue.driver |
| 80 | + setmetatable(queue, getmetatable(abstract)) |
| 81 | + queue.start() |
45 | 82 | else
|
46 |
| - queue = require 'queue.abstract' |
| 83 | + -- Delay a start until the box will be configured |
| 84 | + -- with read_only = false |
| 85 | + wrap_box_cfg() |
| 86 | + end |
| 87 | + return unpack(result) |
| 88 | +end |
| 89 | + |
| 90 | +--- Implementation of the “lazy start” procedure. |
| 91 | +-- The queue module is loaded immediately if the instance was |
| 92 | +-- configured with read_only = false. Otherwise, a start is |
| 93 | +-- delayed until the instance will be configured with read_only = false. |
| 94 | +local function queue_init() |
| 95 | + if rawget(box, 'space') ~= nil and box.info.ro == false then |
| 96 | + -- The box was configured with read_only = false |
| 97 | + queue = require('queue.abstract') |
47 | 98 | queue.register_driver = register_driver
|
48 | 99 | queue.driver = core_drivers
|
49 | 100 | queue.start()
|
| 101 | + else |
| 102 | + wrap_box_cfg() |
50 | 103 | end
|
51 | 104 | end
|
52 | 105 |
|
|
0 commit comments