instrumental_agent 0.8.1 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,6 +3,7 @@ require 'instrumental/version'
3
3
  require 'logger'
4
4
  require 'thread'
5
5
  require 'socket'
6
+ require 'timeout'
6
7
 
7
8
  # Sets up a connection to the collector.
8
9
  #
@@ -12,8 +13,9 @@ module Instrumental
12
13
  BACKOFF = 2.0
13
14
  MAX_RECONNECT_DELAY = 15
14
15
  MAX_BUFFER = 5000
16
+ REPLY_TIMEOUT = 10
15
17
 
16
- attr_accessor :host, :port, :synchronous
18
+ attr_accessor :host, :port, :synchronous, :queue
17
19
  attr_reader :connection, :enabled
18
20
 
19
21
  def self.logger=(l)
@@ -21,7 +23,7 @@ module Instrumental
21
23
  end
22
24
 
23
25
  def self.logger
24
- if !@logger
26
+ if !@logger
25
27
  @logger = Logger.new(STDERR)
26
28
  @logger.level = Logger::WARN
27
29
  end
@@ -240,14 +242,24 @@ module Instrumental
240
242
  end
241
243
  end
242
244
 
245
+ def send_with_reply_timeout(message)
246
+ @socket.puts message
247
+ Timeout.timeout(REPLY_TIMEOUT) do
248
+ response = @socket.gets
249
+ if response.to_s.chomp != "ok"
250
+ raise "Bad Response #{response.inspect} to #{message.inspect}"
251
+ end
252
+ end
253
+ end
254
+
243
255
  def connection_worker
244
256
  command_and_args = nil
245
257
  logger.info "connecting to collector"
246
258
  @socket = TCPSocket.new(host, port)
247
- @failures = 0
248
259
  logger.info "connected to collector at #{host}:#{port}"
249
- @socket.puts "hello version #{Instrumental::VERSION} test_mode #{@test_mode}"
250
- @socket.puts "authenticate #{@api_key}"
260
+ send_with_reply_timeout "hello version #{Instrumental::VERSION} test_mode #{@test_mode}"
261
+ send_with_reply_timeout "authenticate #{@api_key}"
262
+ @failures = 0
251
263
  loop do
252
264
  command_and_args = @queue.pop
253
265
  test_connection
@@ -272,7 +284,7 @@ module Instrumental
272
284
  disconnect
273
285
  @failures += 1
274
286
  delay = [(@failures - 1) ** BACKOFF, MAX_RECONNECT_DELAY].min
275
- logger.info "disconnected, reconnect in #{delay}..."
287
+ logger.error "disconnected, #{@failures} failures in a row, reconnect in #{delay}..."
276
288
  sleep delay
277
289
  retry
278
290
  ensure
@@ -1,3 +1,3 @@
1
1
  module Instrumental
2
- VERSION = "0.8.1"
2
+ VERSION = '0.8.2'
3
3
  end
data/spec/agent_spec.rb CHANGED
@@ -225,15 +225,6 @@ describe Instrumental::Agent, "enabled" do
225
225
  end
226
226
  end
227
227
 
228
- it "should automatically reconnect" do
229
- wait
230
- @server.disconnect_all
231
- @agent.increment('reconnect_test', 1, 1234) # triggers reconnect
232
- wait
233
- @server.connect_count.should == 2
234
- @server.commands.last.should == "increment reconnect_test 1 1234"
235
- end
236
-
237
228
  it "should automatically reconnect when forked" do
238
229
  wait
239
230
  @agent.increment('fork_reconnect_test', 1, 2)
@@ -320,6 +311,50 @@ describe Instrumental::Agent, "enabled" do
320
311
  end
321
312
  end
322
313
 
314
+ describe Instrumental::Agent, "connection problems" do
315
+ after do
316
+ @server.stop
317
+ end
318
+
319
+ it "should automatically reconnect on disconnect" do
320
+ @server = TestServer.new
321
+ @agent = Instrumental::Agent.new('test_token', :collector => @server.host_and_port, :synchronous => false)
322
+ wait
323
+ @server.disconnect_all
324
+ @agent.increment('reconnect_test', 1, 1234) # triggers reconnect
325
+ wait
326
+ @server.connect_count.should == 2
327
+ @server.commands.last.should == "increment reconnect_test 1 1234"
328
+ end
329
+
330
+ it "should buffer commands when server is down" do
331
+ @server = TestServer.new(:listen => false)
332
+ @agent = Instrumental::Agent.new('test_token', :collector => @server.host_and_port, :synchronous => false)
333
+ wait
334
+ @agent.increment('reconnect_test', 1, 1234)
335
+ wait
336
+ @agent.queue.pop(true).should == "increment reconnect_test 1 1234\n"
337
+ end
338
+
339
+ it "should buffer commands when server is not responsive" do
340
+ @server = TestServer.new(:response => false)
341
+ @agent = Instrumental::Agent.new('test_token', :collector => @server.host_and_port, :synchronous => false)
342
+ wait
343
+ @agent.increment('reconnect_test', 1, 1234)
344
+ wait
345
+ @agent.queue.pop(true).should == "increment reconnect_test 1 1234\n"
346
+ end
347
+
348
+ it "should buffer commands when authentication fails" do
349
+ @server = TestServer.new(:authenticate => false)
350
+ @agent = Instrumental::Agent.new('test_token', :collector => @server.host_and_port, :synchronous => false)
351
+ wait
352
+ @agent.increment('reconnect_test', 1, 1234)
353
+ wait
354
+ @agent.queue.pop(true).should == "increment reconnect_test 1 1234\n"
355
+ end
356
+ end
357
+
323
358
  describe Instrumental::Agent, "enabled with sync option" do
324
359
  before do
325
360
  @server = TestServer.new
data/spec/test_server.rb CHANGED
@@ -1,12 +1,19 @@
1
1
  class TestServer
2
2
  attr_accessor :host, :port, :connect_count, :commands
3
3
 
4
- def initialize
4
+ def initialize(options={})
5
+ default_options = {
6
+ :listen => true,
7
+ :authenticate => true,
8
+ :response => true,
9
+ }
10
+ @options = default_options.merge(options)
11
+
5
12
  @connect_count = 0
6
13
  @connections = []
7
14
  @commands = []
8
15
  @host = 'localhost'
9
- listen
16
+ listen if @options[:listen]
10
17
  end
11
18
 
12
19
  def listen
@@ -25,6 +32,15 @@ class TestServer
25
32
  command = socket.gets.strip
26
33
  # puts "got: #{command}"
27
34
  commands << command
35
+ if %w[hello authenticate].include?(command.split(' ')[0])
36
+ if @options[:response]
37
+ if @options[:authenticate]
38
+ socket.puts "ok"
39
+ else
40
+ socket.puts "gtfo"
41
+ end
42
+ end
43
+ end
28
44
  end
29
45
  end
30
46
  end
@@ -50,7 +66,7 @@ class TestServer
50
66
  def stop
51
67
  @stopping = true
52
68
  disconnect_all
53
- @server.close # FIXME: necessary?
69
+ @server.close if @server
54
70
  end
55
71
 
56
72
  def disconnect_all
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: instrumental_agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.8.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -12,11 +12,11 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2012-01-13 00:00:00.000000000 Z
15
+ date: 2012-01-17 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rake
19
- requirement: &70170253502220 !ruby/object:Gem::Requirement
19
+ requirement: &70348894926180 !ruby/object:Gem::Requirement
20
20
  none: false
21
21
  requirements:
22
22
  - - ! '>='
@@ -24,10 +24,10 @@ dependencies:
24
24
  version: '0'
25
25
  type: :development
26
26
  prerelease: false
27
- version_requirements: *70170253502220
27
+ version_requirements: *70348894926180
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: rspec
30
- requirement: &70170253499520 !ruby/object:Gem::Requirement
30
+ requirement: &70348894925360 !ruby/object:Gem::Requirement
31
31
  none: false
32
32
  requirements:
33
33
  - - ~>
@@ -35,10 +35,10 @@ dependencies:
35
35
  version: '2.0'
36
36
  type: :development
37
37
  prerelease: false
38
- version_requirements: *70170253499520
38
+ version_requirements: *70348894925360
39
39
  - !ruby/object:Gem::Dependency
40
40
  name: guard
41
- requirement: &70170253497560 !ruby/object:Gem::Requirement
41
+ requirement: &70348894924280 !ruby/object:Gem::Requirement
42
42
  none: false
43
43
  requirements:
44
44
  - - ! '>='
@@ -46,10 +46,10 @@ dependencies:
46
46
  version: '0'
47
47
  type: :development
48
48
  prerelease: false
49
- version_requirements: *70170253497560
49
+ version_requirements: *70348894924280
50
50
  - !ruby/object:Gem::Dependency
51
51
  name: guard-rspec
52
- requirement: &70170253518380 !ruby/object:Gem::Requirement
52
+ requirement: &70348894923220 !ruby/object:Gem::Requirement
53
53
  none: false
54
54
  requirements:
55
55
  - - ! '>='
@@ -57,10 +57,10 @@ dependencies:
57
57
  version: '0'
58
58
  type: :development
59
59
  prerelease: false
60
- version_requirements: *70170253518380
60
+ version_requirements: *70348894923220
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: growl_notify
63
- requirement: &70170253513400 !ruby/object:Gem::Requirement
63
+ requirement: &70348894922240 !ruby/object:Gem::Requirement
64
64
  none: false
65
65
  requirements:
66
66
  - - ! '>='
@@ -68,10 +68,10 @@ dependencies:
68
68
  version: '0'
69
69
  type: :development
70
70
  prerelease: false
71
- version_requirements: *70170253513400
71
+ version_requirements: *70348894922240
72
72
  - !ruby/object:Gem::Dependency
73
73
  name: rb-fsevent
74
- requirement: &70170253526840 !ruby/object:Gem::Requirement
74
+ requirement: &70348894921540 !ruby/object:Gem::Requirement
75
75
  none: false
76
76
  requirements:
77
77
  - - ! '>='
@@ -79,10 +79,10 @@ dependencies:
79
79
  version: '0'
80
80
  type: :development
81
81
  prerelease: false
82
- version_requirements: *70170253526840
82
+ version_requirements: *70348894921540
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: fuubar
85
- requirement: &70170253541560 !ruby/object:Gem::Requirement
85
+ requirement: &70348894920760 !ruby/object:Gem::Requirement
86
86
  none: false
87
87
  requirements:
88
88
  - - ! '>='
@@ -90,7 +90,7 @@ dependencies:
90
90
  version: '0'
91
91
  type: :development
92
92
  prerelease: false
93
- version_requirements: *70170253541560
93
+ version_requirements: *70348894920760
94
94
  description: Track anything.
95
95
  email:
96
96
  - support@instrumentalapp.com
@@ -126,21 +126,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
126
126
  - - ! '>='
127
127
  - !ruby/object:Gem::Version
128
128
  version: '0'
129
- segments:
130
- - 0
131
- hash: 2243868577827404388
132
129
  required_rubygems_version: !ruby/object:Gem::Requirement
133
130
  none: false
134
131
  requirements:
135
132
  - - ! '>='
136
133
  - !ruby/object:Gem::Version
137
134
  version: '0'
138
- segments:
139
- - 0
140
- hash: 2243868577827404388
141
135
  requirements: []
142
136
  rubyforge_project:
143
- rubygems_version: 1.8.10
137
+ rubygems_version: 1.8.13
144
138
  signing_key:
145
139
  specification_version: 3
146
140
  summary: Agent for reporting data to instrumentalapp.com