firering 1.0.1 → 1.0.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.
data/Rakefile CHANGED
@@ -84,6 +84,7 @@ end
84
84
  #
85
85
  #############################################################################
86
86
 
87
+ desc "release gem"
87
88
  task :release => :build do
88
89
  unless `git branch` =~ /^\* master$/
89
90
  puts "You must be on the master branch to release!"
data/bin/campf-notify CHANGED
@@ -12,7 +12,7 @@ if subdomain.to_s =~ /^\s*$/ || token.to_s =~ /^\s*$/ || room_name.to_s =~ /^\s*
12
12
  puts "Icon path #{icon_path} is incorrect" unless icon_path && File.exists?(icon_path)
13
13
  puts "Room name #{room_name} is missing" unless room_name =~ /\S/
14
14
  puts
15
- puts "The following environment variables are needed: "
15
+ puts "The following environment variables will be used: "
16
16
  puts
17
17
  puts "CAMPFIRE_SUBDOMAIN: #{subdomain || 'missing!'}"
18
18
  puts "CAMPFIRE_TOKEN: #{token || 'missing!'}"
data/firering.gemspec CHANGED
@@ -4,8 +4,8 @@ Gem::Specification.new do |s|
4
4
  s.rubygems_version = '1.3.5'
5
5
 
6
6
  s.name = 'firering'
7
- s.version = '1.0.1'
8
- s.date = '2010-08-16'
7
+ s.version = '1.0.2'
8
+ s.date = '2010-10-01'
9
9
  s.rubyforge_project = 'firering'
10
10
 
11
11
  s.summary = "Campfire API interface powered by EventMachine and Yajl."
@@ -12,8 +12,10 @@ module Firering
12
12
  attr_accessor :token
13
13
  attr_accessor :login
14
14
 
15
+ attr_reader :performed_retries
16
+
15
17
  def initialize(host, streaming_host = "https://streaming.campfirenow.com")
16
- @retry_delay, @redirects, @max_retries = 2, 1, 2
18
+ @retry_delay, @redirects, @max_retries, @performed_retries = 2, 1, 2, 0
17
19
  self.host, self.streaming_host = host, streaming_host
18
20
  yield self if block_given?
19
21
  end
@@ -30,6 +32,10 @@ module Firering
30
32
  @streaming_host = Addressable::URI.parse(host)
31
33
  end
32
34
 
35
+ def subdomain
36
+ host.host.split(".").first
37
+ end
38
+
33
39
  def auth_headers
34
40
  token ? {'authorization' => [token, "X"] } : {'authorization' => [login, password] }
35
41
  end
@@ -56,7 +62,7 @@ module Firering
56
62
  end
57
63
 
58
64
  http.callback {
59
- @performed_retries = 0
65
+ reset_retries_counter
60
66
  if callback
61
67
  data = Yajl::Parser.parse(http.response, :symbolize_keys => true) rescue Hash.new
62
68
  callback.call(data, http)
@@ -82,7 +88,15 @@ module Firering
82
88
  logger.info("performing streaming request to #{uri.to_s}")
83
89
  http = EventMachine::HttpRequest.new(uri).get(parameters)
84
90
 
85
- http.stream { |chunk| parser << chunk; @performed_retries= 0 }
91
+ http.stream do |chunk|
92
+ begin
93
+ parser << chunk; reset_retries_counter
94
+ rescue Yajl::ParseError
95
+ perform_retry(http) do
96
+ stream(room_id, &callback)
97
+ end
98
+ end
99
+ end
86
100
 
87
101
  # Campfire servers will try to hold the streaming connections open indefinitely.
88
102
  # However, API clients must be able to handle occasional timeouts or
@@ -97,19 +111,42 @@ module Firering
97
111
  http
98
112
  end
99
113
 
114
+ def max_retries_reached?
115
+ @performed_retries && @performed_retries >= @max_retries
116
+ end
117
+
100
118
  def perform_retry(http, &callback)
101
- if EventMachine.reactor_running? && (@performed_retries.nil? || @performed_retries < @max_retries)
102
- logger.error("http error #{http.error}. Trying again in #{retry_delay} seconds...")
103
- EventMachine::add_timer(retry_delay) do
104
- @performed_retries = (@performed_retries || 0) + 1
105
- logger.info("Reconnecting...")
106
- callback.call
119
+ if EventMachine.reactor_running?
120
+
121
+ if max_retries_reached?
122
+ logger.error("Firering performed #{performed_retries} but did not get any answer. Increase Firering::Connection.max_retries or check your internet connection.")
123
+ raise Firering::Connection::HTTPError.new(http)
124
+ else
125
+ logger.error("http error #{http.error}. Trying again in #{retry_delay} seconds...")
126
+
127
+ EventMachine::add_timer(retry_delay) do
128
+ logger.info("Reconnecting...")
129
+ increase_retries_counter
130
+ callback.call
131
+ end
107
132
  end
133
+
108
134
  else
109
135
  logger.error("The event machine loop is not running")
110
136
  raise Firering::Connection::HTTPError.new(http)
111
137
  end
112
138
  end
139
+ private :perform_retry
140
+
141
+ def reset_retries_counter
142
+ @performed_retries = 0
143
+ end
144
+ private :reset_retries_counter
145
+
146
+ def increase_retries_counter
147
+ @performed_retries = (@performed_retries || 0) + 1
148
+ end
149
+ private :increase_retries_counter
113
150
 
114
151
  class HTTPError < RuntimeError
115
152
  attr_reader :http
data/lib/firering.rb CHANGED
@@ -5,7 +5,7 @@ require 'yajl'
5
5
  require 'em-http'
6
6
 
7
7
  module Firering
8
- VERSION = '1.0.1'
8
+ VERSION = '1.0.2'
9
9
 
10
10
  class Error < StandardError; end
11
11
 
@@ -16,10 +16,46 @@ describe Firering::Connection do
16
16
  conn.stream(304355) do |message|
17
17
  message.should be_an_instance_of(Firering::Message)
18
18
  end
19
+
19
20
  EM.add_timer(1) do
20
21
  EM.stop
21
22
  end
22
23
  }
23
24
  end
24
25
 
26
+ it "performs connection retries if the connection drops" do
27
+ conn.retry_delay = 1
28
+ make_fixture_server_fail_times(conn.max_retries)
29
+ messages = []
30
+
31
+ EM.run {
32
+ conn.stream(304355) do |message|
33
+ messages << message
34
+ end
35
+ EM.add_timer(conn.max_retries * conn.retry_delay + 1) do
36
+ EM.stop
37
+ end
38
+ }
39
+
40
+ messages.should_not be_empty
41
+ end
42
+
43
+ it "raises an exception if the connection drops and performed enough retries" do
44
+ conn.retry_delay = 1
45
+ make_fixture_server_fail_times(conn.max_retries + 1)
46
+ messages = []
47
+
48
+ begin
49
+ EM.run {
50
+ conn.stream(304355) { |message| messages << message }
51
+
52
+ EM.add_timer(conn.max_retries * conn.retry_delay + 1) { EM.stop }
53
+ }
54
+ rescue Firering::Connection::HTTPError
55
+ ensure
56
+ EM.stop if EventMachine.reactor_running?
57
+ end
58
+
59
+ messages.should be_empty
60
+ end
25
61
  end
@@ -5,21 +5,72 @@ class MyLogger < Logger
5
5
  end
6
6
 
7
7
  class FixtureServer < Struct.new(:logger)
8
+
9
+ def initialize(*args)
10
+ super
11
+ @fails = 0
12
+ end
13
+
8
14
  def call(env)
9
15
  req = Rack::Request.new(env)
10
16
  res = Rack::Response.new
11
- res.write read_fixture(req)
17
+
18
+ if adjusted_fails?(req)
19
+ res.write("OK")
20
+ else
21
+ if @fails > 0
22
+ log_hi("I was requested to fail, fails left: #{ @fails }")
23
+ @fails -= 1
24
+ res.write("")
25
+ res.status = 404
26
+ else
27
+ log_hi("Trying to open fixture")
28
+ res.write read_fixture(req)
29
+ end
30
+ end
31
+
12
32
  res.finish
13
33
  end
14
34
 
35
+ def adjusted_fails?(req)
36
+ if req.path =~ /fail\/(\d+)/
37
+ log_hi("I was requested to fail next #{ @fails = $1.to_i } requests")
38
+ true
39
+ elsif req.path =~ /fail\/reset/
40
+ @fails = 0
41
+ log_hi("Fail count reset, next requests should not fail (unless a fixture is missing)")
42
+ true
43
+ else
44
+ false
45
+ end
46
+ end
47
+
48
+ def log(msg)
49
+ logger.info(" FIXTURES: #{msg}")
50
+ end
51
+
52
+ def log_hi(msg)
53
+ log("/" * 80) ; log(msg) ; log("/" * 80)
54
+ end
55
+
15
56
  def read_fixture(req)
16
57
  return "It Works!" if req.path == "" || req.path == "/"
17
- fixture = ([req.request_method.to_s.downcase] + req.path.split("/")).join("_").squeeze("_").gsub(/\d+/, "ID")
18
- path = File.expand_path(File.join(File.dirname(__FILE__), "json", fixture))
19
- logger.info("opening fixture: #{path}, #{File.file?(path)}")
20
- output = File.file?(path) ? File.read(path) : "FIXTURE NOT FOUND #{path}"
21
- logger.info("\n\n#{output}\n")
22
- output
58
+
59
+ path = fixture_path(req)
60
+
61
+ if File.file?(path)
62
+ log("Fixture found: #{path}")
63
+ File.read(path).tap { |output| logger.info("\n\n#{output}\n") }
64
+ else
65
+ log("Fixture not found: #{path}")
66
+ "FIXTURE NOT FOUND #{path}"
67
+ end
68
+ end
69
+
70
+ def fixture_path(req)
71
+ name_parts = [req.request_method.to_s.downcase] + req.path.split("/")
72
+ name = name_parts.join("_").squeeze("_").gsub(/\d+/, "ID")
73
+ File.expand_path(File.join(File.dirname(__FILE__), "json", name))
23
74
  end
24
75
  end
25
76
 
@@ -56,3 +107,11 @@ def start_fixtures_server(port)
56
107
 
57
108
  pid
58
109
  end
110
+
111
+ def make_fixture_server_fail_times(times)
112
+ open(URI("http://localhost:#{$specs_port}/fail/#{times}"))
113
+ end
114
+
115
+ def reset_fixture_server_fails
116
+ make_fixture_server_fail_times("reset")
117
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: firering
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 1
10
- version: 1.0.1
9
+ - 2
10
+ version: 1.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Emmanuel Oga
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-16 00:00:00 -03:00
18
+ date: 2010-10-01 00:00:00 -03:00
19
19
  default_executable: campf-notify
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency