rapns 2.0.4 → 2.0.5.rc1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 2.0.5.rc1 (Oct 5, 2012) ##
2
+ * Release db connections back into the pool after use (#72).
3
+ * Continue to start daemon if a connection cannot be made during startup (#62) (@mattconnolly).
4
+
1
5
  ## 2.0.4 (Aug 6, 2012) ##
2
6
  * Don't exit when there aren't any Rapns::App instances, just warn (#55).
3
7
 
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [![Build Status](https://secure.travis-ci.org/ileitch/rapns.png)](http://travis-ci.org/ileitch/rapns)
1
+ [![Build Status](https://secure.travis-ci.org/ileitch/rapns.png?branch=master)](http://travis-ci.org/ileitch/rapns)
2
2
 
3
3
  # Features
4
4
 
@@ -164,4 +164,5 @@ Thank you to the following wonderful people for contributing to rapns:
164
164
  * [@tompesman](https://github.com/tompesman)
165
165
  * [@EpicDraws](https://github.com/EpicDraws)
166
166
  * [@dei79](https://github.com/dei79)
167
- * [@adorr](https://github.com/adorr)
167
+ * [@adorr](https://github.com/adorr)
168
+ * [@mattconnolly](https://github.com/mattconnolly)
@@ -0,0 +1,31 @@
1
+ # postgresql is the default if no ADAPTER environment variable is set when running specs.
2
+
3
+ postgresql:
4
+ adapter: postgresql
5
+ database: rapns_test
6
+ host: localhost
7
+ username: postgres
8
+ password: ""
9
+
10
+ jdbcpostgresql:
11
+ adapter: jdbcpostgresql
12
+ database: rapns_test
13
+ host: localhost
14
+ username: postgres
15
+ password: ""
16
+
17
+ mysql:
18
+ adapter: mysql
19
+ database: rapns_test
20
+ host: localhost
21
+ username: rapns_test
22
+ password: ""
23
+ encoding: utf8
24
+
25
+ mysql2:
26
+ adapter: mysql
27
+ database: rapns_test
28
+ host: localhost
29
+ username: rapns_test
30
+ password: ""
31
+ encoding: utf8
@@ -42,8 +42,12 @@ module Rapns
42
42
  feedback_host, feedback_port = HOSTS[app.environment.to_sym][:feedback]
43
43
  feedback_poll = Rapns::Daemon.config.feedback_poll
44
44
  runner = AppRunner.new(app, push_host, push_port, feedback_host, feedback_port, feedback_poll)
45
- runner.start
46
- @all[app.key] = runner
45
+ begin
46
+ runner.start
47
+ @all[app.key] = runner
48
+ rescue
49
+ Rapns::Daemon.logger.info("[App:#{app.key}] failed to start. No notifications will be sent.")
50
+ end
47
51
  end
48
52
  end
49
53
 
@@ -72,11 +76,19 @@ module Rapns
72
76
  @handlers = []
73
77
  end
74
78
 
75
- def start
76
- @feedback_receiver = FeedbackReceiver.new(@app.key, @feedback_host, @feedback_port, @feedback_poll, @app.certificate, @app.password)
77
- @feedback_receiver.start
78
79
 
79
- @app.connections.times { @handlers << start_handler }
80
+ def start
81
+ begin
82
+ @feedback_receiver = FeedbackReceiver.new(@app.key, @feedback_host, @feedback_port, @feedback_poll, @app.certificate, @app.password)
83
+ @feedback_receiver.start
84
+
85
+ @app.connections.times { @handlers << start_handler }
86
+ rescue OpenSSL::SSL::SSLError
87
+ # these errors mean that a connection is not possible, raise back to caller
88
+ raise
89
+ rescue StandardError => e
90
+ Rapns::Daemon.logger.error(e)
91
+ end
80
92
  end
81
93
 
82
94
  def deliver(notification)
@@ -105,6 +105,9 @@ module Rapns
105
105
  ssl_socket.connect
106
106
  Rapns::Daemon.logger.info("[#{@name}] Connected to #{@host}:#{@port}")
107
107
  [tcp_socket, ssl_socket]
108
+ rescue StandardError => e
109
+ Rapns::Daemon.logger.error("[#{@name}] Error connecting to #{@host}:#{@port} : #{e}")
110
+ raise
108
111
  end
109
112
  end
110
113
  end
@@ -12,7 +12,9 @@ module Rapns
12
12
 
13
13
  def with_database_reconnect_and_retry
14
14
  begin
15
- yield
15
+ ActiveRecord::Base.connection_pool.with_connection do
16
+ yield
17
+ end
16
18
  rescue *ADAPTER_ERRORS => e
17
19
  Rapns::Daemon.logger.error(e)
18
20
  database_connection_lost
@@ -2,11 +2,12 @@ module Rapns
2
2
  module Daemon
3
3
  class FeedbackReceiver
4
4
  include InterruptibleSleep
5
+ include DatabaseReconnectable
5
6
 
6
7
  FEEDBACK_TUPLE_BYTES = 38
7
8
 
8
- def initialize(app, host, port, poll, certificate, password)
9
- @app = app
9
+ def initialize(name, host, port, poll, certificate, password)
10
+ @name = name
10
11
  @host = host
11
12
  @port = port
12
13
  @poll = poll
@@ -17,8 +18,17 @@ module Rapns
17
18
  def start
18
19
  @thread = Thread.new do
19
20
  loop do
20
- break if @stop
21
- check_for_feedback
21
+ begin
22
+ break if @stop
23
+ check_for_feedback
24
+ rescue OpenSSL::SSL::SSLError
25
+ # stop the thread if there is an SSL error. Other errors might be recoverable,
26
+ # and retrying later might make sense (for example, a network outage)
27
+ @stop = true
28
+ break
29
+ rescue
30
+ # error will be logged in check_for_feedback
31
+ end
22
32
  interruptible_sleep @poll
23
33
  end
24
34
  end
@@ -33,7 +43,7 @@ module Rapns
33
43
  def check_for_feedback
34
44
  connection = nil
35
45
  begin
36
- connection = Connection.new("FeedbackReceiver:#{@app}", @host, @port, @certificate, @password)
46
+ connection = Connection.new("FeedbackReceiver:#{@name}", @host, @port, @certificate, @password)
37
47
  connection.connect
38
48
 
39
49
  while tuple = connection.read(FEEDBACK_TUPLE_BYTES)
@@ -42,6 +52,7 @@ module Rapns
42
52
  end
43
53
  rescue StandardError => e
44
54
  Rapns::Daemon.logger.error(e)
55
+ raise
45
56
  ensure
46
57
  connection.close if connection
47
58
  end
@@ -56,8 +67,10 @@ module Rapns
56
67
 
57
68
  def create_feedback(failed_at, device_token)
58
69
  formatted_failed_at = failed_at.strftime("%Y-%m-%d %H:%M:%S UTC")
59
- Rapns::Daemon.logger.info("[FeedbackReceiver:#{@app}] Delivery failed at #{formatted_failed_at} for #{device_token}")
60
- Rapns::Feedback.create!(:failed_at => failed_at, :device_token => device_token, :app => @app)
70
+ with_database_reconnect_and_retry do
71
+ Rapns::Daemon.logger.info("[FeedbackReceiver:#{@name}] Delivery failed at #{formatted_failed_at} for #{device_token}")
72
+ Rapns::Feedback.create!(:failed_at => failed_at, :device_token => device_token, :app => @name)
73
+ end
61
74
  end
62
75
  end
63
76
  end
data/lib/rapns/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rapns
2
- VERSION = '2.0.4'
2
+ VERSION = '2.0.5.rc1'
3
3
  end
@@ -110,7 +110,7 @@ describe Rapns::Daemon::Connection do
110
110
  it "ignores IOError when the socket is already closed" do
111
111
  tcp_socket.stub(:close).and_raise(IOError)
112
112
  connection.connect
113
- expect { connection.close }.should_not raise_error(IOError)
113
+ expect { connection.close }.to_not raise_error(IOError)
114
114
  end
115
115
  end
116
116
 
@@ -66,7 +66,7 @@ describe Rapns::Daemon::FeedbackReceiver, 'check_for_feedback' do
66
66
  error = StandardError.new('bork!')
67
67
  connection.stub(:read).and_raise(error)
68
68
  Rapns::Daemon.logger.should_receive(:error).with(error)
69
- receiever.check_for_feedback
69
+ lambda { receiever.check_for_feedback }.should raise_error
70
70
  end
71
71
 
72
72
  it 'sleeps for the feedback poll period' do
@@ -43,7 +43,7 @@ end
43
43
 
44
44
  describe Rapns::Notification, "when assigning the attributes for the device" do
45
45
  it "should raise an ArgumentError if something other than a Hash is assigned" do
46
- expect { Rapns::Notification.new(:attributes_for_device => Array.new) }.should
46
+ expect { Rapns::Notification.new(:attributes_for_device => Array.new) }.to \
47
47
  raise_error(ArgumentError, "attributes_for_device must be a Hash")
48
48
  end
49
49
 
data/spec/spec_helper.rb CHANGED
@@ -10,37 +10,37 @@ rescue LoadError
10
10
  end
11
11
 
12
12
  require 'active_record'
13
- adapters = ['mysql', 'mysql2', 'postgresql', 'jdbcpostgresql']
14
13
 
15
14
  jruby = defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
16
15
 
17
- $adapter = if ENV['ADAPTER']
18
- ENV['ADAPTER']
19
- elsif jruby
20
- 'jdbcpostgresql'
21
- else
22
- 'postgresql'
16
+ $adapter = ENV['ADAPTER'] ||
17
+ if jruby
18
+ 'jdbcpostgresql'
19
+ else
20
+ 'postgresql'
21
+ end
22
+
23
+ DATABASE_CONFIG = YAML.load_file(File.expand_path("../config/database.yml", File.dirname(__FILE__)))
24
+ db_config = DATABASE_CONFIG[$adapter]
25
+
26
+ if db_config.nil?
27
+ puts "No such adapter '#{$adapter}'. Valid adapters are #{DATABASE_CONFIG.keys.join(', ')}."
28
+ exit 1
23
29
  end
24
30
 
25
31
  if jruby
26
32
  if ENV['TRAVIS']
27
- username = 'postgres'
33
+ db_config['username'] = 'postgres'
28
34
  else
29
35
  require 'etc'
30
- username = Etc.getlogin
36
+ db_config['username'] = Etc.getlogin
31
37
  end
32
- else
33
- username = nil
34
- end
35
-
36
- if !adapters.include?($adapter)
37
- puts "No such adapter '#{$adapter}'. Valid adapters are #{adapters.join(', ')}."
38
- exit 1
39
38
  end
40
39
 
41
40
  puts "Using #{$adapter} adapter."
42
41
 
43
- ActiveRecord::Base.establish_connection('username' => username, 'adapter' => $adapter, 'database' => 'rapns_test')
42
+ ActiveRecord::Base.establish_connection(db_config)
43
+
44
44
  require 'generators/templates/create_rapns_notifications'
45
45
  require 'generators/templates/create_rapns_feedback'
46
46
  require 'generators/templates/add_alert_is_json_to_rapns_notifications'
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rapns
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.4
5
- prerelease:
4
+ version: 2.0.5.rc1
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Ian Leitch
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-07 00:00:00.000000000 Z
12
+ date: 2012-10-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: multi_json
@@ -35,6 +35,9 @@ executables:
35
35
  extensions: []
36
36
  extra_rdoc_files: []
37
37
  files:
38
+ - CHANGELOG.md
39
+ - LICENSE
40
+ - README.md
38
41
  - lib/generators/rapns_generator.rb
39
42
  - lib/generators/templates/add_alert_is_json_to_rapns_notifications.rb
40
43
  - lib/generators/templates/add_app_to_rapns.rb
@@ -66,9 +69,7 @@ files:
66
69
  - lib/rapns/patches/rails/3.1.0/postgresql_adapter.rb
67
70
  - lib/rapns/patches/rails/3.1.1/postgresql_adapter.rb
68
71
  - lib/rapns/version.rb
69
- - README.md
70
- - CHANGELOG.md
71
- - LICENSE
72
+ - config/database.yml
72
73
  - spec/rapns/daemon/app_runner_spec.rb
73
74
  - spec/rapns/daemon/connection_spec.rb
74
75
  - spec/rapns/daemon/database_reconnectable_spec.rb
@@ -100,9 +101,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
100
101
  required_rubygems_version: !ruby/object:Gem::Requirement
101
102
  none: false
102
103
  requirements:
103
- - - ! '>='
104
+ - - ! '>'
104
105
  - !ruby/object:Gem::Version
105
- version: '0'
106
+ version: 1.3.1
106
107
  requirements: []
107
108
  rubyforge_project:
108
109
  rubygems_version: 1.8.23
@@ -110,6 +111,7 @@ signing_key:
110
111
  specification_version: 3
111
112
  summary: Easy to use, full featured APNs daemon for Rails 3
112
113
  test_files:
114
+ - config/database.yml
113
115
  - spec/rapns/daemon/app_runner_spec.rb
114
116
  - spec/rapns/daemon/connection_spec.rb
115
117
  - spec/rapns/daemon/database_reconnectable_spec.rb