[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