Skip to content

Commit

Permalink
replicaset_mode: allow api call in init state
Browse files Browse the repository at this point in the history
In replicaset mode, the user can attempt to call public methods on the replica start.
For example, a single script is used for master and replica.

This patch allows you to call a public method in the INIT state without
interrupting the script by exiting with an obscure error.
It will only log an attempt to call a method from the check_state function,
which is present at the beginning of each public method.

Closes #216
  • Loading branch information
0x501D authored and LeonidVas committed Sep 13, 2023
1 parent c3cdc7b commit 6bc1d63
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 4 deletions.
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,27 @@ 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]

- In replicaset mode, the behavior of the public API is reduced to the same behavior
in all queue states, including INIT. Previously, in the INIT state, an ambiguous
error was thrown when trying to access a public method on a replica and the script
was interrupted by an error.

Old behavior (call `create_tube` on replica, queue is in INIT state):
```
2023-09-04 14:01:11.000 [5990] main/103/replica.lua/box.load_cfg I> set 'read_only' configuration option to true
stack traceback:
/home/void/tmp/cluster/repl/queue/init.lua:44: in function '__index'
replica.lua:13: in main chunk
2023-09-04 14:01:11.004 [5990] main/105/checkpoint_daemon I> scheduled next checkpoint for Mon Sep 4 15:11:32 2023
2023-09-04 14:01:11.004 [5990] main utils.c:610 E> LuajitError: /home/void/tmp/cluster/repl/queue/init.lua:45: Please configure box.cfg{} in read/write mode first
```
After this fix:
```
2023-09-11 10:24:31.463 [19773] main/103/replica.lua abstract.lua:93 E> create_tube: queue is in INIT state
```

## [1.3.2] - 2023-08-24

### Fixed
Expand Down
16 changes: 13 additions & 3 deletions queue/init.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
local abstract = require('queue.abstract')
local queue_state = require('queue.abstract.queue_state')
local queue = nil

Expand Down Expand Up @@ -40,9 +41,18 @@ queue = setmetatable({
state = queue_state.show,
cfg = deferred_cfg,
_VERSION = require('queue.version'),
}, { __index = function()
print(debug.traceback())
error('Please configure box.cfg{} in read/write mode first')
}, { __index = function(self, key)
-- In replicaset mode, the user can attempt to call public methods on the replica start.
-- For example, a single script is used for master and replica.
-- Each public method has a check on the state of the queue, so this forwarding is safe.
if deferred_opts['in_replicaset'] == true then
if abstract[key] ~= nil then
return abstract[key]
end
else
print(debug.traceback())
error('Please configure box.cfg{} in read/write mode first')
end
end
})

Expand Down
4 changes: 3 additions & 1 deletion t/200-master-replica.t
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ local conn = {}
test:plan(8)

test:test('Check master-replica setup', function(test)
test:plan(8)
test:plan(9)
local engine = os.getenv('ENGINE') or 'memtx'
tnt.cluster.cfg{}

Expand All @@ -41,6 +41,8 @@ test:test('Check master-replica setup', function(test)

-- Setup tube. Set ttr = 0.5 for sessions expire testing.
conn:call('queue.cfg', {{ttr = 0.5, in_replicaset = true}})
test:isnil(conn:call('queue.create_tube', {'test', 'fifo'}),
'check api call in INIT state')
queue.cfg{ttr = 0.5, in_replicaset = true}
local tube = queue.create_tube('test', 'fifo', {engine = engine})
test:ok(tube, 'test tube created')
Expand Down

0 comments on commit 6bc1d63

Please sign in to comment.