flydata 0.6.0 → 0.6.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: 6afa928a6d8e0ee05f33e9a14d81be9659164e8f
4
- data.tar.gz: d6323ad8aa4f7d04cee5263b92e19b3208c8c651
3
+ metadata.gz: 4ab029d2a33bb77838fe20cf625de7f473efdb30
4
+ data.tar.gz: 8313b3c85c3f98201194fd33b68b60cab15c9417
5
5
  SHA512:
6
- metadata.gz: c273cafd862d6eab962afe5594b7b7b3f72c5536a39b6e6825c98418ee3589e61005a42b4aa77503f3fcbd3d0011ddf550072550f60ba91c6f34c5e9d18bc52d
7
- data.tar.gz: 951b50b74c206488fba05241722c09f7bb5f531b8e2097e2cf810bd6cdd863fb1f83471289287f347d1679e4d8ab4f96d27870f535031ea2e4375c3014b7d9ed
6
+ metadata.gz: 0b2b0a184db03ca9d157ee044b349cdf7ab1c94e5338d536ad51c3be474c8cc6363809646c48406578363901917ac9bb453f0426e461f143b7685d51c95edbde
7
+ data.tar.gz: b7adf39c00e853819265dfc598b4873aef9e469afadd457dc729fce00f682fe1924321f1bd2a361707db7099a96c040300df9b31d2f4ae2a04840151681ed579
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.0
1
+ 0.6.1
@@ -247,23 +247,24 @@ static VALUE rb_json_generate_kv_pairs(VALUE self, VALUE key_ary, VALUE value_ar
247
247
  rb_raise(rb_eArgError, "length of arrays must match");
248
248
  }
249
249
 
250
- std::stringstream ss;
250
+ std::stringstream* ss = new std::stringstream();
251
251
 
252
- ss << "{";
252
+ *ss << "{";
253
253
 
254
254
  for (long i = 0; i < key_len; i++)
255
255
  {
256
- if (i > 0) { ss << ","; }
256
+ if (i > 0) { *ss << ","; }
257
257
 
258
258
  VALUE key = rb_ary_entry(key_ary, i);
259
259
  VALUE value = rb_ary_entry(value_ary, i);
260
260
 
261
- add_kv_pair(key, value, ss);
261
+ add_kv_pair(key, value, *ss);
262
262
  }
263
- ss << "}";
263
+ *ss << "}";
264
264
 
265
- const std::string& str = ss.str();
265
+ const std::string& str = ss->str();
266
266
  VALUE json = rb_str_new(str.data(), str.size());
267
+ delete ss; ss = 0;
267
268
  int enc = rb_enc_find_index("UTF-8");
268
269
  rb_enc_associate_index(json, enc);
269
270
 
@@ -0,0 +1,10 @@
1
+ module FlydataCore
2
+ module Event
3
+ #Nouns
4
+ INIT_SYNC = "init_sync"
5
+
6
+ #Verbs
7
+ STARTED = "started"
8
+ FINISHED = "finished"
9
+ end
10
+ end
@@ -11,6 +11,7 @@ module FlydataCore
11
11
  end
12
12
 
13
13
  protected
14
+
14
15
  def self.register_handler(opts)
15
16
  @noun = opts[:noun]
16
17
  @verb = opts[:verb] || EVENT_VERB_ANY
@@ -21,6 +22,7 @@ module FlydataCore
21
22
  end
22
23
 
23
24
  private
25
+
24
26
  def self.handlers(noun, verb)
25
27
  handlers = (@@handlers_hash[key(noun, verb)] || []).clone
26
28
 
@@ -6,23 +6,44 @@ module FlydataCore
6
6
  class FlydataEvent
7
7
  attr_accessor :noun
8
8
  attr_accessor :verb
9
- attr_accessor :data
9
+ attr_accessor :data #recommended that it be a hash
10
10
  attr_accessor :id
11
11
  attr_accessor :created
12
12
  attr_accessor :data_entry_id
13
13
  attr_accessor :data_port_id
14
14
 
15
- def initialize (noun, verb, data=nil, de_id=nil,dp_id=nil, id=nil, timestamp=nil)
15
+ # params:
16
+ # data_port_id: nil,
17
+ # data_entry_id: nil,
18
+ # id: nil,
19
+ # data: nil,
20
+ # timestamp: nil
21
+ def initialize (noun, verb, params = {})
22
+ params ||= {}
23
+
16
24
  @noun = noun
17
25
  @verb = verb
18
- @data_entry_id = de_id
19
- @data_port_id = dp_id
20
- @data = data
21
- @id = id.nil? ? SecureRandom.uuid: id
22
- @created = timestamp.nil? ? Time.now : timestamp
26
+ @data_entry_id = params[:data_entry_id] ? params[:data_entry_id].to_i : nil
27
+ @data_port_id = params[:data_port_id] ? params[:data_port_id].to_i : nil
28
+ @data = params[:data]
29
+ @id = params[:id].nil? ? SecureRandom.uuid : params[:id]
30
+ @created = params[:timestamp].nil? ? Time.now : params[:timestamp]
31
+ end
32
+
33
+ def to_h
34
+ {
35
+ noun: @noun,
36
+ verb: @verb,
37
+ data_entry_id: @data_entry_id,
38
+ data_port_id: @data_port_id,
39
+ id: @id,
40
+ created: @created,
41
+ data: @data,
42
+ }
23
43
  end
44
+
24
45
  def to_json
25
- {:noun => @noun, :verb => @verb, :data_entry_id=>@data_entry_id, :data_port_id=> @data_port_id, id => @id, :created => @created, :data => @data}.to_json
46
+ to_h.to_json
26
47
  end
27
48
  end
28
49
  end
@@ -3,7 +3,6 @@ require 'flydata-core/event/flydata_event_handler_registry'
3
3
  module FlydataCore
4
4
  module Event
5
5
  class FlydataEventProcessor
6
-
7
6
  def self.process(event)
8
7
  handlers = FlydataEventHandlerRegistry.handlers(event.noun, event.verb)
9
8
  if handlers.nil? || handlers.empty?
@@ -14,6 +13,5 @@ module FlydataCore
14
13
  end
15
14
  end
16
15
  end
17
-
18
16
  end
19
17
  end
@@ -4,20 +4,24 @@ module FlydataCore
4
4
  module Event
5
5
 
6
6
  class FlydataEventSender
7
-
8
- def send_event(noun, verb, data=nil, data_entry_id=nil, data_port_id=nil, routing_key="default")
9
- event = FlydataEvent.new(noun, verb, data, data_entry_id, data_port_id)
7
+ def send_event(noun, verb, params = {})
8
+ params ||= {}
9
+ routing_key = params[:routing_key] || 'default'
10
+ event = FlydataEvent.new(noun, verb, params)
10
11
  send(event, routing_key)
11
12
  end
12
13
 
13
14
  protected
15
+
14
16
  def send(event, routing_key)
15
17
  raise "send method not implemented"
16
18
  end
17
19
  end
18
20
 
19
21
  class SimpleEventSender <FlydataEventSender
22
+
20
23
  protected
24
+
21
25
  def send(event, routing_key)
22
26
  FlydataEventProcessor.process(event)
23
27
  end
@@ -109,19 +109,13 @@ module FlydataCore
109
109
  msg = build_log_message(level, message, log_params, options)
110
110
  before_logging(level, message, msg, log_params, options)
111
111
  logger = get_logger(options)
112
- set_mutex(logger)
113
- logger.mutex.synchronize do
114
- original_depth_offset = nil
115
- if logger.instance_variable_defined? :@depth_offset
116
- original_depth_offset = logger.instance_variable_get(:@depth_offset)
117
- depth_offset = 3 # log_common + synchronize + synchronized block
118
- depth_offset += options[:depth_offset] if options.has_key?(:depth_offset)
119
- logger.instance_variable_set(:@depth_offset, original_depth_offset + depth_offset)
120
- end
112
+ # For patched Fluent::Log
113
+ if logger.respond_to? :flydata_patched
114
+ depth_offset = 2 # original_depth_offset + log_common
115
+ depth_offset += options[:depth_offset] if options.has_key?(:depth_offset)
116
+ logger.send(level, msg, depth_offset: depth_offset)
117
+ else
121
118
  logger.send(level, msg)
122
- if original_depth_offset
123
- logger.instance_variable_set(:@depth_offset, original_depth_offset)
124
- end
125
119
  end
126
120
  end
127
121
 
@@ -154,17 +148,6 @@ module FlydataCore
154
148
  options[:logger] || logger || log_context_logger || $log
155
149
  end
156
150
 
157
- # set mutex if logger doesn't have one
158
- def set_mutex(logger)
159
- return if logger.respond_to?(:mutex)
160
-
161
- mtx = Mutex.new
162
- logger.instance_variable_set(:@mutex, mtx)
163
- class << logger
164
- attr_reader :mutex
165
- end
166
- end
167
-
168
151
  def build_log_message(level, raw_message, log_params = {}, options = {})
169
152
  message = raw_message.dup
170
153
  # check keys
@@ -9,7 +9,7 @@ module FlydataCore
9
9
  describe "#process" do
10
10
 
11
11
  context "when event has one verb handler and one any verb handler," do
12
- let(:event) {FlydataEvent.new("test2","testing",nil, 1)}
12
+ let(:event) {FlydataEvent.new("test2", "testing", id: 1)}
13
13
  it "should call both handlers" do
14
14
  expect(AnyHandler).to receive(:handle).with(event)
15
15
  expect(Handler3).to receive(:handle).with(event)
@@ -18,7 +18,7 @@ module FlydataCore
18
18
  end
19
19
 
20
20
  context "when event has two handlers," do
21
- let(:event) {FlydataEvent.new("test","testing",nil, 1)}
21
+ let(:event) {FlydataEvent.new("test","testing", id: 1)}
22
22
  it "should call both handlers" do
23
23
  expect(Handler1).to receive(:handle).with(event)
24
24
  expect(Handler2).to receive(:handle).with(event)
@@ -11,7 +11,7 @@ module FlydataCore
11
11
 
12
12
  context "#send_event" do
13
13
  subject{
14
- send_event("test","testing",nil, 1)
14
+ send_event("test","testing", id: 1)
15
15
  }
16
16
  it "should raise exception" do
17
17
  expect { raise Exception}
@@ -5,34 +5,43 @@ module FlydataCore
5
5
  module Event
6
6
  describe FlydataEvent do
7
7
  describe "#initialize" do
8
- let(:noun){"test"}
9
- let(:verb){"testing"}
10
- let(:data){{test:123}}
8
+ let(:noun) { "test" }
9
+ let(:verb) { "testing" }
10
+ let(:data) { { 'tables' => %w(table_a table_b) } }
11
11
 
12
- context "when noun and verb are passed" do
13
- it {
14
- event = FlydataEvent.new(noun,verb, nil,1)
15
- expect(event.noun).to eql(noun)
16
- expect(event.verb).to eql(verb)
17
- expect(event.data).to be_nil
18
- expect(event.id).not_to be_nil
12
+ context 'when all parameters are given' do
13
+ let(:parameters) do
14
+ { data_entry_id: 1,
15
+ data_port_id: 2,
16
+ data: data,
17
+ id: 12,
18
+ created: Time.now + 60, }
19
+ end
20
+
21
+ it 'sets given data to instance variables' do
22
+ event = FlydataEvent.new(noun, verb, parameters)
23
+ expect(event.noun).to eq(noun)
24
+ expect(event.verb).to eq(verb)
25
+ expect(event.data).to eq(data)
26
+ expect(event.id).to eq(12)
19
27
  expect(event.data_entry_id).to eql(1)
20
- expect(event.created).not_to be_nil
21
- }
28
+ expect(event.data_port_id).to eql(2)
29
+ expect(event.created).to be_kind_of(Time)
30
+ end
22
31
  end
23
32
 
24
- context "when noun, verb and data are passed" do
25
- it {
26
- event = FlydataEvent.new(noun,verb,data,1)
27
- expect(event.noun).to eql(noun)
28
- expect(event.verb).to eql(verb)
29
- expect(event.data).to eql(data)
30
- expect(event.data_entry_id).to eql(1)
33
+ context 'when parameters are empty' do
34
+ it 'sets default or nil to instance variables' do
35
+ event = FlydataEvent.new(noun, verb)
36
+ expect(event.noun).to eq(noun)
37
+ expect(event.verb).to eq(verb)
38
+ expect(event.data).to be_nil
31
39
  expect(event.id).not_to be_nil
40
+ expect(event.data_entry_id).to be_nil
41
+ expect(event.data_port_id).to be_nil
32
42
  expect(event.created).not_to be_nil
33
- }
43
+ end
34
44
  end
35
-
36
45
  end
37
46
  end
38
47
  end
Binary file
@@ -6,13 +6,13 @@ module Flydata
6
6
  module Command
7
7
  class Restart < Base
8
8
  def self.slop
9
- Slop.new do
10
- on 'skip-helper', 'Skip restarting the Helper'
11
- end
9
+ sender_opts = Flydata::Command::Sender.slop_start # Needs options for Sender#start
10
+ sender_opts.on 'skip-helper', 'Skip starting the Helper'
11
+ sender_opts
12
12
  end
13
13
 
14
14
  def run
15
- sender = Flydata::Command::Sender.new
15
+ sender = Flydata::Command::Sender.new(opts)
16
16
  sender.restart
17
17
  unless opts.skip_helper?
18
18
  helper = Flydata::Command::Helper.new
@@ -8,6 +8,7 @@ module Flydata
8
8
  def self.slop_start
9
9
  Slop.new do
10
10
  on 'n', 'no-daemon', 'Start FlyData agent as a regular program'
11
+ on 'e', 'no-email', 'Skip sending init-sync-start notification email'
11
12
  end
12
13
  end
13
14
  def start(options_or_show_final_message = {show_final_message: true}) # For backward compatibility. Use only as options going forward
@@ -58,7 +59,8 @@ module Flydata
58
59
  # surpress messages if fluentd is started in #try_mysql_sync
59
60
  options[:quiet] = true
60
61
  Flydata::Command::Sync.new.try_mysql_sync(
61
- binlog_ready_callback: start_fluentd)
62
+ binlog_ready_callback: start_fluentd,
63
+ no_email: opts.no_email?)
62
64
  options[:quiet] = quiet_option
63
65
  start_fluentd.call unless fluentd_started
64
66
  if options[:show_final_message] && !options[:quiet]
@@ -20,6 +20,7 @@ require 'flydata-core/mysql/binlog_pos'
20
20
  require 'flydata/mysql/table_ddl'
21
21
  require 'flydata-core/mysql/command_generator'
22
22
  require 'flydata/event/api_event_sender'
23
+ require 'flydata-core/event/event_dictionary'
23
24
  require 'sigdump/setup'
24
25
  #require 'ruby-prof' # to enable profiling, also set the class' RUN_PROFILE
25
26
 
@@ -150,7 +151,7 @@ EOS
150
151
  log_info_stdout <<EOS
151
152
  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
 
153
- flyudata sync:reset --init
154
+ flydata sync:reset --init
154
155
  EOS
155
156
  return
156
157
  end
@@ -672,9 +673,14 @@ EOM
672
673
  log_info_stdout("This process can take hours depending on data size and load on your database. Please be patient...")
673
674
  sync_fm.save_sync_info(@full_initial_sync, target_tables)
674
675
  # This notification will be uncommented after init_sync_finish email integration is released
675
- #unless options[:sync_resumed]
676
- # FlydataCore::Event::ApiEventSender.instance.send_event("init_sync", "started", {"tables" => target_tables}, de['id'])
677
- #end
676
+ unless options[:sync_resumed]
677
+ FlydataCore::Event::ApiEventSender.instance.send_event(
678
+ FlydataCore::Event::INIT_SYNC,
679
+ FlydataCore::Event::STARTED,
680
+ data: {"tables" => target_tables, 'no_email' => options[:no_email]},
681
+ data_entry_id: de['id'],
682
+ data_port_id: de['data_port_id'])
683
+ end
678
684
  dump_generator = Flydata::Parser::Mysql::MysqlDumpGeneratorNoMasterData.new(de['mysql_data_entry_preference'].merge('tables' => target_tables))
679
685
  if file_dump
680
686
  binlog_pos = nil
@@ -877,10 +883,10 @@ EOM
877
883
  sync_fm.save_dump_pos(STATUS_PARSING, table_name, last_pos, binlog_pos, state, substate)
878
884
 
879
885
  # send record count for the table
880
- if mysql_table &&
886
+ if table_name.to_s != '' &&
881
887
  state == Flydata::Parser::Mysql::MysqlDumpParser::State::CREATE_TABLE
882
888
  # all records for `mysql_table` have been sent
883
- send_record_counts(de, sync_fm, mysql_table.table_name,
889
+ send_record_counts(de, sync_fm, table_name,
884
890
  send_record_counts_threads)
885
891
  log_info_stdout(" -> Finished sending data for table '#{table_name}'...")
886
892
  end
@@ -29,6 +29,9 @@ module Mysql
29
29
  end
30
30
 
31
31
  private
32
+ def binlog_pos(record)
33
+ "#{@context.current_binlog_file}\t#{record['next_position'] - record['event_length']}"
34
+ end
32
35
 
33
36
  def supported_database
34
37
  @context.database
@@ -42,8 +45,7 @@ module Mysql
42
45
  acceptable = @context.tables.include?(table)
43
46
 
44
47
  if acceptable and @table_binlog_pos[record['table_name']]
45
- if @table_binlog_pos[record['table_name']] >= Flydata::Mysql::BinLogPosition.new(
46
- "#{@context.current_binlog_file}\t#{record['next_position'] - record['event_length']}")
48
+ if @table_binlog_pos[record['table_name']] >= Flydata::Mysql::BinLogPosition.new(binlog_pos(record))
47
49
  acceptable = false
48
50
  else
49
51
  @context.sync_fm.delete_table_binlog_pos(record['table_name'])
@@ -73,7 +75,6 @@ module Mysql
73
75
  return unless acceptable_table?(record, table) && acceptable_event?(type, table)
74
76
 
75
77
  table_rev = @context.table_revs[table]
76
- position = record['next_position'] - record['event_length']
77
78
 
78
79
  # Add common information to each record
79
80
  records.each do |r|
@@ -84,7 +85,7 @@ module Mysql
84
85
  r[TYPE] = type
85
86
  r[RESPECT_ORDER] = true
86
87
  r[TABLE_NAME] = table
87
- r[SRC_POS] = "#{@context.current_binlog_file}\t#{position}"
88
+ r[SRC_POS] = binlog_pos(record)
88
89
  r[TABLE_REV] = table_rev
89
90
  r[V] = FlydataCore::Record::V2
90
91
  end
@@ -51,13 +51,11 @@ class DatabaseDdlQueryHandler < DdlQueryHandler
51
51
 
52
52
  return unless acceptable_event?(type)
53
53
 
54
- position = record['next_position'] - record['event_length']
55
-
56
54
  # Add common information to each record
57
55
  records.each do |r|
58
56
  r[TYPE] = type
59
57
  r[RESPECT_ORDER] = true
60
- r[SRC_POS] = "#{@context.current_binlog_file}\t#{position}"
58
+ r[SRC_POS] = binlog_pos(record)
61
59
  r[V] = FlydataCore::Record::V2
62
60
  end
63
61
 
@@ -15,8 +15,8 @@ module Mysql
15
15
 
16
16
  def process(record)
17
17
  #Issuing warning message only for the current database.
18
- if record["db_name"] == @context.database
19
- $log.warn("DROP DATABASE detected. A full re-sync is required to provide sync consistency. db_name: #{record["db_name"]}")
18
+ if acceptable_db?(record) #record["db_name"] == @context.database
19
+ $log.warn("DROP DATABASE detected. A full re-sync is required to provide sync consistency. - db_name:'#{record["db_name"]}' query:'#{record["query"]}' normalized query:'#{record['normalized_query']}' binlog_pos:'#{binlog_pos(record)}'")
20
20
  end
21
21
  #NOTE: No emit_record here because this record should not be sent to data servers for now
22
22
  end
@@ -108,6 +108,7 @@ module Flydata
108
108
  expect(subject).to receive(:ask_yes_no).and_return(true).at_least(:once)
109
109
  Flydata::Parser::Mysql::DatabaseSizeCheck.any_instance.should_receive(:get_db_bytesize).and_return(db_byte)
110
110
  Flydata::MysqlCompatibilityCheck.any_instance.should_receive(:check)
111
+ expect_any_instance_of(FlydataCore::Event::ApiEventSender).to receive(:send_event).once
111
112
  end
112
113
  context 'with no stream option' do
113
114
  before do
@@ -19,9 +19,11 @@ module Mysql
19
19
  shared_examples "test different dbs" do
20
20
  context "for the target db" do
21
21
  let(:database) { target_database }
22
-
22
+ let(:binlog_pos) { "#{context.current_binlog_file}\t#{record['next_position'] - record['event_length']}" }
23
+
23
24
  it "shows a warning message" do
24
- expect($log).to receive(:warn).with("DROP DATABASE detected. A full re-sync is required to provide sync consistency. db_name: #{record["db_name"]}").once
25
+ expect($log).to receive(:warn).with("DROP DATABASE detected. A full re-sync is required to provide sync consistency. - db_name:'#{record["db_name"]}' query:'#{record["query"]}' normalized query:'#{record["normalized_query"]}' binlog_pos:'#{binlog_pos}'")
26
+
25
27
  subject
26
28
  end
27
29
  end
@@ -65,5 +65,29 @@ describe JSON do
65
65
  it_behaves_like "producing the expected result"
66
66
  end
67
67
  end
68
+
69
+ context 'testing memory' do
70
+ let(:keys) { ['id', 'user_id', 'name', 'timestamp'] }
71
+ let(:values) { ['29388381012', '192938439', 'Muy Fiel y Reconquistadora Ciudad de San Felipe y Santiago de Montevideo', '2015-12-01 12:34:56' ] }
72
+ let(:expected_result) { %Q|{"id":"29388381012","user_id":"192938439","name":"Muy Fiel y Reconquistadora Ciudad de San Felipe y Santiago de Montevideo","timestamp":"2015-12-01 12:34:56"}| }
73
+ xcontext 'when run many many times' do
74
+ thread = nil
75
+ before do
76
+ GC.stress = true
77
+ thread = Thread.new { loop {rand(9).to_s * rand(9)} }
78
+ end
79
+ it do
80
+ 6000.times do
81
+ result = described_class.generate_kv_pairs(keys, values)
82
+ rand(9).to_s * rand(9)
83
+ expect(result).to eq expected_result
84
+ end
85
+ end
86
+ after do
87
+ GC.stress = false
88
+ thread.kill
89
+ end
90
+ end
91
+ end
68
92
  end
69
93
  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.6.0
4
+ version: 0.6.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: 2015-12-01 00:00:00.000000000 Z
15
+ date: 2015-12-07 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rest-client
@@ -513,6 +513,7 @@ files:
513
513
  - flydata-core/lib/flydata-core/core_ext/object.rb
514
514
  - flydata-core/lib/flydata-core/core_ext/object/prepend.rb
515
515
  - flydata-core/lib/flydata-core/errors.rb
516
+ - flydata-core/lib/flydata-core/event/event_dictionary.rb
516
517
  - flydata-core/lib/flydata-core/event/event_handler_base.rb
517
518
  - flydata-core/lib/flydata-core/event/flydata_event.rb
518
519
  - flydata-core/lib/flydata-core/event/flydata_event_handler_registry.rb
@@ -744,7 +745,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
744
745
  version: '0'
745
746
  requirements: []
746
747
  rubyforge_project:
747
- rubygems_version: 2.4.3
748
+ rubygems_version: 2.0.14.1
748
749
  signing_key:
749
750
  specification_version: 4
750
751
  summary: FlyData Agent