flydata 0.8.0 → 0.8.1

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: 7ec2c4c57c3aa4ddcb5f419474f7558300f0f242
4
- data.tar.gz: 6f7148b0c6fc8a114938d1a698a9917fe1ccbe95
3
+ metadata.gz: 68c50586cde303759f5ac328ff7562286e7480e3
4
+ data.tar.gz: 83c940bbdccc612ee4fb965d98d28e62b53c8e44
5
5
  SHA512:
6
- metadata.gz: b89d17e0dd83ccadfa794a3819ae4074336b9b45af56523fcf54349feb115971460e28648f11d3e04e942e6e032e8a4b3fddde891b370c868221d5a8a533adba
7
- data.tar.gz: 60e612f837ca719b0da1b60efbde9057576277c15b325fa52e7a0bcc647c9008da91d43bb292ecc59a1eac1eeb426dcef8abce70bba2364cbfe25c28634dc42a
6
+ metadata.gz: 1031061296b5f598ce63109738fc5b75d83bfa1a754ae5ea5afa71ad1680159205ca28e54d441797204edd2a3865901e5087ac2c4e8207b71f2ddc601dba76fa
7
+ data.tar.gz: c40898079b909de3f880f9afd0ffbd8622fc5058b10ce5780e8440cca9d5d5c047160583e3a2c330e1864a4c7000163b079520c6e07bf5569a969200ed443343
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.0
1
+ 0.8.1
data/flydata.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "flydata"
8
- s.version = "0.8.0"
8
+ s.version = "0.8.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Koichi Fujikawa", "Masashi Miyazaki", "Matthew Luu", "Mak Inada", "Sriram NS"]
12
- s.date = "2017-02-03"
12
+ s.date = "2017-02-08"
13
13
  s.description = "FlyData Agent"
14
14
  s.email = "sysadmin@flydata.com"
15
15
  s.executables = ["fdredshift", "flydata", "serverinfo", "split_sync_ddl.rb"]
@@ -208,6 +208,7 @@ Gem::Specification.new do |s|
208
208
  "lib/flydata/helper/action/check_remote_actions.rb",
209
209
  "lib/flydata/helper/action/clear.rb",
210
210
  "lib/flydata/helper/action/repair.rb",
211
+ "lib/flydata/helper/action/reset.rb",
211
212
  "lib/flydata/helper/action/restart_agent.rb",
212
213
  "lib/flydata/helper/action/resync.rb",
213
214
  "lib/flydata/helper/action/send_logs.rb",
@@ -367,6 +368,7 @@ Gem::Specification.new do |s|
367
368
  "spec/flydata/helper/action/check_remote_actions_spec.rb",
368
369
  "spec/flydata/helper/action/clear_spec.rb",
369
370
  "spec/flydata/helper/action/repair_spec.rb",
371
+ "spec/flydata/helper/action/reset_spec.rb",
370
372
  "spec/flydata/helper/action/restart_agent_spec.rb",
371
373
  "spec/flydata/helper/action/resync_spec.rb",
372
374
  "spec/flydata/helper/action/send_logs_spec.rb",
data/lib/flydata.rb CHANGED
@@ -35,6 +35,7 @@ module Flydata
35
35
  FLYDATA_HELPER_CONF = File.join(FLYDATA_HELPER_HOME, "helper.conf")
36
36
  FLYDATA_CMD_PATH = ENV['FLYDATA_CMD_PATH'] || "flydata"
37
37
  FLYDATA_CLIENT_BUFFER_DIR = File.join(FLYDATA_HOME, 'buffer')
38
+ FLYDATA_DEBUG_FILE = File.join(FLYDATA_HOME, '.debug')
38
39
 
39
40
  VERSION_PATH = File.join(FLYDATA_GEM_HOME, 'VERSION')
40
41
  include Flydata::Heroku
@@ -128,6 +128,7 @@ EOS
128
128
  on 'i', 'init', 'Resets unfinished initial sync'
129
129
  on 'force-run', 'Run forcefully, ignoring exclusive run info'
130
130
  on 'f', 'force', "Resets tables including append only tables. Use this option only when you want to stop sync for the append only table permanently."
131
+ on 'include-unregistered', "Resets tables including unregistered tables. Use this option only when resetting removed tables."
131
132
  end
132
133
  end
133
134
 
@@ -141,7 +142,7 @@ EOS
141
142
  tables = []
142
143
  reset_init = false
143
144
  end
144
- sync_resumed, auto_create = set_current_tables(tables, resume: !opts[:all])
145
+ sync_resumed, auto_create = set_current_tables(tables, resume: !opts[:all], include_unregistered: opts.include_unregistered?)
145
146
  target_tables = opts[:all] ? @full_tables : @input_tables
146
147
  target_append_only_tables = target_tables & @append_only_tables
147
148
  target_full_sync_tables = target_tables - @append_only_tables
@@ -1552,7 +1553,7 @@ Thank you for using FlyData!
1552
1553
  (@unsynced_tables == @full_tables)
1553
1554
  sync_fm.close
1554
1555
 
1555
- verify_input_tables(@input_tables, @full_tables)
1556
+ verify_input_tables(@input_tables, @full_tables, options)
1556
1557
 
1557
1558
  [sync_resumed, auto_create]
1558
1559
  end
@@ -1607,13 +1608,17 @@ Thank you for using FlyData!
1607
1608
  SyncFileManager.new(de, source)
1608
1609
  end
1609
1610
 
1610
- def verify_input_tables(input_tables, all_tables)
1611
+ def verify_input_tables(input_tables, all_tables, options = {})
1611
1612
  return unless input_tables
1612
- inval_table = []
1613
- input_tables.each do |tab|
1614
- inval_table << tab unless all_tables.include?(tab)
1613
+ inval_tables = input_tables - all_tables
1614
+ unless inval_tables.empty?
1615
+ msg = "These tables are not registered tables: #{inval_tables.join(", ")}"
1616
+ if options[:include_unregistered]
1617
+ log_warn_stderr(msg)
1618
+ else
1619
+ raise msg
1620
+ end
1615
1621
  end
1616
- raise "These tables are not registered tables: #{inval_table.join(", ")}" unless inval_table.empty?
1617
1622
  end
1618
1623
 
1619
1624
  def check_master_position_files
@@ -9,15 +9,28 @@ module Flydata
9
9
  def execute(opts = {})
10
10
  sub_command = command(opts)
11
11
  cmd = FLYDATA_CMD % { sub_command: sub_command }
12
- log_debug("Executing `#{cmd}`")
12
+ log_info("Executing `#{cmd}`")
13
13
  o, e, s = Util::Shell.run_cmd(cmd)
14
- log_error(e) if not e.to_s.empty?
15
- log_error("Could not execute #{cmd}. Response status : #{s}") unless (s.to_i == 0)
14
+ log_warn(e) if not e.to_s.empty?
15
+ log_error("[error] Could not execute #{cmd}. Response status: #{s}") unless (s.to_i == 0)
16
16
  end
17
17
 
18
18
  # Override this. Needs to be implemented by the subclass
19
19
  #def command(opts = {})
20
20
  #end
21
+
22
+ def get_tables(opts)
23
+ tables = config_hash(opts)[:tables]
24
+ tables_str = case tables
25
+ when Array
26
+ tables.join(' ')
27
+ when String # --all option
28
+ tables
29
+ else
30
+ raise "Wrong tables parameter - tables:\"#{tables}\""
31
+ end
32
+ tables_str
33
+ end
21
34
  end
22
35
  end
23
36
  end
@@ -0,0 +1,14 @@
1
+ require 'flydata/helper/action/agent_action'
2
+
3
+ module Flydata
4
+ module Helper
5
+ module Action
6
+ class Reset < AgentAction
7
+ def command(opts = {})
8
+ arg = get_tables(opts)
9
+ "sync:reset -y --force --include-unregistered %s" % [arg]
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -5,15 +5,7 @@ module Flydata
5
5
  module Action
6
6
  class Resync < AgentAction
7
7
  def command(opts = {})
8
- tables = config_hash(opts)[:tables]
9
- arg = case tables
10
- when Array
11
- tables.join(' ')
12
- when String # --all option
13
- tables
14
- else
15
- raise "Wrong tables parameter - tables:\"#{tables}\""
16
- end
8
+ arg = get_tables(opts)
17
9
  "sync:resync -y --force %s" % [arg]
18
10
  end
19
11
  end
@@ -16,7 +16,6 @@ module Flydata
16
16
  end
17
17
 
18
18
  def execute(opts = {})
19
- log_debug("Sending logs")
20
19
  num_of_lines = DEFAULT_NUM_OF_LINES
21
20
  action_id = opts[:id]
22
21
  begin
@@ -24,6 +23,7 @@ module Flydata
24
23
  rescue
25
24
  # Use default number of lines if config is nil, mal-formed etc
26
25
  end
26
+ log_info("Sending logs - num_of_lines:#{num_of_lines}")
27
27
  tailed_lines = tail(FLYDATA_LOG, num_of_lines)
28
28
  @api_client.agent.send_logs(action_id, tailed_lines)
29
29
  end
@@ -52,6 +52,7 @@ module Flydata
52
52
  self.new(:resync, true, Action::Resync),
53
53
  self.new(:clear, true, Action::Clear),
54
54
  self.new(:stop_helper, true, Action::StopHelper),
55
+ self.new(:reset, true, Action::Reset),
55
56
  ].inject({}) do |h, action|
56
57
  h[action.action_name] = action
57
58
  h
@@ -22,7 +22,7 @@ module Flydata
22
22
  action_ownership = @action_ownership_map[action_name]
23
23
  if action_ownership.nil?
24
24
  # unknown action. probably a new action
25
- log_warn "unsupported action `#{action_name}'. Skip."
25
+ log_error "[error] unsupported action `#{action_name}'. Skip."
26
26
  return false
27
27
  end
28
28
 
@@ -50,21 +50,27 @@ module Flydata
50
50
  self.synchronize do
51
51
  return nil if @queue.empty?
52
52
 
53
- # Wait until action will be processed
54
- action = @queue.values.first
55
- action_ownership = action[:action_ownership]
56
- return nil if action_ownership.processing?
57
-
58
53
  # Check resource change flag
59
- if action_ownership.resource_change &&
60
- @action_ownership_map.any? { |name, act_own|
54
+ rsc_act_running = @action_ownership_map.any? { |name, act_own|
61
55
  (act_own.resource_change && act_own.processing?) }
62
- return nil
56
+
57
+ target_key, target_action = @queue.find do |key, action|
58
+ action_ownership = action[:action_ownership]
59
+
60
+ # Wait until a same action will be processed
61
+ next if action_ownership.processing?
62
+
63
+ # Skip if another resource change action is running
64
+ next if action_ownership.resource_change && rsc_act_running
65
+
66
+ true
63
67
  end
64
68
 
65
- @queue.shift # delete last acion from queue
66
- action_ownership.owner = new_owner
67
- action
69
+ return nil if target_key.nil? || target_action.nil?
70
+ @queue.delete(target_key)
71
+
72
+ target_action[:action_ownership].owner = new_owner
73
+ target_action
68
74
  end
69
75
  end
70
76
 
@@ -86,15 +92,24 @@ module Flydata
86
92
  end
87
93
 
88
94
  def dump
89
- $log.info "\n" + <<EOT
90
- ========
91
- action_ownership_channel dump
95
+ queue_info = @queue.collect{|k,v|
96
+ "- #{k} #{v[:action_info]}"
97
+ }.join("\n")
92
98
 
93
- queue:
94
- #{@queue}
99
+ map_info = @action_ownership_map.collect{|k,v|
100
+ "- #{v.action_name} owner:\"#{v.owner}\" " +
101
+ "retry:#{v.retry_count} " +
102
+ "last:\"#{v.last_processed_time > 0 ? Time.at(v.last_processed_time).utc : '-'}\""
103
+ }.join("\n")
95
104
 
96
- action_ownership_map:
97
- #{@action_ownership_map}
105
+ <<EOT
106
+
107
+ ========
108
+ action_ownership_channel dump
109
+ # queue:
110
+ #{queue_info}
111
+ # action_ownership_map:
112
+ #{map_info}
98
113
  ========
99
114
  EOT
100
115
  end
@@ -7,6 +7,7 @@ module Flydata
7
7
 
8
8
  RUN_INTERVAL = 1.0 #second
9
9
  RUN_GC_INTERVAL = 60.0 * 5 #seconds
10
+ DEBUG_DUMP_INTERVAL = 60.0 #seconds
10
11
 
11
12
  def initialize(helper_conf, server)
12
13
  @stop_flag = ServerEngine::BlockingFlag.new
@@ -98,10 +99,22 @@ module Flydata
98
99
  end
99
100
  end
100
101
 
102
+ dump_queue_if_needed
101
103
  run_gc_if_needed
102
104
  wait_until_next_turn(start_time)
103
105
  end
104
106
 
107
+ def dump_queue_if_needed
108
+ now = Time.now
109
+ @last_dump_time ||= now
110
+ if (@last_dump_time + DEBUG_DUMP_INTERVAL) < now
111
+ if File.exists?(FLYDATA_DEBUG_FILE)
112
+ log_info(@server.action_ownership_channel.dump) rescue nil
113
+ end
114
+ @last_dump_time = now
115
+ end
116
+ end
117
+
105
118
  def run_gc_if_needed
106
119
  now = Time.now
107
120
  @last_gc_time ||= now
@@ -58,6 +58,7 @@ module Flydata
58
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
+ log_info("New action was requested - action:#{new_action_name} action_info:#{new_action_info}")
61
62
  #server.action_ownership_channel.dump
62
63
  end
63
64
  action_ownership.reset_retry_count
@@ -454,7 +454,7 @@ module Flydata
454
454
  let(:command_options) { ["-y", "--all"] }
455
455
  let(:sync_info) { nil }
456
456
  it do
457
- expect(subject_object).to receive(:set_current_tables).with([], resume: false).and_call_original
457
+ expect(subject_object).to receive(:set_current_tables).with([], resume: false, include_unregistered: false).and_call_original
458
458
  expect(subject_object).to receive(:wait_for_server_buffer).with( {:timeout=>timeout_value, :tables=>arg_tables} )
459
459
  expect(subject_object).to receive(:cleanup_sync_server).with( default_data_entry, arg_tables )
460
460
  subject
@@ -482,7 +482,7 @@ module Flydata
482
482
  let(:sync_info_tables) { ["table1", "table2", "table4"] }
483
483
  let(:target_tables_for_api) { [] }
484
484
  it do
485
- expect(subject_object).to receive(:set_current_tables).with([], resume: true).and_call_original
485
+ expect(subject_object).to receive(:set_current_tables).with([], resume: true, include_unregistered: false).and_call_original
486
486
  expect(subject_object).to receive(:wait_for_server_buffer).with(
487
487
  {:timeout=>timeout_value, :tables=>target_tables_for_api} )
488
488
  expect(subject_object).to receive(:cleanup_sync_server).with(
@@ -496,7 +496,7 @@ module Flydata
496
496
  let(:sync_info_tables) { ["table2"] }
497
497
  let(:target_tables_for_api) { sync_info_tables }
498
498
  it do
499
- expect(subject_object).to receive(:set_current_tables).with([], resume: true).and_call_original
499
+ expect(subject_object).to receive(:set_current_tables).with([], resume: true, include_unregistered: false).and_call_original
500
500
  expect(subject_object).to receive(:wait_for_server_buffer).with(
501
501
  {:timeout=>timeout_value, :tables=>target_tables_for_api} )
502
502
  expect(subject_object).to receive(:cleanup_sync_server).with(
@@ -519,7 +519,7 @@ module Flydata
519
519
  allow_any_instance_of(SyncFileManager).to receive(:get_new_table_list).with(full_tables, "generated_ddl").and_return([])
520
520
  end
521
521
  it do
522
- expect(subject_object).to receive(:set_current_tables).with(arg_tables, resume: true).and_call_original
522
+ expect(subject_object).to receive(:set_current_tables).with(arg_tables, resume: true, include_unregistered: false).and_call_original
523
523
  expect(subject_object).to receive(:wait_for_server_buffer).with(
524
524
  {:timeout=>timeout_value, :tables=>arg_tables} )
525
525
  expect(subject_object).to receive(:cleanup_sync_server).with(
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ require_relative '../helper_shared_context'
3
+ require 'flydata/helper/action/reset'
4
+
5
+ module Flydata
6
+ module Helper
7
+ module Action
8
+ describe Reset do
9
+ include_context 'helper context'
10
+
11
+ describe "#command" do
12
+ subject { described_class.new(config).command(opts) }
13
+
14
+ context 'without opts' do
15
+ let(:opts) { {} }
16
+ it { expect{subject}.to raise_error(/^Wrong tables parameter/) }
17
+ end
18
+
19
+ context 'with tables array' do
20
+ let(:opts) { {config_hash: {tables: %w(table_a table_b)}} }
21
+ it { is_expected.to eq("sync:reset -y --force --include-unregistered table_a table_b") }
22
+ end
23
+
24
+ context 'with tables string' do
25
+ let(:opts) { {config_hash: {tables: "table_a table_b"}} }
26
+ it { is_expected.to eq("sync:reset -y --force --include-unregistered table_a table_b") }
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,5 +1,7 @@
1
1
  require 'spec_helper'
2
2
  require 'flydata/helper/action_ownership_channel'
3
+ require 'flydata/helper/action_ownership'
4
+ require 'flydata/helper/server'
3
5
  require 'timecop'
4
6
 
5
7
  module Flydata
@@ -25,7 +27,7 @@ module Flydata
25
27
  context "when action is not valid" do
26
28
  let(:action_name) { :start_agent }
27
29
  it "should return false and leave a log" do
28
- expect(channel).to receive(:log_warn)
30
+ expect(channel).to receive(:log_error)
29
31
  is_expected.to be(false)
30
32
  end
31
33
  end
@@ -40,6 +42,22 @@ module Flydata
40
42
  expect(channel.instance_variable_get(:@queue).size).to be(1)
41
43
  end
42
44
  end
45
+
46
+ context "when the queue already contains the action but different id" do
47
+ let(:prev_action_info) do
48
+ { id: 100, config: %Q|{"num_of_lines" : "100"}| }
49
+ end
50
+
51
+ before do
52
+ channel.request_action(action_name, prev_action_info)
53
+ end
54
+ it "should not alter the queue and return false" do
55
+ expect(channel.instance_variable_get(:@queue).size).to be(1)
56
+ is_expected.to be(true)
57
+ expect(channel.instance_variable_get(:@queue).size).to be(2)
58
+ end
59
+ end
60
+
43
61
  end
44
62
 
45
63
  describe '#take_action_ownership' do
@@ -75,6 +93,22 @@ module Flydata
75
93
  end
76
94
  end
77
95
 
96
+ context "when the action does not need to be taken exclusively \
97
+ but enqueued behind an exclusive actions in progress" do
98
+ before do
99
+ channel.request_action(:stop_agent)
100
+ channel.take_action_ownership("another-owner")
101
+ channel.request_action(:restart_agent)
102
+ channel.request_action(:send_logs, action_info)
103
+ end
104
+ it "should return a processable non-exclusive action" do
105
+ action = subject
106
+ expect(action[:action_ownership].action_name).to be(:send_logs)
107
+ expect(action[:action_ownership].owner).to be(new_owner)
108
+ expect(action[:action_info]).to eq(action_info)
109
+ end
110
+ end
111
+
78
112
  context "when the action can be taken" do
79
113
  before do
80
114
  channel.request_action(:send_logs, action_info)
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.8.0
4
+ version: 0.8.1
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: 2017-02-03 00:00:00.000000000 Z
15
+ date: 2017-02-08 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rest-client
@@ -683,6 +683,7 @@ files:
683
683
  - lib/flydata/helper/action/check_remote_actions.rb
684
684
  - lib/flydata/helper/action/clear.rb
685
685
  - lib/flydata/helper/action/repair.rb
686
+ - lib/flydata/helper/action/reset.rb
686
687
  - lib/flydata/helper/action/restart_agent.rb
687
688
  - lib/flydata/helper/action/resync.rb
688
689
  - lib/flydata/helper/action/send_logs.rb
@@ -842,6 +843,7 @@ files:
842
843
  - spec/flydata/helper/action/check_remote_actions_spec.rb
843
844
  - spec/flydata/helper/action/clear_spec.rb
844
845
  - spec/flydata/helper/action/repair_spec.rb
846
+ - spec/flydata/helper/action/reset_spec.rb
845
847
  - spec/flydata/helper/action/restart_agent_spec.rb
846
848
  - spec/flydata/helper/action/resync_spec.rb
847
849
  - spec/flydata/helper/action/send_logs_spec.rb