[PATCH] Make box.once() wait until instance enters rw mode

Vladimir Davydov vdavydov.dev at gmail.com
Thu Feb 1 15:00:37 MSK 2018


If master is rw and replica is ro, it will help resolve box.once
conflicts.
---
Branch: box-once-wait-rw

 src/box/lua/schema.lua         |  5 +++++
 test/engine/iterator.result    |  2 +-
 test/engine/savepoint.result   | 12 ++++++------
 test/replication/once.result   | 44 ++++++++++++++++++++++++++++++++++++++++++
 test/replication/once.test.lua | 17 ++++++++++++++++
 5 files changed, 73 insertions(+), 7 deletions(-)

diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index 207e9444..d7cb32cd 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -1,6 +1,7 @@
 -- schema.lua (internal file)
 --
 local ffi = require('ffi')
+local fiber = require('fiber')
 local msgpack = require('msgpack')
 local msgpackffi = require('msgpackffi')
 local fun = require('fun')
@@ -2191,6 +2192,10 @@ box.once = function(key, func, ...)
     end
 
     local key = "once"..key
+    -- Wait until the instance enters rw mode.
+    while box.space._schema:get{key} == nil and box.info.ro do
+        fiber.sleep(1)
+    end
     if box.space._schema:get{key} ~= nil then
         return
     end
diff --git a/test/engine/iterator.result b/test/engine/iterator.result
index 63fead40..35376c00 100644
--- a/test/engine/iterator.result
+++ b/test/engine/iterator.result
@@ -4215,7 +4215,7 @@ s:replace{35}
 ...
 state, value = gen(param,state)
 ---
-- error: 'builtin/box/schema.lua:975: usage: next(param, state)'
+- error: 'builtin/box/schema.lua:976: usage: next(param, state)'
 ...
 value
 ---
diff --git a/test/engine/savepoint.result b/test/engine/savepoint.result
index 9d238ecc..6e079587 100644
--- a/test/engine/savepoint.result
+++ b/test/engine/savepoint.result
@@ -14,7 +14,7 @@ s1 = box.savepoint()
 ...
 box.rollback_to_savepoint(s1)
 ---
-- error: 'builtin/box/schema.lua:298: Usage: box.rollback_to_savepoint(savepoint)'
+- error: 'builtin/box/schema.lua:299: Usage: box.rollback_to_savepoint(savepoint)'
 ...
 box.begin() s1 = box.savepoint()
 ---
@@ -323,27 +323,27 @@ test_run:cmd("setopt delimiter ''");
 ok1, errmsg1
 ---
 - false
-- 'builtin/box/schema.lua:298: Usage: box.rollback_to_savepoint(savepoint)'
+- 'builtin/box/schema.lua:299: Usage: box.rollback_to_savepoint(savepoint)'
 ...
 ok2, errmsg2
 ---
 - false
-- 'builtin/box/schema.lua:298: Usage: box.rollback_to_savepoint(savepoint)'
+- 'builtin/box/schema.lua:299: Usage: box.rollback_to_savepoint(savepoint)'
 ...
 ok3, errmsg3
 ---
 - false
-- 'builtin/box/schema.lua:298: Usage: box.rollback_to_savepoint(savepoint)'
+- 'builtin/box/schema.lua:299: Usage: box.rollback_to_savepoint(savepoint)'
 ...
 ok4, errmsg4
 ---
 - false
-- 'builtin/box/schema.lua:298: Usage: box.rollback_to_savepoint(savepoint)'
+- 'builtin/box/schema.lua:299: Usage: box.rollback_to_savepoint(savepoint)'
 ...
 ok5, errmsg5
 ---
 - false
-- 'builtin/box/schema.lua:298: Usage: box.rollback_to_savepoint(savepoint)'
+- 'builtin/box/schema.lua:299: Usage: box.rollback_to_savepoint(savepoint)'
 ...
 s:select{}
 ---
diff --git a/test/replication/once.result b/test/replication/once.result
index 1abc482a..247641df 100644
--- a/test/replication/once.result
+++ b/test/replication/once.result
@@ -1,3 +1,6 @@
+fiber = require('fiber')
+---
+...
 box.once()
 ---
 - error: 'Illegal parameters, Usage: box.once(key, func, ...)'
@@ -37,3 +40,44 @@ once
 ---
 - 1
 ...
+-- Check that box.once() does not fail if the instance is read-only,
+-- instead it waits until the instance enters read-write mode.
+once = nil
+---
+...
+box.cfg{read_only = true}
+---
+...
+_ = fiber.create(function() box.once("ro", f, 1) end)
+---
+...
+fiber.sleep(0.5)
+---
+...
+once -- nil
+---
+- null
+...
+box.cfg{read_only = false}
+---
+...
+while once == nil do fiber.sleep(0.001) end
+---
+...
+once -- 1
+---
+- 1
+...
+box.cfg{read_only = true}
+---
+...
+box.once("ro", f, 1) -- ok, already done
+---
+...
+once -- 1
+---
+- 1
+...
+box.cfg{read_only = false}
+---
+...
diff --git a/test/replication/once.test.lua b/test/replication/once.test.lua
index b3b62b1f..33469ef9 100644
--- a/test/replication/once.test.lua
+++ b/test/replication/once.test.lua
@@ -1,3 +1,5 @@
+fiber = require('fiber')
+
 box.once()
 box.once("key")
 box.once("key", "key")
@@ -10,3 +12,18 @@ box.once("test", f, 1)
 once
 box.once("test", f, 1)
 once
+
+-- Check that box.once() does not fail if the instance is read-only,
+-- instead it waits until the instance enters read-write mode.
+once = nil
+box.cfg{read_only = true}
+_ = fiber.create(function() box.once("ro", f, 1) end)
+fiber.sleep(0.5)
+once -- nil
+box.cfg{read_only = false}
+while once == nil do fiber.sleep(0.001) end
+once -- 1
+box.cfg{read_only = true}
+box.once("ro", f, 1) -- ok, already done
+once -- 1
+box.cfg{read_only = false}
-- 
2.11.0




More information about the Tarantool-patches mailing list