flydata 0.2.21 → 0.2.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/flydata.gemspec +6 -5
- data/lib/flydata/fluent-plugins/idle_event_detector.rb +68 -0
- data/lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb +18 -0
- data/lib/flydata/output/forwarder.rb +3 -1
- data/spec/flydata/fluent-plugins/idle_event_detector_spec.rb +403 -0
- data/spec/flydata/output/forwarder_spec.rb +19 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99feeb76fa109f4255e1d76c881d1631e82fdfbe
|
4
|
+
data.tar.gz: 8c080c31ac049d2ad3e30bef154507a6ec15aec7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f51151ca084d61e1fdf9bea821151f86f54c773c53223daa35a0ac5e173125906cc2cee2ab53ef691bcebcd7f1ae59b96476977786e6d076b3542021dea982cb
|
7
|
+
data.tar.gz: fbca06f1f714479abcf848e16cd9905579ed857ffbcf7a1b9b3d42895f17fb5446f7fc5e17ffa103595e25c87ac1c06e011c03449a16b9c1f4c5afc6f52968ed
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.22
|
data/flydata.gemspec
CHANGED
@@ -2,16 +2,14 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: flydata 0.2.21 ruby lib
|
6
5
|
|
7
6
|
Gem::Specification.new do |s|
|
8
7
|
s.name = "flydata"
|
9
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.22"
|
10
9
|
|
11
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
-
s.require_paths = ["lib"]
|
13
11
|
s.authors = ["Koichi Fujikawa", "Masashi Miyazaki", "Matthew Luu", "Mak Inada", "Sriram NS"]
|
14
|
-
s.date = "2014-12-
|
12
|
+
s.date = "2014-12-15"
|
15
13
|
s.description = "FlyData Agent"
|
16
14
|
s.email = "sysadmin@flydata.com"
|
17
15
|
s.executables = ["fdmysqldump", "flydata", "serverinfo"]
|
@@ -91,6 +89,7 @@ Gem::Specification.new do |s|
|
|
91
89
|
"lib/flydata/compatibility_check.rb",
|
92
90
|
"lib/flydata/credentials.rb",
|
93
91
|
"lib/flydata/cron.rb",
|
92
|
+
"lib/flydata/fluent-plugins/idle_event_detector.rb",
|
94
93
|
"lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb",
|
95
94
|
"lib/flydata/fluent-plugins/mysql/alter_table_query_handler.rb",
|
96
95
|
"lib/flydata/fluent-plugins/mysql/binlog_position.rb",
|
@@ -126,6 +125,7 @@ Gem::Specification.new do |s|
|
|
126
125
|
"spec/flydata/command/sender_spec.rb",
|
127
126
|
"spec/flydata/command/sync_spec.rb",
|
128
127
|
"spec/flydata/compatibility_check_spec.rb",
|
128
|
+
"spec/flydata/fluent-plugins/idle_event_detector_spec.rb",
|
129
129
|
"spec/flydata/fluent-plugins/in_mysql_binlog_flydata_spec.rb",
|
130
130
|
"spec/flydata/fluent-plugins/mysql/alter_table_query_handler_spec.rb",
|
131
131
|
"spec/flydata/fluent-plugins/mysql/binlog_position_spec.rb",
|
@@ -143,7 +143,8 @@ Gem::Specification.new do |s|
|
|
143
143
|
]
|
144
144
|
s.homepage = "http://flydata.com/"
|
145
145
|
s.licenses = ["All right reserved."]
|
146
|
-
s.
|
146
|
+
s.require_paths = ["lib"]
|
147
|
+
s.rubygems_version = "2.0.14"
|
147
148
|
s.summary = "FlyData Agent"
|
148
149
|
|
149
150
|
if s.respond_to? :specification_version then
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Fluent
|
2
|
+
|
3
|
+
class IdleEventDetector
|
4
|
+
def initialize(initial_interval, continuous_interval, check_interval = 5)
|
5
|
+
@mutex = Mutex.new
|
6
|
+
@initial_interval = initial_interval
|
7
|
+
@continuous_interval = continuous_interval
|
8
|
+
@check_interval = check_interval
|
9
|
+
end
|
10
|
+
|
11
|
+
def start(&block)
|
12
|
+
raise "block must be given" unless block_given?
|
13
|
+
@callback = block
|
14
|
+
stop if @thread
|
15
|
+
@last_event_at = @timestamp = Time.current
|
16
|
+
@is_absent = false
|
17
|
+
|
18
|
+
@thread = Thread.new do
|
19
|
+
loop do
|
20
|
+
check_state
|
21
|
+
sleep @check_interval
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def stop
|
27
|
+
@thread.exit if @thread
|
28
|
+
@thread = nil
|
29
|
+
@is_absent = false
|
30
|
+
@last_event_at = @timestamp = nil
|
31
|
+
@callback = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def notify
|
35
|
+
update_last_event_time
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def update_last_event_time
|
41
|
+
@mutex.synchronize do
|
42
|
+
@last_event_at = @timestamp = Time.current
|
43
|
+
if @is_absent
|
44
|
+
@callback.call(:event_arrived_finally, @last_event_at) if @callback
|
45
|
+
@is_absent = false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def check_state
|
51
|
+
@mutex.synchronize do
|
52
|
+
if @is_absent
|
53
|
+
if Time.current - @timestamp >= @continuous_interval
|
54
|
+
@callback.call(:event_still_not_coming, @last_event_at) if @callback
|
55
|
+
@timestamp = Time.current
|
56
|
+
end
|
57
|
+
else
|
58
|
+
if Time.current - @timestamp >= @initial_interval
|
59
|
+
@callback.call(:event_not_coming, @last_event_at) if @callback
|
60
|
+
@is_absent = true
|
61
|
+
@timestamp = Time.current
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -14,6 +14,7 @@ require_relative 'preference'
|
|
14
14
|
require_relative 'mysql/binlog_position_file'
|
15
15
|
require_relative 'mysql/binlog_record_dispatcher'
|
16
16
|
require_relative 'mysql/context'
|
17
|
+
require_relative 'idle_event_detector'
|
17
18
|
require_relative 'mysql/table_meta'
|
18
19
|
|
19
20
|
#Monkey-patch fluentd class (EngineClass) to support shutdown for input plugin.
|
@@ -49,6 +50,9 @@ class MysqlBinlogFlydataInput < MysqlBinlogInput
|
|
49
50
|
config_param :database, :string
|
50
51
|
config_param :tables, :string
|
51
52
|
config_param :tables_append_only, :string
|
53
|
+
config_param :initial_idle_interval, :integer, :default => 30
|
54
|
+
config_param :continuous_idle_interval, :integer, :default => 600
|
55
|
+
config_param :check_interval, :integer, :default => 5
|
52
56
|
|
53
57
|
def configure(conf)
|
54
58
|
super
|
@@ -80,10 +84,22 @@ class MysqlBinlogFlydataInput < MysqlBinlogInput
|
|
80
84
|
table_meta: table_meta,
|
81
85
|
)
|
82
86
|
@record_dispatcher = Mysql::FlydataBinlogRecordDispatcher.new(@context)
|
87
|
+
@idle_event_detector = IdleEventDetector.new(@initial_idle_interval, @continuous_idle_interval, @check_interval)
|
83
88
|
end
|
84
89
|
|
85
90
|
def start
|
86
91
|
super
|
92
|
+
@idle_event_detector.start do |reason, timestamp|
|
93
|
+
case reason
|
94
|
+
when :event_not_coming
|
95
|
+
$log.warn "No binary log event since #{timestamp}"
|
96
|
+
when :event_still_not_coming
|
97
|
+
$log.warn "No binary log event since #{timestamp}"
|
98
|
+
when :event_arrived_finally
|
99
|
+
$log.info "Binary log event has come at #{timestamp}"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
87
103
|
positions_path = @context.sync_fm.table_positions_dir_path
|
88
104
|
Dir.mkdir positions_path unless File.exists? positions_path
|
89
105
|
rescue Binlog::Error
|
@@ -132,6 +148,7 @@ EOS
|
|
132
148
|
end
|
133
149
|
|
134
150
|
def event_listener(event)
|
151
|
+
@idle_event_detector.notify
|
135
152
|
@record_dispatcher.dispatch(event)
|
136
153
|
rescue Exception => e
|
137
154
|
position = @binlog_position_file.read
|
@@ -141,6 +158,7 @@ EOS
|
|
141
158
|
end
|
142
159
|
|
143
160
|
def shutdown
|
161
|
+
@idle_event_detector.stop
|
144
162
|
if @thread and @thread.alive?
|
145
163
|
$log.info "Requesting stop Kodama"
|
146
164
|
@kodama_client.stop_request
|
@@ -23,6 +23,8 @@ module Flydata
|
|
23
23
|
end
|
24
24
|
|
25
25
|
class TcpForwarder
|
26
|
+
include CommandLoggable
|
27
|
+
|
26
28
|
FORWARD_HEADER = [0x92].pack('C')
|
27
29
|
BUFFER_SIZE = 1024 * 1024 * 32 # 32M
|
28
30
|
DEFUALT_SEND_TIMEOUT = 60 # 1 minute
|
@@ -95,7 +97,7 @@ module Flydata
|
|
95
97
|
log_error_stderr("! Error: Failed to send data. Exceeded the retry limit. retry_count:#{retry_count}")
|
96
98
|
raise e
|
97
99
|
end
|
98
|
-
log_warn_stderr("! Warn:
|
100
|
+
log_warn_stderr("! Warn: Retrying to send data. retry_count:#{retry_count} error=#{e.to_s}")
|
99
101
|
wait_time = RETRY_INTERVAL ** retry_count
|
100
102
|
log_warn_stderr(" Now waiting for next retry. time=#{wait_time}sec")
|
101
103
|
sleep wait_time
|
@@ -0,0 +1,403 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'fluent_plugins_spec_helper'
|
4
|
+
require 'idle_event_detector'
|
5
|
+
require 'timecop'
|
6
|
+
|
7
|
+
module Fluent
|
8
|
+
|
9
|
+
describe IdleEventDetector do
|
10
|
+
let(:time) { Time.local(2014, 12, 1, 5, 0, 0) }
|
11
|
+
let(:initial_interval) { 0.1 }
|
12
|
+
let(:continuous_interval) { 0.18 }
|
13
|
+
let(:check_interval) { 0.1 }
|
14
|
+
|
15
|
+
subject { described_class.new(initial_interval, continuous_interval, check_interval) }
|
16
|
+
|
17
|
+
describe '#start' do
|
18
|
+
context 'without block' do
|
19
|
+
it 'errors out' do
|
20
|
+
expect{ subject.start }.to raise_error
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'no event within initial_interval' do
|
25
|
+
before do
|
26
|
+
Timecop.freeze(time)
|
27
|
+
@callback_called = false
|
28
|
+
end
|
29
|
+
let(:callback) { Proc.new { @callback_called = true } }
|
30
|
+
it 'fires :event_not_coming callback' do
|
31
|
+
|
32
|
+
subject.start(&callback)
|
33
|
+
|
34
|
+
Timecop.freeze(time + initial_interval + continuous_interval * 0.2)
|
35
|
+
|
36
|
+
sleep check_interval * 1.1
|
37
|
+
|
38
|
+
expect(@callback_called).to eq true
|
39
|
+
end
|
40
|
+
after do
|
41
|
+
Timecop.return
|
42
|
+
@callback_called = false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
context 'no event during test which completes before initial_interval' do
|
46
|
+
before do
|
47
|
+
Timecop.freeze(time)
|
48
|
+
@callback_called = false
|
49
|
+
end
|
50
|
+
let(:callback) { Proc.new { @callback_called = true } }
|
51
|
+
it 'does not fire :event_not_coming callback' do
|
52
|
+
|
53
|
+
subject.start(&callback)
|
54
|
+
|
55
|
+
Timecop.freeze(time + initial_interval * 0.2)
|
56
|
+
|
57
|
+
sleep check_interval * 1.1
|
58
|
+
|
59
|
+
expect(@callback_called).to eq false
|
60
|
+
|
61
|
+
subject.stop
|
62
|
+
end
|
63
|
+
after do
|
64
|
+
Timecop.return
|
65
|
+
@callback_called = false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
context 'an event during test which completes after initial_interval' do
|
69
|
+
before do
|
70
|
+
Timecop.freeze(time)
|
71
|
+
@callback_called = false
|
72
|
+
end
|
73
|
+
let(:callback) { Proc.new { @callback_called = true } }
|
74
|
+
it 'does not fire :event_not_coming callback' do
|
75
|
+
|
76
|
+
subject.start(&callback)
|
77
|
+
|
78
|
+
Timecop.freeze(time + initial_interval * 0.2)
|
79
|
+
|
80
|
+
sleep check_interval * 1.1
|
81
|
+
|
82
|
+
subject.notify
|
83
|
+
|
84
|
+
Timecop.freeze(time + initial_interval + initial_interval * 0.1)
|
85
|
+
|
86
|
+
sleep check_interval * 1.1
|
87
|
+
|
88
|
+
expect(@callback_called).to eq false
|
89
|
+
|
90
|
+
subject.stop
|
91
|
+
end
|
92
|
+
after do
|
93
|
+
Timecop.return
|
94
|
+
@callback_called = false
|
95
|
+
end
|
96
|
+
end
|
97
|
+
context 'no event during test which completes after initial_interval + continuous_interval' do
|
98
|
+
let(:callback) {
|
99
|
+
Proc.new do |reason|
|
100
|
+
case reason
|
101
|
+
when :event_not_coming
|
102
|
+
@initial_callback_called = true
|
103
|
+
when :event_still_not_coming
|
104
|
+
@continuous_callback_called = true
|
105
|
+
end
|
106
|
+
end
|
107
|
+
}
|
108
|
+
before do
|
109
|
+
Timecop.freeze(time)
|
110
|
+
@initial_callback_called = false
|
111
|
+
@continuous_callback_called = false
|
112
|
+
end
|
113
|
+
it 'fires an :event_not_coming callback and an :event_still_not_coming' do
|
114
|
+
subject.start(&callback)
|
115
|
+
|
116
|
+
expect(@initial_callback_called).to eq false
|
117
|
+
expect(@continuous_callback_called).to eq false
|
118
|
+
|
119
|
+
Timecop.freeze(time + initial_interval + continuous_interval * 0.2)
|
120
|
+
sleep check_interval * 1.1
|
121
|
+
|
122
|
+
expect(@initial_callback_called).to eq true
|
123
|
+
expect(@continuous_callback_called).to eq false
|
124
|
+
|
125
|
+
Timecop.freeze(time + initial_interval + continuous_interval + check_interval)
|
126
|
+
|
127
|
+
sleep check_interval * 1.1
|
128
|
+
|
129
|
+
expect(@initial_callback_called).to eq true
|
130
|
+
expect(@continuous_callback_called).to eq true
|
131
|
+
|
132
|
+
subject.stop
|
133
|
+
end
|
134
|
+
after do
|
135
|
+
Timecop.return
|
136
|
+
@initial_callback_called = false
|
137
|
+
@continuous_callback_called = false
|
138
|
+
@arrived_callback_called = false
|
139
|
+
end
|
140
|
+
end
|
141
|
+
context 'an event during test after initial_interval' do
|
142
|
+
let(:callback) {
|
143
|
+
Proc.new do |reason|
|
144
|
+
case reason
|
145
|
+
when :event_not_coming
|
146
|
+
@initial_callback_called = true
|
147
|
+
when :event_still_not_coming
|
148
|
+
@continuous_callback_called = true
|
149
|
+
when :event_arrived_finally
|
150
|
+
@arrived_callback_called = true
|
151
|
+
end
|
152
|
+
end
|
153
|
+
}
|
154
|
+
before do
|
155
|
+
Timecop.freeze(time)
|
156
|
+
@initial_callback_called = false
|
157
|
+
@continuous_callback_called = false
|
158
|
+
@arrived_callback_called = false
|
159
|
+
end
|
160
|
+
it 'fires an :event_not_coming callback and an :event_arrived_finaly callback' do
|
161
|
+
subject.start(&callback)
|
162
|
+
|
163
|
+
expect(@initial_callback_called).to eq false
|
164
|
+
expect(@continuous_callback_called).to eq false
|
165
|
+
expect(@arrived_callback_called).to eq false
|
166
|
+
|
167
|
+
Timecop.freeze(time + initial_interval + initial_interval * 0.2)
|
168
|
+
sleep check_interval * 1.1
|
169
|
+
|
170
|
+
expect(@initial_callback_called).to eq true
|
171
|
+
expect(@continuous_callback_called).to eq false
|
172
|
+
expect(@arrived_callback_called).to eq false
|
173
|
+
|
174
|
+
Timecop.freeze(time + initial_interval + initial_interval * 0.8)
|
175
|
+
|
176
|
+
subject.notify
|
177
|
+
|
178
|
+
sleep check_interval * 1.1
|
179
|
+
|
180
|
+
expect(@initial_callback_called).to eq true
|
181
|
+
expect(@continuous_callback_called).to eq false
|
182
|
+
expect(@arrived_callback_called).to eq true
|
183
|
+
|
184
|
+
subject.stop
|
185
|
+
end
|
186
|
+
after do
|
187
|
+
Timecop.return
|
188
|
+
@initial_callback_called = false
|
189
|
+
@continuous_callback_called = false
|
190
|
+
@arrived_callback_called = false
|
191
|
+
end
|
192
|
+
end
|
193
|
+
context 'an event during test after initial_interval + continuous_interval' do
|
194
|
+
let(:callback) {
|
195
|
+
Proc.new do |reason|
|
196
|
+
case reason
|
197
|
+
when :event_not_coming
|
198
|
+
@initial_callback_called = true
|
199
|
+
when :event_still_not_coming
|
200
|
+
@continuous_callback_called = true
|
201
|
+
when :event_arrived_finally
|
202
|
+
@arrived_callback_called = true
|
203
|
+
end
|
204
|
+
end
|
205
|
+
}
|
206
|
+
before do
|
207
|
+
Timecop.freeze(time)
|
208
|
+
@initial_callback_called = false
|
209
|
+
@continuous_callback_called = false
|
210
|
+
@arrived_callback_called = false
|
211
|
+
end
|
212
|
+
it 'fires all 3 callbacks' do
|
213
|
+
subject.start(&callback)
|
214
|
+
|
215
|
+
expect(@initial_callback_called).to eq false
|
216
|
+
expect(@continuous_callback_called).to eq false
|
217
|
+
expect(@arrived_callback_called).to eq false
|
218
|
+
|
219
|
+
Timecop.freeze(time + initial_interval + initial_interval * 0.2)
|
220
|
+
sleep check_interval * 1.1
|
221
|
+
|
222
|
+
expect(@initial_callback_called).to eq true
|
223
|
+
expect(@continuous_callback_called).to eq false
|
224
|
+
expect(@arrived_callback_called).to eq false
|
225
|
+
|
226
|
+
@initial_callback_called = false
|
227
|
+
|
228
|
+
Timecop.freeze(time + initial_interval + continuous_interval + initial_interval * 0.2)
|
229
|
+
|
230
|
+
sleep check_interval * 1.1
|
231
|
+
|
232
|
+
expect(@initial_callback_called).to eq false
|
233
|
+
expect(@continuous_callback_called).to eq true
|
234
|
+
expect(@arrived_callback_called).to eq false
|
235
|
+
|
236
|
+
@continuous_callback_called = false
|
237
|
+
|
238
|
+
Timecop.freeze(time + initial_interval + continuous_interval + initial_interval * 0.4)
|
239
|
+
|
240
|
+
subject.notify
|
241
|
+
|
242
|
+
sleep check_interval * 1.1
|
243
|
+
|
244
|
+
expect(@initial_callback_called).to eq false
|
245
|
+
expect(@continuous_callback_called).to eq false
|
246
|
+
expect(@arrived_callback_called).to eq true
|
247
|
+
|
248
|
+
subject.stop
|
249
|
+
end
|
250
|
+
after do
|
251
|
+
Timecop.return
|
252
|
+
@initial_callback_called = false
|
253
|
+
@continuous_callback_called = false
|
254
|
+
@arrived_callback_called = false
|
255
|
+
end
|
256
|
+
end
|
257
|
+
context 'no event during test which is long enough for two event_still_not_coming callbacks' do
|
258
|
+
let(:callback) {
|
259
|
+
Proc.new do |reason|
|
260
|
+
case reason
|
261
|
+
when :event_not_coming
|
262
|
+
@initial_callback_called = true
|
263
|
+
when :event_still_not_coming
|
264
|
+
@continuous_callback_called = true
|
265
|
+
when :event_arrived_finally
|
266
|
+
@arrived_callback_called = true
|
267
|
+
end
|
268
|
+
end
|
269
|
+
}
|
270
|
+
before do
|
271
|
+
Timecop.freeze(time)
|
272
|
+
@initial_callback_called = false
|
273
|
+
@continuous_callback_called = false
|
274
|
+
@arrived_callback_called = false
|
275
|
+
end
|
276
|
+
it 'fires two event_still_not_coming callbacks after an event_not_coming callback' do
|
277
|
+
subject.start(&callback)
|
278
|
+
|
279
|
+
expect(@initial_callback_called).to eq false
|
280
|
+
expect(@continuous_callback_called).to eq false
|
281
|
+
expect(@arrived_callback_called).to eq false
|
282
|
+
|
283
|
+
Timecop.freeze(time + initial_interval + initial_interval * 0.2)
|
284
|
+
sleep check_interval * 1.1
|
285
|
+
|
286
|
+
expect(@initial_callback_called).to eq true
|
287
|
+
expect(@continuous_callback_called).to eq false
|
288
|
+
expect(@arrived_callback_called).to eq false
|
289
|
+
|
290
|
+
@initial_callback_called = false
|
291
|
+
|
292
|
+
Timecop.freeze(time + initial_interval + continuous_interval + initial_interval * 0.2)
|
293
|
+
|
294
|
+
sleep check_interval * 1.1
|
295
|
+
|
296
|
+
expect(@initial_callback_called).to eq false
|
297
|
+
expect(@continuous_callback_called).to eq true
|
298
|
+
expect(@arrived_callback_called).to eq false
|
299
|
+
|
300
|
+
@continuous_callback_called = false
|
301
|
+
|
302
|
+
Timecop.freeze(time + initial_interval + continuous_interval + continuous_interval + initial_interval * 0.2)
|
303
|
+
|
304
|
+
sleep check_interval * 1.1
|
305
|
+
|
306
|
+
expect(@initial_callback_called).to eq false
|
307
|
+
expect(@continuous_callback_called).to eq true
|
308
|
+
expect(@arrived_callback_called).to eq false
|
309
|
+
|
310
|
+
subject.stop
|
311
|
+
end
|
312
|
+
after do
|
313
|
+
Timecop.return
|
314
|
+
@initial_callback_called = false
|
315
|
+
@continuous_callback_called = false
|
316
|
+
@arrived_callback_called = false
|
317
|
+
end
|
318
|
+
end
|
319
|
+
context 'an event after initial_interval and no event for another initial_interval time' do
|
320
|
+
let(:callback) {
|
321
|
+
Proc.new do |reason|
|
322
|
+
case reason
|
323
|
+
when :event_not_coming
|
324
|
+
@initial_callback_called = true
|
325
|
+
when :event_still_not_coming
|
326
|
+
@continuous_callback_called = true
|
327
|
+
when :event_arrived_finally
|
328
|
+
@arrived_callback_called = true
|
329
|
+
end
|
330
|
+
end
|
331
|
+
}
|
332
|
+
before do
|
333
|
+
Timecop.freeze(time)
|
334
|
+
@initial_callback_called = false
|
335
|
+
@continuous_callback_called = false
|
336
|
+
@arrived_callback_called = false
|
337
|
+
end
|
338
|
+
it 'fires two event_still_not_coming callbacks after an event_not_coming callback' do
|
339
|
+
subject.start(&callback)
|
340
|
+
|
341
|
+
expect(@initial_callback_called).to eq false
|
342
|
+
expect(@continuous_callback_called).to eq false
|
343
|
+
expect(@arrived_callback_called).to eq false
|
344
|
+
|
345
|
+
Timecop.freeze(time + initial_interval + initial_interval * 0.2)
|
346
|
+
sleep check_interval * 1.1
|
347
|
+
|
348
|
+
expect(@initial_callback_called).to eq true
|
349
|
+
expect(@continuous_callback_called).to eq false
|
350
|
+
expect(@arrived_callback_called).to eq false
|
351
|
+
|
352
|
+
@initial_callback_called = false
|
353
|
+
|
354
|
+
Timecop.freeze(time + initial_interval + initial_interval * 0.4)
|
355
|
+
|
356
|
+
subject.notify
|
357
|
+
|
358
|
+
sleep check_interval * 1.1
|
359
|
+
|
360
|
+
expect(@initial_callback_called).to eq false
|
361
|
+
expect(@continuous_callback_called).to eq false
|
362
|
+
expect(@arrived_callback_called).to eq true
|
363
|
+
|
364
|
+
@arrived_callback_called = false
|
365
|
+
|
366
|
+
Timecop.freeze(time + initial_interval + initial_interval * 0.4 + initial_interval + initial_interval * 0.2)
|
367
|
+
|
368
|
+
sleep check_interval * 1.1
|
369
|
+
|
370
|
+
expect(@initial_callback_called).to eq true
|
371
|
+
expect(@continuous_callback_called).to eq false
|
372
|
+
expect(@arrived_callback_called).to eq false
|
373
|
+
|
374
|
+
subject.stop
|
375
|
+
end
|
376
|
+
after do
|
377
|
+
Timecop.return
|
378
|
+
@initial_callback_called = false
|
379
|
+
@continuous_callback_called = false
|
380
|
+
@arrived_callback_called = false
|
381
|
+
end
|
382
|
+
end
|
383
|
+
end
|
384
|
+
describe '#stop' do
|
385
|
+
context 'stop without corresponding start' do
|
386
|
+
it 'behaves nicely' do
|
387
|
+
subject.stop
|
388
|
+
end
|
389
|
+
end
|
390
|
+
context 'stop with corresponding start' do
|
391
|
+
it 'kills the thread' do
|
392
|
+
subject.start {}
|
393
|
+
thread = subject.instance_variable_get(:@thread)
|
394
|
+
expect(thread.alive?).to eq true
|
395
|
+
subject.stop
|
396
|
+
sleep 0.05
|
397
|
+
expect(thread.alive?).to eq false
|
398
|
+
end
|
399
|
+
end
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
end
|
@@ -8,8 +8,8 @@ module Flydata
|
|
8
8
|
let(:forwarder) do
|
9
9
|
ForwarderFactory.create('tcpforwarder', 'test_tag', ['localhost:3456', 'localhost:4567'])
|
10
10
|
end
|
11
|
+
let(:conn) { double(TCPSocket) }
|
11
12
|
before :each do
|
12
|
-
conn = double(TCPSocket)
|
13
13
|
allow(conn).to receive(:setsockopt)
|
14
14
|
allow(conn).to receive(:write)
|
15
15
|
allow(conn).to receive(:close)
|
@@ -73,6 +73,24 @@ module Flydata
|
|
73
73
|
expect(forwarder.buffer_record_count).to be(0)
|
74
74
|
end
|
75
75
|
end
|
76
|
+
context 'when the error happens during the data sending' do
|
77
|
+
before do
|
78
|
+
@never_received = true
|
79
|
+
allow(conn).to receive(:write) do
|
80
|
+
if @never_received
|
81
|
+
@never_received = false
|
82
|
+
raise "test-error"
|
83
|
+
else
|
84
|
+
nil
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
it 'retry and succeed sending data' do
|
89
|
+
forwarder.emit(record)
|
90
|
+
forwarder.emit(record)
|
91
|
+
expect(forwarder.emit(record)).to be(true)
|
92
|
+
end
|
93
|
+
end
|
76
94
|
end
|
77
95
|
|
78
96
|
describe '#pickup_server' do
|
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.2.
|
4
|
+
version: 0.2.22
|
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: 2014-12-
|
15
|
+
date: 2014-12-15 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rest-client
|
@@ -474,6 +474,7 @@ files:
|
|
474
474
|
- lib/flydata/compatibility_check.rb
|
475
475
|
- lib/flydata/credentials.rb
|
476
476
|
- lib/flydata/cron.rb
|
477
|
+
- lib/flydata/fluent-plugins/idle_event_detector.rb
|
477
478
|
- lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb
|
478
479
|
- lib/flydata/fluent-plugins/mysql/alter_table_query_handler.rb
|
479
480
|
- lib/flydata/fluent-plugins/mysql/binlog_position.rb
|
@@ -509,6 +510,7 @@ files:
|
|
509
510
|
- spec/flydata/command/sender_spec.rb
|
510
511
|
- spec/flydata/command/sync_spec.rb
|
511
512
|
- spec/flydata/compatibility_check_spec.rb
|
513
|
+
- spec/flydata/fluent-plugins/idle_event_detector_spec.rb
|
512
514
|
- spec/flydata/fluent-plugins/in_mysql_binlog_flydata_spec.rb
|
513
515
|
- spec/flydata/fluent-plugins/mysql/alter_table_query_handler_spec.rb
|
514
516
|
- spec/flydata/fluent-plugins/mysql/binlog_position_spec.rb
|
@@ -543,7 +545,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
543
545
|
version: '0'
|
544
546
|
requirements: []
|
545
547
|
rubyforge_project:
|
546
|
-
rubygems_version: 2.
|
548
|
+
rubygems_version: 2.0.14
|
547
549
|
signing_key:
|
548
550
|
specification_version: 4
|
549
551
|
summary: FlyData Agent
|