diff --git a/CHANGELOG.md b/CHANGELOG.md index 1603b2a..d02db6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ - Fixed a bug when `server:grep_log()` failed to find a string logged in `server:exec()` called immediately before it (gh-421). +- Fixed `cluster:sync()` to drop instances removed from the config. It is + now possible to reload the config with `cluster:reload()` after removing + an instance (gh-423). ## 1.1.0 diff --git a/luatest/cluster.lua b/luatest/cluster.lua index 28ca9bc..789b188 100644 --- a/luatest/cluster.lua +++ b/luatest/cluster.lua @@ -197,6 +197,7 @@ end -- -- * Write the new config into the config file. -- * Update the internal list of instances. +-- * Drops instances removed from the config. -- -- @tab config New config. function Cluster:sync(config) @@ -206,16 +207,26 @@ function Cluster:sync(config) treegen.write_file(self._dir, self._config_file_rel, yaml.encode(config)) - for i, name in ipairs(instance_names) do - if self._server_map[name] == nil then - local iserver = server:new(fun.chain(self._server_opts, { + local old_server_map = self._server_map + self._server_map = {} + self._servers = {} + + for _, name in ipairs(instance_names) do + local iserver = old_server_map[name] + if iserver == nil then + iserver = server:new(fun.chain(self._server_opts, { alias = name, }):tomap()) - table.insert(self._servers, i, iserver) - self._server_map[name] = iserver + else + old_server_map[name] = nil end + self._server_map[name] = iserver + table.insert(self._servers, iserver) end + for _, iserver in pairs(old_server_map) do + iserver:drop() + end end --- Reload configuration on all the instances. diff --git a/test/cluster_test.lua b/test/cluster_test.lua index 51bdf7f..9dcab5d 100644 --- a/test/cluster_test.lua +++ b/test/cluster_test.lua @@ -133,34 +133,41 @@ g.test_sync = function() :use_group('g-001') :use_replicaset('r-001') :add_instance('i-001', {}) + :use_replicaset('r-002') + :add_instance('i-002', {}) :config() local c = cluster:new(config, server_opts) - t.assert_equals(c:size(), 1) + t.assert_equals(c:size(), 2) c:start() - assert_instance_running(c, 'i-001') - c:stop() - assert_instance_stopped(c, 'i-001') + local server1 = c['i-001'] + local server2 = c['i-002'] + t.assert_is_not(server1.process, nil) + t.assert_is_not(server2.process, nil) local config2 = cbuilder:new() :use_group('g-001') - :use_replicaset('r-001') + :use_replicaset('r-002') :add_instance('i-002', {}) :use_group('g-002') - :use_replicaset('r-002') + :use_replicaset('r-003') :add_instance('i-003', {}) :config() c:sync(config2) - t.assert_equals(c:size(), 3) + t.assert_is(c['i-001'], nil) + t.assert_is(c['i-002'], server2) + t.assert_is(server1.process, nil) + t.assert_is_not(server2.process, nil) + + t.assert_equals(c:size(), 2) - c:start_instance('i-002') c:start_instance('i-003') assert_instance_running(c, 'i-002') assert_instance_running(c, 'i-003')