flare-tools 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 51a516a3ee2ee78de4e03ac77194243273ef4b97
4
+ data.tar.gz: 8e3c8e3cfcb570b6207c784f43c25882b4fe8d42
5
+ SHA512:
6
+ metadata.gz: 6d5145f2207134f8fdac4574db9fecb08d34accbd2532be32528bf90c029b816d722a9392840364e4fe5a18fe108d18ee453f145fd40413f34153015f77cf23e
7
+ data.tar.gz: f8cc80b90393f36481cb8668076fc2c49bf2ca11994f589971a5dbc04aa4cf055739196a5e92aec25e4e84fcf002b41da5f105837cf29ea3589998398bd68038
@@ -1,13 +1,13 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.3
4
3
  - 1.8.7
4
+ - 1.9.3
5
5
  - 2.0.0
6
- - 2.1.3
6
+ - 2.1.5
7
7
  before_install:
8
8
  - travis_retry sudo apt-get update
9
9
  - travis_retry sudo apt-get install libtokyocabinet-dev
10
- - travis_retry sudo apt-get install libboost-program-options-dev libboost-regex-dev libboost-serialization-dev libboost-thread-dev
10
+ - travis_retry sudo apt-get install libboost-program-options-dev libboost-regex-dev libboost-serialization-dev libboost-thread-dev libboost-system-dev
11
11
  - travis_retry sudo apt-get install uuid-dev
12
12
  - git clone https://github.com/gree/flare.git flare
13
13
  - (cd flare && ./autogen.sh)
@@ -1,3 +1,11 @@
1
+ === 0.7.0 / 2014-12-12
2
+ * Major Enhancements
3
+ * Modify 'remove' subcommand behavior.
4
+ * Now flare-tools can remove a downed node.
5
+ * Minor Enhancements
6
+ * Fixed sometimes stats command abort.
7
+ * Fixed flare-deploy command degraded
8
+
1
9
  === 0.6.0 / 2014-11-07
2
10
  * Minor Enhancements
3
11
  * Modify default options to safely
data/README.txt CHANGED
@@ -101,7 +101,7 @@ Please see the stats subcommand section of flare-admin for further detail.
101
101
  -c, --count=[REPEATTIME] repeat count
102
102
  --delimiter=[CHAR] delimiter
103
103
 
104
- === flare-stdmin
104
+ === flare-admin
105
105
 
106
106
  Flare-admin consists of a battery of subcommands used for maintaining a flare cluster.
107
107
  You must specify the hostname and port number of the index node by telling them as options
@@ -305,12 +305,9 @@ subcommands:
305
305
  --quiet use quiet mode
306
306
 
307
307
  [remove] remove a node. (experimental)
308
- Usage: flare-admin remove
308
+ Usage: flare-admin remove [hostname:port] ...
309
309
  --force commit changes without confirmation
310
- --wait=[SECOND] specify the time to wait node for getting ready (default:30)
311
- --retry=[COUNT] retry count(default:5)
312
- --connection-threshold=[COUNT]
313
- specify connection threashold (default:2)
310
+ --retry=COUNT retry count(default:0)
314
311
 
315
312
  [dump] dump data from nodes. (experimental)
316
313
  Usage: flare-admin dump [hostname:port] ...
@@ -42,13 +42,23 @@ You can find debian packages at http://labs.gree.jp/Top/OpenSource/Flare/Downloa
42
42
 
43
43
  == Installing flare-tools
44
44
 
45
- Flare-tools hasn't been published to the public gem repository yet, so please pull the
46
- code from the git repository and type "rake install_gem" in your shell.
45
+ === Before install
47
46
 
48
- mynode1$ sudo gem install hoe newgem rdoc
49
- mynode1$ git clone ...
50
- mynode1$ cd flare-tools
51
- mynode1$ rake rake install_gem
47
+ flare-tools and dependent gem packages require the libraries shown below.
48
+
49
+ - libtokyocabinet
50
+ - libbz2
51
+ - zlib
52
+
53
+ You should install these libraries before installing flare-tools. For example, if you are using Debian / Ubuntu:
54
+
55
+ mynode1$ sudo apt-get install libtokyocabinet-dev libbz2-dev zlib1g-dev rubygems
56
+
57
+ === Install
58
+
59
+ flare-tools is available on rubygems.
60
+
61
+ mynode1$ gem install flare-tools
52
62
 
53
63
  == Setting up your index server.
54
64
 
@@ -3,4 +3,19 @@
3
3
 
4
4
  $LOAD_PATH.unshift File.dirname(__FILE__)+"/../lib"
5
5
 
6
- require 'flare/tools/cli/flare_argv0.rb'
6
+ require 'flare/tools/cli/dispatch'
7
+
8
+ cliname = "deploy"
9
+ argv = ARGV.dup
10
+
11
+ # We should clear ARGV to use (Kernel#)gets.
12
+ # see also: http://stackoverflow.com/questions/1883925/kernelgets-attempts-to-read-file-instead-of-standard-input
13
+ ARGV.clear
14
+
15
+ class Flare::Tools::Cli::DispatchWithDeploy < Flare::Tools::Cli::Dispatch
16
+ def initialize
17
+ super
18
+ @subcommands['deploy'] = Flare::Tools::Cli::Deploy
19
+ end
20
+ end
21
+ Flare::Tools::Cli::DispatchWithDeploy.new.main(cliname, argv, false)
@@ -3,4 +3,19 @@
3
3
 
4
4
  $LOAD_PATH.unshift File.dirname(__FILE__)+"/../lib"
5
5
 
6
- require 'flare/tools/cli/flare_argv0.rb'
6
+ require 'flare/tools/cli/dispatch'
7
+
8
+ cliname = "deploy"
9
+ argv = ARGV.dup
10
+
11
+ # We should clear ARGV to use (Kernel#)gets.
12
+ # see also: http://stackoverflow.com/questions/1883925/kernelgets-attempts-to-read-file-instead-of-standard-input
13
+ ARGV.clear
14
+
15
+ class Flare::Tools::Cli::DispatchWithDeploy < Flare::Tools::Cli::Dispatch
16
+ def initialize
17
+ super
18
+ @subcommands['deploy'] = Flare::Tools::Cli::Deploy
19
+ end
20
+ end
21
+ Flare::Tools::Cli::DispatchWithDeploy.new.main(cliname, argv, false)
@@ -3,4 +3,19 @@
3
3
 
4
4
  $LOAD_PATH.unshift File.dirname(__FILE__)+"/../lib"
5
5
 
6
- require 'flare/tools/cli/flare_argv0.rb'
6
+ require 'flare/tools/cli/dispatch'
7
+
8
+ cliname = "deploy"
9
+ argv = ARGV.dup
10
+
11
+ # We should clear ARGV to use (Kernel#)gets.
12
+ # see also: http://stackoverflow.com/questions/1883925/kernelgets-attempts-to-read-file-instead-of-standard-input
13
+ ARGV.clear
14
+
15
+ class Flare::Tools::Cli::DispatchWithDeploy < Flare::Tools::Cli::Dispatch
16
+ def initialize
17
+ super
18
+ @subcommands['deploy'] = Flare::Tools::Cli::Deploy
19
+ end
20
+ end
21
+ Flare::Tools::Cli::DispatchWithDeploy.new.main(cliname, argv, false)
@@ -3,4 +3,19 @@
3
3
 
4
4
  $LOAD_PATH.unshift File.dirname(__FILE__)+"/../lib"
5
5
 
6
- require 'flare/tools/cli/flare_argv0.rb'
6
+ require 'flare/tools/cli/dispatch'
7
+
8
+ cliname = "deploy"
9
+ argv = ARGV.dup
10
+
11
+ # We should clear ARGV to use (Kernel#)gets.
12
+ # see also: http://stackoverflow.com/questions/1883925/kernelgets-attempts-to-read-file-instead-of-standard-input
13
+ ARGV.clear
14
+
15
+ class Flare::Tools::Cli::DispatchWithDeploy < Flare::Tools::Cli::Dispatch
16
+ def initialize
17
+ super
18
+ @subcommands['deploy'] = Flare::Tools::Cli::Deploy
19
+ end
20
+ end
21
+ Flare::Tools::Cli::DispatchWithDeploy.new.main(cliname, argv, false)
@@ -3,4 +3,19 @@
3
3
 
4
4
  $LOAD_PATH.unshift File.dirname(__FILE__)+"/../lib"
5
5
 
6
- require 'flare/tools/cli/flare_argv0.rb'
6
+ require 'flare/tools/cli/dispatch'
7
+
8
+ cliname = "deploy"
9
+ argv = ARGV.dup
10
+
11
+ # We should clear ARGV to use (Kernel#)gets.
12
+ # see also: http://stackoverflow.com/questions/1883925/kernelgets-attempts-to-read-file-instead-of-standard-input
13
+ ARGV.clear
14
+
15
+ class Flare::Tools::Cli::DispatchWithDeploy < Flare::Tools::Cli::Dispatch
16
+ def initialize
17
+ super
18
+ @subcommands['deploy'] = Flare::Tools::Cli::Deploy
19
+ end
20
+ end
21
+ Flare::Tools::Cli::DispatchWithDeploy.new.main(cliname, argv, false)
@@ -0,0 +1,22 @@
1
+ # -*- coding: utf-8; -*-
2
+ # Authors:: Yuya YAGUCHI <yuya.yaguchi@gree.net>
3
+ # Copyright:: Copyright (C) GREE, Inc. 2014.
4
+ # License:: MIT-style
5
+
6
+ require 'flare/util/interruption'
7
+
8
+ module Flare; end
9
+ module Flare::Cli; end
10
+ module Flare::Cli::AskNodeRemove
11
+
12
+ # @param [Flare::Entity::Server] server
13
+ # @param [Flare::Tools::Cluster::NodeStat] node_stat
14
+ # @return [Boolean] approved
15
+ def ask_node_remove(server, node_stat)
16
+ STDERR.print "remove the node from a cluster (node=#{server}, role=#{node_stat.role}, state=#{node_stat.state}) (y/n): "
17
+ interruptible {
18
+ STDIN.gets.chomp.upcase == "Y"
19
+ }
20
+ end
21
+
22
+ end
@@ -0,0 +1,29 @@
1
+ # -*- coding: utf-8; -*-
2
+ # Authors:: Yuya YAGUCHI <yuya.yaguchi@gree.net>
3
+ # Copyright:: Copyright (C) GREE, Inc. 2014.
4
+ # License:: MIT-style
5
+
6
+ require 'flare/entity/server'
7
+
8
+ module Flare; end
9
+ module Flare::Cli; end
10
+ module Flare::Cli::ParseHostPortPairs
11
+ Entity = Flare::Entity
12
+
13
+ # @param [String] args
14
+ # @return [Array] server entities
15
+ # @return [nil]
16
+ def parse_host_port_pairs(args)
17
+ servers = args.map {|x| x.split(':')}
18
+ servers.each do |x|
19
+ if x.size != 2
20
+ error "invalid argument '#{x.join(':')}'. it must be hostname:port."
21
+ return nil
22
+ end
23
+ end
24
+ servers.map do |s|
25
+ Entity::Server.new(s[0], s[1])
26
+ end
27
+ end
28
+
29
+ end
@@ -2,6 +2,10 @@ module Flare; end
2
2
  module Flare::Entity; end
3
3
  class Flare::Entity::Server < Struct.new(:host, :port)
4
4
  def to_s
5
+ nodekey
6
+ end
7
+
8
+ def nodekey
5
9
  "#{self.host}:#{self.port}"
6
10
  end
7
11
  end
@@ -0,0 +1,33 @@
1
+ # -*- coding: utf-8; -*-
2
+ # Authors:: Yuya YAGUCHI <yuya.yaguchi@gree.net>
3
+ # Copyright:: Copyright (C) GREE, Inc. 2014.
4
+ # License:: MIT-style
5
+
6
+ module Flare; end
7
+ module Flare::Operation; end
8
+ module Flare::Operation::NodeRemove
9
+
10
+ # @param [Flare::Tools::Cluster::NodeStat] node_stat
11
+ # @return [Boolean]
12
+ def node_can_remove_safely?(node_stat)
13
+ node_stat.proxy? && node_stat.down?
14
+ end
15
+
16
+ # @param [Flare::Tools::IndexServer] client index server client
17
+ # @param [Flare::Entity::Server] server
18
+ # @param [Integer] retry_count
19
+ # @param [Boolean] dry_run
20
+ # @return [Boolean] succeeded
21
+ def node_remove(client, server, retry_count, dry_run)
22
+ (retry_count + 1).times do
23
+ resp = false
24
+ info "removing #{server}."
25
+ resp = client.node_remove(server.host, server.port) unless dry_run
26
+ if resp
27
+ return true
28
+ end
29
+ end
30
+ return false
31
+ end
32
+
33
+ end
@@ -73,12 +73,17 @@ module Flare
73
73
  node = @nodes[hostname_port] = Node.new(hostname_port, pid)
74
74
  node
75
75
  end
76
-
76
+
77
77
  def shutdown
78
78
  daemon = Daemon.instance
79
79
  daemon.shutdown
80
80
  end
81
81
 
82
+ def shutdown_node(node)
83
+ daemon = Daemon.instance
84
+ daemon.shutdown_flared(node.pid)
85
+ end
86
+
82
87
  def nodes
83
88
  @nodes.values
84
89
  end
@@ -36,19 +36,7 @@ module Flare
36
36
  def shutdown
37
37
  STDERR.print "killing..."
38
38
  (@flared+@flarei).each do |pid|
39
- STDERR.print " #{pid}"
40
- begin
41
- timeout(10) do
42
- Process.kill :TERM, pid
43
- Process.waitpid pid
44
- end
45
- rescue Errno::ESRCH
46
- STDERR.print "?"
47
- rescue TimeoutError => e
48
- Process.kill :KILL, pid
49
- Process.waitpid pid
50
- STDERR.print "*"
51
- end
39
+ kill_node_process(pid)
52
40
  end
53
41
  STDERR.print "\n"
54
42
  Process.waitall
@@ -126,6 +114,16 @@ module Flare
126
114
  pid
127
115
  end
128
116
 
117
+ def shutdown_flared(target_pid)
118
+ STDERR.print "killing node..."
119
+ @flared.each_with_index do |pid, i|
120
+ next unless pid == target_pid
121
+ kill_node_process(pid)
122
+ end
123
+ STDERR.print "\n"
124
+ @flared.delete(target_pid)
125
+ end
126
+
129
127
  def deleteall(delthem)
130
128
  return unless FileTest.exist?(delthem)
131
129
  if FileTest.directory?(delthem)
@@ -139,6 +137,24 @@ module Flare
139
137
  end
140
138
  end
141
139
 
140
+ private
141
+
142
+ def kill_node_process(pid)
143
+ STDERR.print " #{pid}"
144
+ begin
145
+ timeout(10) do
146
+ Process.kill :TERM, pid
147
+ Process.waitpid pid
148
+ end
149
+ rescue Errno::ESRCH
150
+ STDERR.print "?"
151
+ rescue TimeoutError => e
152
+ Process.kill :KILL, pid
153
+ Process.waitpid pid
154
+ STDERR.print "*"
155
+ end
156
+ end
157
+
142
158
  end
143
159
  end
144
160
  end
@@ -56,7 +56,7 @@ module Flare
56
56
  @alive = false
57
57
  end
58
58
 
59
- attr_reader :hostname, :port, :hostname_port
59
+ attr_reader :hostname, :port, :hostname_port, :pid
60
60
  end
61
61
  end
62
62
  end
@@ -9,7 +9,7 @@ module Flare
9
9
  # flare-tools module.
10
10
  module Tools
11
11
  # the version number of flare-tools
12
- VERSION = '0.6.0'
12
+ VERSION = '0.7.0'
13
13
  TITLE = "Flare-tools version #{VERSION} Copyright (C) GREE, Inc. 2011-2014"
14
14
  autoload :Common, 'flare/tools/common'
15
15
  autoload :Cluster, 'flare/tools/cluster'
@@ -3,29 +3,28 @@
3
3
  # Copyright:: Copyright (C) GREE, Inc. 2011.
4
4
  # License:: MIT-style
5
5
 
6
- #
7
6
  module Flare
8
7
  module Tools
9
8
  module Cli
10
- autoload :List, 'flare/tools/cli/list'
11
- autoload :Stats, 'flare/tools/cli/stats'
12
- autoload :Index, 'flare/tools/cli/index'
9
+ autoload :Activate, 'flare/tools/cli/activate'
13
10
  autoload :Balance, 'flare/tools/cli/balance'
11
+ autoload :Deploy, 'flare/tools/cli/deploy'
14
12
  autoload :Down, 'flare/tools/cli/down'
15
- autoload :Slave, 'flare/tools/cli/slave'
16
- autoload :Reconstruct, 'flare/tools/cli/reconstruct'
13
+ autoload :Dump, 'flare/tools/cli/dump'
14
+ autoload :Dumpkey, 'flare/tools/cli/dumpkey'
15
+ autoload :Index, 'flare/tools/cli/index'
16
+ autoload :List, 'flare/tools/cli/list'
17
17
  autoload :Master, 'flare/tools/cli/master'
18
- autoload :Deploy, 'flare/tools/cli/deploy'
19
- autoload :Threads, 'flare/tools/cli/threads'
18
+ autoload :Part, 'flare/tools/cli/part'
20
19
  autoload :Ping, 'flare/tools/cli/ping'
20
+ autoload :Reconstruct, 'flare/tools/cli/reconstruct'
21
21
  autoload :Remove, 'flare/tools/cli/remove'
22
- autoload :Activate, 'flare/tools/cli/activate'
23
- autoload :Dump, 'flare/tools/cli/dump'
24
- autoload :Dumpkey, 'flare/tools/cli/dumpkey'
25
- autoload :Verify, 'flare/tools/cli/verify'
26
22
  autoload :Restore, 'flare/tools/cli/restore'
23
+ autoload :Slave, 'flare/tools/cli/slave'
24
+ autoload :Stats, 'flare/tools/cli/stats'
27
25
  autoload :Summary, 'flare/tools/cli/summary'
28
- autoload :Part, 'flare/tools/cli/part'
26
+ autoload :Threads, 'flare/tools/cli/threads'
27
+ autoload :Verify, 'flare/tools/cli/verify'
29
28
  end
30
29
  end
31
30
  end
@@ -19,28 +19,29 @@ class Flare::Tools::Cli::Dispatch
19
19
 
20
20
  def initialize
21
21
  @subcommands = {
22
- 'list' => Cli::List,
22
+ 'activate' => Cli::Activate,
23
23
  'balance' => Cli::Balance,
24
24
  'down' => Cli::Down,
25
- 'slave' => Cli::Slave,
26
- 'reconstruct' => Cli::Reconstruct,
25
+ 'dump' => Cli::Dump,
26
+ 'dumpkey' => Cli::Dumpkey,
27
+ 'index' => Cli::Index,
28
+ 'list' => Cli::List,
27
29
  'master' => Cli::Master,
28
- 'threads' => Cli::Threads,
30
+ 'part' => Cli::Part,
29
31
  'ping' => Cli::Ping,
32
+ 'reconstruct' => Cli::Reconstruct,
30
33
  'remove' => Cli::Remove,
31
- 'index' => Cli::Index,
32
- 'activate' => Cli::Activate,
33
- 'dump' => Cli::Dump,
34
- 'dumpkey' => Cli::Dumpkey,
35
- 'verify' => Cli::Verify,
36
- 'stats' => Cli::Stats,
37
34
  'restore' => Cli::Restore,
35
+ 'slave' => Cli::Slave,
36
+ 'stats' => Cli::Stats,
38
37
  'summary' => Cli::Summary,
39
- 'part' => Cli::Part,
38
+ 'threads' => Cli::Threads,
39
+ 'verify' => Cli::Verify,
40
40
  }
41
41
  end
42
42
 
43
43
  def main(subcommand_name, argv, as_subcommand)
44
+ prepare
44
45
  _main(subcommand_name, argv, as_subcommand)
45
46
  rescue => e
46
47
  level = 1
@@ -55,6 +56,10 @@ class Flare::Tools::Cli::Dispatch
55
56
 
56
57
  private
57
58
 
59
+ def prepare
60
+ Thread.abort_on_exception = true
61
+ end
62
+
58
63
  def _main(subcommand_name, argv, as_subcommand)
59
64
  @subcommand_name = subcommand_name
60
65
 
@@ -1,122 +1,84 @@
1
1
  # -*- coding: utf-8; -*-
2
- # Authors:: Kiyoshi Ikehara <kiyoshi.ikehara@gree.net>
3
- # Copyright:: Copyright (C) GREE, Inc. 2011.
2
+ # Authors:: Yuya YAGUCHI <yuya.yaguchi@gree.net>
3
+ # Copyright:: Copyright (C) GREE, Inc. 2014.
4
4
  # License:: MIT-style
5
5
 
6
- require 'flare/tools/index_server'
7
- require 'flare/util/conversion'
8
6
  require 'flare/tools/common'
9
7
  require 'flare/tools/cli/sub_command'
10
8
  require 'flare/tools/cli/index_server_config'
9
+ require 'flare/cli/parse_host_port_pairs'
10
+ require 'flare/cli/ask_node_remove'
11
+ require 'flare/operation/node_remove'
11
12
 
12
- module Flare
13
- module Tools
14
- module Cli
13
+ module Flare; end
14
+ module Flare::Tools; end
15
+ module Flare::Tools::Cli; end
15
16
 
16
- class Remove < SubCommand
17
- include Flare::Util::Conversion
18
- include Flare::Tools::Common
19
- include Flare::Tools::Cli::IndexServerConfig
17
+ class Flare::Tools::Cli::Remove < Flare::Tools::Cli::SubCommand
18
+ include Flare::Tools::Common
19
+ include Flare::Tools::Cli::IndexServerConfig
20
+ include Flare::Cli::ParseHostPortPairs
21
+ include Flare::Cli::AskNodeRemove
22
+ include Flare::Operation::NodeRemove
20
23
 
21
- myname :remove
22
- desc "remove a node. (experimental)"
23
- usage "remove"
24
+ myname :remove
25
+ desc "remove a downed node."
26
+ usage "remove [hostname:port] ..."
24
27
 
25
- def setup
26
- super
27
- set_option_index_server
28
- set_option_dry_run
29
- set_option_force
30
- @optp.on('--wait=SECOND', "specify the time to wait node for getting ready (default:#{@wait})") {|v| @wait = v.to_i}
31
- @optp.on('--retry=COUNT', "retry count(default:#{@retry})") {|v| @retry = v.to_i}
32
- @optp.on('--connection-threshold=[COUNT]', "specify connection threashold (default:#{@connection_threshold})") {|v| @connection_threshold = v.to_i}
33
- end
28
+ def setup
29
+ super
30
+ set_option_index_server
31
+ set_option_dry_run
32
+ set_option_force
33
+ @optp.on('--retry=COUNT', "retry count(default:#{@retry})") {|v| @retry = v.to_i }
34
+ end
34
35
 
35
- def initialize
36
- super
37
- @force = false
38
- @wait = 30
39
- @retry = 5
40
- @connection_threshold = 2
41
- end
36
+ def initialize
37
+ super
38
+ @retry = 0
39
+ end
42
40
 
43
- def execute(config, args)
44
- parse_index_server(config, args)
41
+ def execute(config, args)
42
+ parse_index_server(config, args)
43
+ nodes = parse_host_port_pairs(args)
44
+ unless nodes
45
+ return S_NG
46
+ end
45
47
 
46
- hosts = args.map {|x| x.split(':')}
47
- hosts.each do |x|
48
- if x.size != 2
49
- error "invalid argument '#{x.join(':')}'. it must be hostname:port."
50
- return S_NG
51
- end
52
- end
48
+ Flare::Tools::IndexServer.open(config[:index_server_hostname], config[:index_server_port], @timeout) do |s|
49
+ cluster = fetch_cluster(s)
53
50
 
54
- Flare::Tools::IndexServer.open(config[:index_server_hostname], config[:index_server_port], @timeout) do |s|
55
- cluster = fetch_cluster(s)
51
+ nodes.each do |node|
52
+ node_stat = cluster.node_stat(node.nodekey)
56
53
 
57
- hosts.each do |hostname,port|
58
- nodekey = nodekey_of hostname, port
59
- unless cluster.has_nodekey? nodekey
60
- error "unknown node name: #{nodekey}"
61
- return S_NG
62
- end
63
- end
54
+ unless node_stat
55
+ error "node not found in cluster. (node=#{node})"
56
+ next
57
+ end
64
58
 
65
- hosts.each do |hostname,port|
66
- exec = false
67
- Flare::Tools::Node.open(hostname, port, @timeout) do |n|
68
- nwait = @wait
69
- node = n.stats
70
- cluster = Flare::Tools::Cluster.new(s.host, s.port, s.stats_nodes)
71
- while nwait > 0
72
- conn = node['curr_connections'].to_i
73
- cluster = fetch_cluster(s)
74
- role = cluster.node_stat("#{hostname}:#{port}")['role']
75
- info "waiting until #{hostname}:#{port} (role=#{role}, connections=#{conn}) is inactive..."
76
- if conn <= @connection_threshold && role == 'proxy'
77
- exec = true
78
- break
79
- end
80
- interruptible {sleep 1}
81
- nwait -= 1
82
- node = n.stats
83
- end
84
- unless @force
85
- node_stat = cluster.node_stat("#{hostname}:#{port}")
86
- role = node_stat['role']
87
- state = node_stat['state']
88
- STDERR.print "please shutdown the daemon and continue (node=#{hostname}:#{port}, role=#{role}, state=#{state}) (y/n): "
89
- interruptible {
90
- exec = false if gets.chomp.upcase != "Y"
91
- }
92
- end
93
- end
59
+ # check status downed & proxy
60
+ unless node_can_remove_safely?(node_stat)
61
+ error "node should role=proxy and state=down. (node=#{node} role=#{node_stat.role} state=#{node_stat.state})"
62
+ return S_NG
63
+ end
94
64
 
95
- if exec
96
- suc = false
97
- nretry = @retry
98
- while nretry > 0
99
- resp = false
100
- info "removing #{hostname}:#{port}."
101
- resp = s.node_remove(hostname, port) unless @dry_run
102
- if resp
103
- suc = true
104
- break
105
- end
106
- nretry -= 1
107
- end
108
- info "done." if suc
109
- info "failed." unless suc
110
- else
111
- info "skipped."
112
- end
113
- end
114
- puts string_of_nodelist(s.stats_nodes)
115
- end
65
+ # ask really remove or not
66
+ unless @force || ask_node_remove(node, node_stat)
67
+ return S_NG
68
+ end
116
69
 
117
- S_OK
70
+ succeeded = node_remove(s, node, @retry, @dry_run)
71
+ unless succeeded
72
+ error "node remove failed. (node=#{node})"
73
+ return S_NG
118
74
  end
119
75
  end
76
+
77
+ # puts node list after nodes removed
78
+ puts ""
79
+ puts string_of_nodelist(s.stats_nodes)
80
+
81
+ return S_OK
120
82
  end
121
83
  end
122
84
  end
@@ -204,7 +204,7 @@ module Flare
204
204
  :time => time,
205
205
  }
206
206
  rescue Errno::ECONNREFUSED => e
207
- rescue => e
207
+ rescue Timeout::Error, StandardError => e
208
208
  begin
209
209
  s.close unless s.nil?
210
210
  rescue => close_error
@@ -62,6 +62,12 @@ module Flare
62
62
  threads
63
63
  end
64
64
 
65
+ defcmd :stats_threads_queue, 'stats threads queue\r\n' do |resp|
66
+ m = /STAT total_thread_queue (\d+)/.match(resp)
67
+ return false unless m
68
+ m[1].to_i
69
+ end
70
+
65
71
  defcmd :ping, 'ping\r\n' do |resp|
66
72
  true if resp
67
73
  end
@@ -239,8 +239,7 @@ class CliTest < Test::Unit::TestCase
239
239
  master = targets.shift
240
240
  args = targets.map{|n| "#{n.hostname}:#{n.port}"}
241
241
  assert_equal(S_OK, down(*args))
242
- args = targets.map{|n| "#{n.hostname}:#{n.port}"} << "--connection-threshold=4"
243
- # sleep 3
242
+ targets.map{|n| @flare_cluster.shutdown_node(n) }
244
243
  assert_equal(S_OK, remove(*args))
245
244
  assert_equal(false, @flare_cluster.exist?(args[0]))
246
245
  assert_equal(false, @flare_cluster.exist?(args[1]))
@@ -251,8 +250,8 @@ class CliTest < Test::Unit::TestCase
251
250
  @flare_cluster.prepare_data(@node_servers[0], "key", 1000)
252
251
  targets = @node_servers.dup
253
252
  master = targets.shift
254
- args = targets.map{|n| "#{n.hostname}:#{n.port}"} << "--connection-threshold=4" << "--wait=3"
255
- assert_equal(S_OK, remove(*args))
253
+ args = targets.map{|n| "#{n.hostname}:#{n.port}"}
254
+ assert_equal(S_NG, remove(*args))
256
255
  assert_equal(true, @flare_cluster.exist?(args[0]))
257
256
  assert_equal(true, @flare_cluster.exist?(args[1]))
258
257
  end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flare-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
5
- prerelease:
4
+ version: 0.7.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - kikehara
@@ -10,70 +9,62 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2014-11-07 00:00:00.000000000 Z
12
+ date: 2014-12-12 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: log4r
17
16
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
17
  requirements:
20
- - - ! '>='
18
+ - - '>='
21
19
  - !ruby/object:Gem::Version
22
20
  version: 1.1.10
23
21
  type: :runtime
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
24
  requirements:
28
- - - ! '>='
25
+ - - '>='
29
26
  - !ruby/object:Gem::Version
30
27
  version: 1.1.10
31
28
  - !ruby/object:Gem::Dependency
32
29
  name: tokyocabinet
33
30
  requirement: !ruby/object:Gem::Requirement
34
- none: false
35
31
  requirements:
36
- - - ! '>='
32
+ - - '>='
37
33
  - !ruby/object:Gem::Version
38
34
  version: '1.29'
39
35
  type: :runtime
40
36
  prerelease: false
41
37
  version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
38
  requirements:
44
- - - ! '>='
39
+ - - '>='
45
40
  - !ruby/object:Gem::Version
46
41
  version: '1.29'
47
42
  - !ruby/object:Gem::Dependency
48
43
  name: bundler
49
44
  requirement: !ruby/object:Gem::Requirement
50
- none: false
51
45
  requirements:
52
- - - ! '>='
46
+ - - '>='
53
47
  - !ruby/object:Gem::Version
54
48
  version: '1.6'
55
49
  type: :development
56
50
  prerelease: false
57
51
  version_requirements: !ruby/object:Gem::Requirement
58
- none: false
59
52
  requirements:
60
- - - ! '>='
53
+ - - '>='
61
54
  - !ruby/object:Gem::Version
62
55
  version: '1.6'
63
56
  - !ruby/object:Gem::Dependency
64
57
  name: rake
65
58
  requirement: !ruby/object:Gem::Requirement
66
- none: false
67
59
  requirements:
68
- - - ! '>='
60
+ - - '>='
69
61
  - !ruby/object:Gem::Version
70
62
  version: '0'
71
63
  type: :development
72
64
  prerelease: false
73
65
  version_requirements: !ruby/object:Gem::Requirement
74
- none: false
75
66
  requirements:
76
- - - ! '>='
67
+ - - '>='
77
68
  - !ruby/object:Gem::Version
78
69
  version: '0'
79
70
  description: Flare-tools is a collection of tools for Flare distributed key-value
@@ -114,8 +105,11 @@ files:
114
105
  - bin/flare-stats
115
106
  - bin/flare-zkadmin
116
107
  - flare-tools.gemspec
108
+ - lib/flare/cli/ask_node_remove.rb
109
+ - lib/flare/cli/parse_host_port_pairs.rb
117
110
  - lib/flare/entity/server.rb
118
111
  - lib/flare/net/connection.rb
112
+ - lib/flare/operation/node_remove.rb
119
113
  - lib/flare/test/cluster.rb
120
114
  - lib/flare/test/daemon.rb
121
115
  - lib/flare/test/node.rb
@@ -210,30 +204,26 @@ files:
210
204
  homepage: http://github.com/gree/flare-tools
211
205
  licenses:
212
206
  - MIT
207
+ metadata: {}
213
208
  post_install_message:
214
209
  rdoc_options: []
215
210
  require_paths:
216
211
  - lib
217
212
  required_ruby_version: !ruby/object:Gem::Requirement
218
- none: false
219
213
  requirements:
220
- - - ! '>='
214
+ - - '>='
221
215
  - !ruby/object:Gem::Version
222
216
  version: '0'
223
- segments:
224
- - 0
225
- hash: 4173589925550821460
226
217
  required_rubygems_version: !ruby/object:Gem::Requirement
227
- none: false
228
218
  requirements:
229
- - - ! '>='
219
+ - - '>='
230
220
  - !ruby/object:Gem::Version
231
221
  version: '0'
232
222
  requirements: []
233
223
  rubyforge_project:
234
- rubygems_version: 1.8.23
224
+ rubygems_version: 2.4.4
235
225
  signing_key:
236
- specification_version: 3
226
+ specification_version: 4
237
227
  summary: Management Tools for Flare
238
228
  test_files:
239
229
  - test/experimental/cache_test.rb