[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