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 +4 -4
- data/VERSION +1 -1
- data/flydata.gemspec +0 -0
- data/lib/flydata.rb +1 -0
- data/lib/flydata/command/sync.rb +35 -13
- data/lib/flydata/helper/action/check_remote_actions.rb +1 -1
- data/lib/flydata/helper/action/update_helper_config.rb +24 -0
- data/lib/flydata/helper/action_ownership.rb +2 -1
- data/lib/flydata/helper/action_ownership_channel.rb +5 -1
- data/lib/flydata/helper/base_action.rb +0 -4
- data/lib/flydata/helper/config_parser.rb +3 -4
- data/lib/flydata/helper/worker.rb +1 -1
- data/lib/flydata/sync_file_manager.rb +12 -7
- data/spec/flydata/helper/action/check_remote_actions_spec.rb +1 -1
- data/spec/flydata/helper/action/restart_agent_spec.rb +1 -1
- data/spec/flydata/helper/action/send_logs_spec.rb +1 -1
- data/spec/flydata/helper/action/stop_agent_spec.rb +1 -1
- data/spec/flydata/helper/action_ownership_channel_spec.rb +3 -2
- data/spec/flydata/helper/action_ownership_spec.rb +2 -1
- data/spec/flydata/helper/config_parser_spec.rb +57 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6afa928a6d8e0ee05f33e9a14d81be9659164e8f
|
4
|
+
data.tar.gz: d6323ad8aa4f7d04cee5263b92e19b3208c8c651
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c273cafd862d6eab962afe5594b7b7b3f72c5536a39b6e6825c98418ee3589e61005a42b4aa77503f3fcbd3d0011ddf550072550f60ba91c6f34c5e9d18bc52d
|
7
|
+
data.tar.gz: 951b50b74c206488fba05241722c09f7bb5f531b8e2097e2cf810bd6cdd863fb1f83471289287f347d1679e4d8ab4f96d27870f535031ea2e4375c3014b7d9ed
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
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
|
data/lib/flydata/command/sync.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
133
|
-
|
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
|
-
|
168
|
-
sync_fm.delete_table_control_files(
|
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
|
-
|
172
|
-
|
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
|
@@ -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
|
-
|
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)
|
@@ -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(
|
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
|
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
|
-
|
337
|
-
|
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)
|
@@ -8,7 +8,7 @@ module Flydata
|
|
8
8
|
include_context 'helper context'
|
9
9
|
|
10
10
|
describe "#execute" do
|
11
|
-
subject { described_class.new(
|
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
|
@@ -8,7 +8,7 @@ module Flydata
|
|
8
8
|
include_context 'helper context'
|
9
9
|
|
10
10
|
describe "#execute" do
|
11
|
-
subject { described_class.new(
|
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
|
28
|
-
expect
|
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(
|
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.
|
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-
|
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.
|
747
|
+
rubygems_version: 2.4.3
|
747
748
|
signing_key:
|
748
749
|
specification_version: 4
|
749
750
|
summary: FlyData Agent
|