flare-tools 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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