rapns 2.0.4 → 2.0.5.rc1
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/CHANGELOG.md +4 -0
- data/README.md +3 -2
- data/config/database.yml +31 -0
- data/lib/rapns/daemon/app_runner.rb +18 -6
- data/lib/rapns/daemon/connection.rb +3 -0
- data/lib/rapns/daemon/database_reconnectable.rb +3 -1
- data/lib/rapns/daemon/feedback_receiver.rb +20 -7
- data/lib/rapns/version.rb +1 -1
- data/spec/rapns/daemon/connection_spec.rb +1 -1
- data/spec/rapns/daemon/feedback_receiver_spec.rb +1 -1
- data/spec/rapns/notification_spec.rb +1 -1
- data/spec/spec_helper.rb +17 -17
- metadata +10 -8
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
|
-
[](http://travis-ci.org/ileitch/rapns)
|
1
|
+
[](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)
|
data/config/database.yml
ADDED
@@ -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
|
-
|
46
|
-
|
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
|
-
|
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
|
@@ -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(
|
9
|
-
@
|
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
|
-
|
21
|
-
|
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:#{@
|
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
|
-
|
60
|
-
|
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
@@ -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 }.
|
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) }.
|
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 =
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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(
|
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.
|
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-
|
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
|
-
-
|
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:
|
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
|