instrumental_agent 0.8.1 → 0.8.2

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.
@@ -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