flydata 0.5.21 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 516813af4ea0557232dfd85e16c84b3666fa6576
4
- data.tar.gz: 8fa4a979e70fde765532a000952f1deab76a0973
3
+ metadata.gz: 6afa928a6d8e0ee05f33e9a14d81be9659164e8f
4
+ data.tar.gz: d6323ad8aa4f7d04cee5263b92e19b3208c8c651
5
5
  SHA512:
6
- metadata.gz: b3eac9c57d1adced1b2657d12797fd076744f8659f032017c6826f92b6f6b1f7b7a6a40bdc476a9fd369402da50eeb92bc9c6022a712b9a6fa70c00648c55a1d
7
- data.tar.gz: 25f4a8c298d41f3efdbf9f9560c2d215699af1ebfad086fd8d52ae51a00004a8893bdc288ef0ac7331f7d96030a542e1ec18cf941991907ca8ec8e1daee082b2
6
+ metadata.gz: c273cafd862d6eab962afe5594b7b7b3f72c5536a39b6e6825c98418ee3589e61005a42b4aa77503f3fcbd3d0011ddf550072550f60ba91c6f34c5e9d18bc52d
7
+ data.tar.gz: 951b50b74c206488fba05241722c09f7bb5f531b8e2097e2cf810bd6cdd863fb1f83471289287f347d1679e4d8ab4f96d27870f535031ea2e4375c3014b7d9ed
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.21
1
+ 0.6.0
data/flydata.gemspec CHANGED
Binary file
data/lib/flydata.rb CHANGED
@@ -31,6 +31,7 @@ module Flydata
31
31
  FLYDATA_CONF = File.join(FLYDATA_HOME, 'flydata.conf')
32
32
  FLYDATA_LOCK = File.join(FLYDATA_HOME, 'flydata_lock.pid')
33
33
  FLYDATA_HELPER_HOME = File.join(FLYDATA_HOME, 'helper')
34
+ FLYDATA_HELPER_CONF = File.join(FLYDATA_HELPER_HOME, "helper.conf")
34
35
 
35
36
  VERSION_PATH = File.join(FLYDATA_GEM_HOME, 'VERSION')
36
37
  include Flydata::Heroku
@@ -115,22 +115,42 @@ EOS
115
115
  Slop.new do
116
116
  on 'c', 'client', 'Resets client only.'
117
117
  on 'y', 'yes', 'Skip command prompt assuming yes to all questions. Use this for batch operation.'
118
+ on 'a', 'all', 'Resets Sync for all tables'
119
+ on 'i', 'init', 'Resets unfinished initial sync'
118
120
  end
119
121
  end
120
122
 
121
123
  # Command: flydata sync:reset
122
124
  # - Entry method
123
125
  def reset(*tables)
124
- show_purpose_name
126
+
127
+ if tables.empty? && !opts[:all] && !opts[:init]
128
+ log_info_stdout <<EOS
129
+ ERROR! Argument or option must be specified.
130
+
131
+ To reset all tables: flydata sync:reset --all
132
+ To reset specific tables: flydata sync:reset table1 table2 ...
133
+ To reset unfinished initial sync: flydata sync:reset --init
134
+ EOS
135
+ return
136
+ end
125
137
 
126
138
  # Set instance variables
127
- sync_resumed = set_current_tables(tables, resume: true)
139
+ reset_init = opts[:init]
140
+ if opts[:all]
141
+ tables = []
142
+ reset_init = false
143
+ end
144
+ sync_resumed = set_current_tables(tables, resume: !opts[:all])
145
+
146
+ return if !sync_resumed && reset_init
128
147
 
129
148
  message = ''
130
149
  if sync_resumed && !tables.empty?
131
150
  log_info_stdout <<EOS
132
- Initial sync is in progress. In this case, you can only reset the initial sync. To reset specific table(s), please resume and complete the initial sync by running the 'flydata start' command first.
133
- If you'd like to reset the initial sync in progress, run the 'flydata reset' command with no arguments.
151
+ ERROR! You cannot reset tables because the previous initial sync has not been completed. Reset the unfinished initial sync first with the following command:
152
+
153
+ flyudata sync:reset --init
134
154
  EOS
135
155
  return
136
156
  end
@@ -138,6 +158,7 @@ EOS
138
158
  # Flush client buffer
139
159
  msg_tables = @input_tables.empty? ? '' : " for these tables : #{@input_tables.join(" ")}"
140
160
  msg_sync_type = sync_resumed ? "the current initial sync" : "the current sync"
161
+ show_purpose_name
141
162
  return unless ask_yes_no("This resets #{msg_sync_type}#{msg_tables}. Are you sure?")
142
163
  sender = Flydata::Command::Sender.new
143
164
  sender.flush_client_buffer # TODO We should rather delete buffer files
@@ -164,12 +185,13 @@ EOS
164
185
  sync_fm = create_sync_file_manager(de)
165
186
 
166
187
  # Delete local files
167
- tables_for_deleting = tables.empty? ? sync_fm.tables_from_positions_dir : @input_tables
168
- sync_fm.delete_table_control_files(*tables_for_deleting)
188
+ sync_fm.delete_dump_files
189
+ sync_fm.delete_table_control_files(*@input_tables)
169
190
 
170
191
  new_tables_after_reset = @unsynced_tables + @input_tables
171
- delete_binlog =@input_tables.empty? or @full_tables.empty? or @full_tables.all?{|ft| new_tables_after_reset.include?(ft)}
172
- sync_fm.delete_non_table_control_files(delete_binlog)
192
+ if @input_tables.empty? or @full_tables.empty? or @full_tables.all?{|ft| new_tables_after_reset.include?(ft)}
193
+ sync_fm.delete_master_position_files
194
+ end
173
195
  sync_fm.close
174
196
  log_info_stdout("Reset completed successfully.")
175
197
  end
@@ -568,11 +590,6 @@ EOS
568
590
  Flydata::Command::Conf.new.copy_templates
569
591
  end
570
592
 
571
- # initialize stats
572
- target_tables.each do |table_name|
573
- sync_fm.save_record_count_stat(table_name, 0)
574
- end
575
-
576
593
  generate_mysqldump(de, sync_fm, !opts.dump_stream?, options) do |mysqldump_io, binlog_pos, db_bytesize|
577
594
  parse_mysqldump_and_send(mysqldump_io, dp, de, sync_fm, binlog_pos, db_bytesize)
578
595
  end
@@ -779,6 +796,11 @@ EOM
779
796
  end
780
797
  log_info_stdout("Sending data to FlyData Server...")
781
798
 
799
+ # initialize stats
800
+ target_tables.each do |table_name|
801
+ sync_fm.save_record_count_stat(table_name, 0)
802
+ end
803
+
782
804
  bench_start_time = Time.now
783
805
 
784
806
  output_thread = QueueableThread.new
@@ -17,7 +17,7 @@ module Flydata
17
17
  end
18
18
 
19
19
  def execute(opts = {})
20
- action_position = ActionPosition.new(config)
20
+ action_position = ActionPosition.new(config[:helper])
21
21
 
22
22
  # Get actions from flydata web server
23
23
  last_id = action_position.load
@@ -0,0 +1,24 @@
1
+ require 'flydata/helper/base_action'
2
+
3
+ module Flydata
4
+ module Helper
5
+ module Action
6
+ class UpdateHelperConfig < BaseAction
7
+ def execute(opts = {})
8
+ conf_path = config[:config_path] || FLYDATA_HELPER_CONF
9
+ helper_conf = opts[:config]
10
+ helper_conf = "#{helper_conf}\n" if helper_conf && helper_conf.size > 0 && !helper_conf.end_with?("\n")
11
+ if helper_conf
12
+ log_info("updating Helper config:#{conf_path}")
13
+ File.open(conf_path, "w") {|f| f.write helper_conf }
14
+ else
15
+ log_info("removing Helper config:#{conf_path}")
16
+ File.unlink(conf_path) if File.exists?(conf_path)
17
+ end
18
+ # reload conf
19
+ Process.kill("USR2", Process.ppid)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -46,7 +46,8 @@ module Flydata
46
46
  self.new(:check_abnormal_shutdown, false, Action::CheckAbnormalShutdown),
47
47
  self.new(:send_logs, false, Action::SendLogs),
48
48
  self.new(:stop_agent, true, Action::StopAgent),
49
- self.new(:restart_agent, true, Action::RestartAgent)
49
+ self.new(:restart_agent, true, Action::RestartAgent),
50
+ self.new(:update_helper_config, false, Action::UpdateHelperConfig),
50
51
  ].inject({}) do |h, action|
51
52
  h[action.action_name] = action
52
53
  h
@@ -1,4 +1,5 @@
1
1
  require 'monitor'
2
+ require 'flydata-core/logger'
2
3
 
3
4
  module Flydata
4
5
  module Helper
@@ -7,6 +8,7 @@ module Flydata
7
8
  # - Give a action with ownership to workers
8
9
  class ActionOwnershipChannel
9
10
  include MonitorMixin
11
+ include FlydataCore::Logger
10
12
 
11
13
  def initialize
12
14
  @action_ownership_map = ActionOwnership.action_ownership_map
@@ -19,7 +21,9 @@ module Flydata
19
21
  def request_action(action_name, action_info = {})
20
22
  action_ownership = @action_ownership_map[action_name]
21
23
  if action_ownership.nil?
22
- raise "Received invalid action request:#{action_name}"
24
+ # unknown action. probably a new action
25
+ log_warn "unsupported action `#{action_name}'. Skip."
26
+ return false
23
27
  end
24
28
  self.synchronize do
25
29
  if @queue.has_key?(action_name)
@@ -11,10 +11,6 @@ module Flydata
11
11
 
12
12
  attr_accessor :config
13
13
 
14
- def get_service(service_class)
15
- service_class.new(config)
16
- end
17
-
18
14
  # Override
19
15
  #def execute(opts = {}, &block)
20
16
  #end
@@ -19,7 +19,6 @@ module Flydata
19
19
  # check_interval: 10s
20
20
  # ============================================
21
21
  class Config < Hash
22
- DEFAULT_INTERVAL = 30.0
23
22
  DEFAULT_SCHEDULED_ACTIONS = {
24
23
  check_remote_actions: {
25
24
  check_interval: '30s',
@@ -31,9 +30,6 @@ module Flydata
31
30
  DEFAULT_HELPER = {
32
31
  scheduled_actions: DEFAULT_SCHEDULED_ACTIONS,
33
32
  }
34
- DEFAULT_CONFIG = {
35
- helper: DEFAULT_HELPER
36
- }
37
33
 
38
34
  def self.create(hash)
39
35
  self.new.merge(hash)
@@ -155,6 +151,9 @@ module Flydata
155
151
 
156
152
  class ConfigParser
157
153
  def self.parse_file(config_path = nil)
154
+ if config_path.nil? && File.exists?(FLYDATA_HELPER_CONF)
155
+ config_path = FLYDATA_HELPER_CONF
156
+ end
158
157
  config_path.nil? ? { helper: Config.default } : parse(File.open(config_path).read)
159
158
  end
160
159
 
@@ -55,7 +55,7 @@ module Flydata
55
55
  action_id = action_info && action_info[:id] ? "[#{action_info[:id]}]" : "" #scheduled actions (eg:- check_remote_action) don't have id
56
56
  set_log_context_item(:prefix, "[worker][#{action_ownership.action_name}]#{action_id}")
57
57
  begin
58
- action_ownership.action_class.new(helper_conf).execute(action_info) do |new_action_name, new_action_info = nil|
58
+ action_ownership.action_class.new(config).execute(action_info) do |new_action_name, new_action_info = nil|
59
59
  # request action if the action requires
60
60
  server.action_ownership_channel.request_action(new_action_name, new_action_info)
61
61
  end
@@ -300,7 +300,6 @@ module Flydata
300
300
  end
301
301
 
302
302
  def delete_table_control_files(*tables)
303
- return if (tables.nil? or tables.empty?)
304
303
  files_to_delete = [
305
304
  table_position_file_paths(*tables),
306
305
  table_binlog_pos_paths(*tables),
@@ -315,7 +314,6 @@ module Flydata
315
314
 
316
315
  def tables_from_positions_dir
317
316
  all_table_control_files = Dir.glob(File.join(table_positions_dir_path, '*.{pos,generated_ddl,init,rev}'))
318
- return if all_table_control_files.nil?
319
317
  tables = Set.new
320
318
  all_table_control_files.each do |control_file|
321
319
  file_name = File.basename(control_file)
@@ -325,7 +323,7 @@ module Flydata
325
323
  tables.to_a
326
324
  end
327
325
 
328
- def delete_non_table_control_files(delete_binlog= false)
326
+ def delete_dump_files
329
327
  files_to_delete = [
330
328
  dump_file_path,
331
329
  dump_pos_path,
@@ -333,16 +331,23 @@ module Flydata
333
331
  sync_info_file,
334
332
  stats_path
335
333
  ]
336
- if delete_binlog
337
- files_to_delete << binlog_path
338
- files_to_delete << sent_binlog_path
339
- files_to_delete << lock_pid_file
334
+ files_to_delete.flatten.each do |file_to_delete|
335
+ FileUtils.rm(file_to_delete) if File.exists?(file_to_delete)
340
336
  end
337
+ end
338
+
339
+ def delete_master_position_files
340
+ files_to_delete = [
341
+ binlog_path,
342
+ sent_binlog_path,
343
+ lock_pid_file,
344
+ ]
341
345
  files_to_delete.flatten.each do |file_to_delete|
342
346
  FileUtils.rm(file_to_delete) if File.exists?(file_to_delete)
343
347
  end
344
348
  end
345
349
 
350
+
346
351
  def delete_table_binlog_pos(table_name)
347
352
  file = File.join(table_positions_dir_path, table_name + ".binlog.pos")
348
353
  if File.exists?(file)
@@ -19,7 +19,7 @@ module Flydata
19
19
 
20
20
  let(:check_remote_action) do
21
21
  allow(ApiClient).to receive(:instance).and_return(api_client)
22
- described_class.new(helper_conf)
22
+ described_class.new(config)
23
23
  end
24
24
 
25
25
  let(:empty_actions) do
@@ -8,7 +8,7 @@ module Flydata
8
8
  include_context 'helper context'
9
9
 
10
10
  describe "#execute" do
11
- subject { described_class.new(helper_conf).execute }
11
+ subject { described_class.new(config).execute }
12
12
  it "executes the restart action" do
13
13
  expect(Open3).to receive(:capture3).with({}, "flydata restart --skip-helper")
14
14
  subject
@@ -18,7 +18,7 @@ module Flydata
18
18
 
19
19
  let(:send_log_action) do
20
20
  allow(ApiClient).to receive(:instance).and_return(api_client)
21
- described_class.new(helper_conf)
21
+ described_class.new(config)
22
22
  end
23
23
 
24
24
  let(:action_info) do
@@ -8,7 +8,7 @@ module Flydata
8
8
  include_context 'helper context'
9
9
 
10
10
  describe "#execute" do
11
- subject { described_class.new(helper_conf).execute }
11
+ subject { described_class.new(config).execute }
12
12
  it "executes the stop action" do
13
13
  expect(Open3).to receive(:capture3).with({}, "flydata stop")
14
14
  subject
@@ -24,8 +24,9 @@ module Flydata
24
24
 
25
25
  context "when action is not valid" do
26
26
  let(:action_name) { :start_agent }
27
- it "should raise an error" do
28
- expect {subject}.to raise_error('Received invalid action request:start_agent')
27
+ it "should return false and leave a log" do
28
+ expect(channel).to receive(:log_warn)
29
+ is_expected.to be(false)
29
30
  end
30
31
  end
31
32
 
@@ -36,12 +36,13 @@ module Flydata
36
36
  describe '.action_ownership_map' do
37
37
  subject { described_class.action_ownership_map }
38
38
  it do
39
- expect(subject.size).to eq(5)
39
+ expect(subject.size).to eq(6)
40
40
  expect(subject.include?(:check_remote_actions)).to be(true)
41
41
  expect(subject.include?(:check_abnormal_shutdown)).to be(true)
42
42
  expect(subject.include?(:send_logs)).to be(true)
43
43
  expect(subject.include?(:stop_agent)).to be(true)
44
44
  expect(subject.include?(:restart_agent)).to be(true)
45
+ expect(subject.include?(:update_helper_config)).to be(true)
45
46
  end
46
47
  end
47
48
  end
@@ -105,6 +105,63 @@ EOT
105
105
  end
106
106
  end
107
107
  end
108
+ describe ".parse_file" do
109
+ subject { described_class.parse_file(path) }
110
+
111
+ let(:expected_result) { double("expected_parse_result") }
112
+
113
+ shared_examples "opening a conf file and parse the contents" do
114
+ let(:conf_contents) { double("conf_contents") }
115
+ let(:conf_file) { double("conf_file") }
116
+
117
+ before do
118
+ expect(File).to receive(:open).with(expected_path).
119
+ and_return(conf_file)
120
+ expect(conf_file).to receive(:read).and_return(conf_contents)
121
+ expect(described_class).to receive(:parse).with(conf_contents).
122
+ and_return(expected_result)
123
+ end
124
+ end
125
+
126
+ context "when path is given" do
127
+ let(:path) { "/path/to/my/helper.conf" }
128
+ let(:expected_path) { path }
129
+
130
+ before do
131
+ expect(File).to_not receive(:exists?)
132
+ end
133
+ include_examples "opening a conf file and parse the contents"
134
+ it { is_expected.to eq(expected_result) }
135
+ end
136
+ context "when no path is given" do
137
+ let(:path) { nil }
138
+ let(:expected_path) { File.join(Flydata::FLYDATA_HELPER_HOME, "helper.conf") }
139
+
140
+ context "and default conf file exists" do
141
+ before do
142
+ expect(File).to receive(:exists?).with(expected_path).
143
+ and_return true
144
+ end
145
+ include_examples "opening a conf file and parse the contents"
146
+ it { is_expected.to eq(expected_result) }
147
+ end
148
+ context "and default conf file does not exist" do
149
+ before do
150
+ expect(File).to receive(:exists?).with(expected_path).
151
+ and_return false
152
+ end
153
+ let(:expected_result) { {
154
+ helper: {
155
+ scheduled_actions: {
156
+ check_remote_actions: { check_interval: "30s"},
157
+ check_abnormal_shutdown: {:check_interval=>"60s"}
158
+ }
159
+ }
160
+ } }
161
+ it { is_expected.to eq(expected_result) }
162
+ end
163
+ end
164
+ end
108
165
  end
109
166
  end
110
167
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flydata
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.21
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Koichi Fujikawa
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2015-11-25 00:00:00.000000000 Z
15
+ date: 2015-12-01 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rest-client
@@ -635,6 +635,7 @@ files:
635
635
  - lib/flydata/helper/action/restart_agent.rb
636
636
  - lib/flydata/helper/action/send_logs.rb
637
637
  - lib/flydata/helper/action/stop_agent.rb
638
+ - lib/flydata/helper/action/update_helper_config.rb
638
639
  - lib/flydata/helper/action_ownership.rb
639
640
  - lib/flydata/helper/action_ownership_channel.rb
640
641
  - lib/flydata/helper/base_action.rb
@@ -743,7 +744,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
743
744
  version: '0'
744
745
  requirements: []
745
746
  rubyforge_project:
746
- rubygems_version: 2.0.14.1
747
+ rubygems_version: 2.4.3
747
748
  signing_key:
748
749
  specification_version: 4
749
750
  summary: FlyData Agent