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

Vladimir Davydov vdavydov.dev at gmail.com
Sat Feb 10 19:49:00 MSK 2018


It will help resolve box.once() conflicts in case master is rw
and replica is ro.

Closes #2537
---
 src/box/lua/schema.lua         |  1 +
 test/replication/once.result   | 48 ++++++++++++++++++++++++++++++++++++++++++
 test/replication/once.test.lua | 18 ++++++++++++++++
 3 files changed, 67 insertions(+)

diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index 207e9444..89e27555 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -2194,6 +2194,7 @@ box.once = function(key, func, ...)
     if box.space._schema:get{key} ~= nil then
         return
     end
+    box.ctl.wait_rw()
     box.space._schema:put{key}
     return func(...)
 end
diff --git a/test/replication/once.result b/test/replication/once.result
index 1abc482a..99ac05b7 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,48 @@ 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}
+---
+...
+ch = fiber.channel(1)
+---
+...
+_ = fiber.create(function() box.once("ro", f, 1) ch:put(true) end)
+---
+...
+fiber.sleep(0.001)
+---
+...
+once -- nil
+---
+- null
+...
+box.cfg{read_only = false}
+---
+...
+ch:get()
+---
+- true
+...
+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..264c6367 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,19 @@ 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}
+ch = fiber.channel(1)
+_ = fiber.create(function() box.once("ro", f, 1) ch:put(true) end)
+fiber.sleep(0.001)
+once -- nil
+box.cfg{read_only = false}
+ch:get()
+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