[PATCH] Make box.once() wait until instance enters rw mode
Konstantin Osipov
kostja at tarantool.org
Thu Feb 1 15:11:09 MSK 2018
* Vladimir Davydov <vdavydov.dev at gmail.com> [18/02/01 15:02]:
Terrible fix.
Please add a channel which will be notified when leaving RO
> 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
--
Konstantin Osipov, Moscow, Russia, +7 903 626 22 32
http://tarantool.org - www.twitter.com/kostja_osipov
More information about the Tarantool-patches
mailing list