apple_shove 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/README.md CHANGED
@@ -2,30 +2,72 @@
2
2
 
3
3
  APN Service Provider. More powerful than a push...
4
4
 
5
- ## Installation
5
+ ## Why?
6
6
 
7
- Add this line to your application's Gemfile:
7
+ A quick look at [The Ruby Toolbox](https://www.ruby-toolbox.com/search?utf8=✓&q=apns) reveals a ton of pre-existing APNS gems. Why recreate the wheel?
8
8
 
9
- gem 'apple_shove'
9
+ We needed an APNS package for use with a many-tenant MDM platform. Specifically, we needed the ability to quickly push many notifications to devices spanning across *many* push certificates.
10
10
 
11
- And then execute:
11
+ ### What about [arthurnn/apn_sender](https://github.com/arthurnn/apn_sender)?
12
12
 
13
- $ bundle
13
+ We started here and eventually [forked](https://github.com/tboyko/apn_sender) and added MDM support. **apn_sender** keeps a persistent connection to Apple, which is great. It doesn't handle multiple certificates though, so that means we'd have to have a separate daemon process running for every single push certificate.
14
14
 
15
- Or install it yourself as:
15
+ In fact, most APNS packages were eliminated for this reason: They weren't built with multiple-certificate handling in mind, meaning something costly would have to be instantiated for each certificate.
16
16
 
17
- $ gem install apple_shove
17
+ ### What about [jeremytregunna/racoon](https://github.com/jeremytregunna/racoon)?
18
+
19
+ This gem sets out to solve multiple-certificate handling, but it fell short in two ways:
20
+
21
+ 1. It requires the compilation and usage of a fork of ZMQMachine. We don't want to have to manually compile the gem and we don't want to depend on someone keeping a fork of a project maintained.
22
+ 2. It assumes the bottleneck is in the building of the APNS message, not in the SSL connection setup/teardown with Apple. The gem instantiates many _workers_ for the activity of building the message to be pushed, but by default only runs a single _firehose_, which is responsible for connecting to Apple. We found the opposite to be true: the connection to Apple is the slowest part.
23
+
24
+ ## How does AppleShove work?
25
+
26
+ In brief, AppleShove receives push requests from a Redis queue structure. These push requests include the APNS certificate and the payload to be pushed. A single thread called the _demultiplexer_ reads from this Redis queue and also manages a pool of connection threads to Apple. When a request is received, the _demultiplexer_ sends the request to the appropriate connection thread. If the connection thread doesn't already exist, it's created first. That's it!
27
+
28
+ For you concurrency fans out there, we are using the Actor concurrency pattern via [Celluloid](https://github.com/celluloid/celluloid).
29
+
30
+ This architecture accomplishes a few things:
31
+
32
+ 1. "Caches" connections to Apple. If we've sent a notification with a particular certificate recently, we get to reuse the connection instead of having to re-establish it.
33
+ 2. Allows notifications to be sent in parallel. We aren't waiting for a series of connections and disconnections to take place before we can send notification #n.
34
+ 3. Simplifies our client implementation. Since each notification contains all of the information AppleShove needs to send it on it's way, we can request notifications via a single static method.
35
+
36
+ Willing to give it a try? Onward...
18
37
 
19
38
  ## Usage
20
39
 
40
+ ### Sending Notifications
41
+
42
+ Sending a notification request looks like this:
43
+
44
+ apns_p12 = File.read('my_cert.p12')
45
+ token = '[device token string]'
46
+ payload = { mdm: '[push magic string]' } # this can also be an app notification
47
+
48
+ AppleShove.notify(apns_p12, token, payload)
49
+
50
+ Need it to be a sandbox notification?
51
+
52
+ sandbox = true
53
+ AppleShove.notify(apns_p12, token, payload, sandbox)
54
+
55
+ ### Checking the Feedback Service
56
+
57
+ We also have a feedback mechanism in place:
58
+
59
+ tokens_array = AppleShove.feedback_tokens(apns_p12)
60
+
61
+ ### Running the Service
62
+
21
63
  # bundle exec rake -T
22
- bundle exec rake apple_shove:run
23
- bundle exec rake apple_shove:start
24
- bundle exec rake apple_shove:stop
25
- bundle exec rake apple_shove:status
26
- bundle exec rake apple_shove:stats
64
+ bundle exec rake apple_shove:run # run in the foreground
65
+ bundle exec rake apple_shove:start # start as a daemon
66
+ bundle exec rake apple_shove:stop # stop the daemon
67
+ bundle exec rake apple_shove:status # see status of daemon
68
+ bundle exec rake apple_shove:stats # stats related to daemon
27
69
 
28
- ### Optional Command Line Arguments
70
+ #### Optional Command Line Arguments
29
71
 
30
72
  log_dir: specify an absolute path if you want to log
31
73
  pid_dir: specify an absolute or relative path where the PID file
@@ -35,13 +77,29 @@ Or install it yourself as:
35
77
 
36
78
  Example usage:
37
79
 
38
- bundle exec rake apple_shove:start connection_limit=100 log_dir=log
80
+ bundle exec rake apple_shove:start connection_limit=100 log_dir=/var/log
81
+
82
+ ## Installation
83
+
84
+ Add this line to your application's Gemfile:
85
+
86
+ gem 'apple_shove'
87
+
88
+ And then execute:
89
+
90
+ $ bundle
91
+
92
+ Or install it yourself as:
93
+
94
+ $ gem install apple_shove
95
+
96
+ ## Additional Notes
39
97
 
40
- ## TCP Keep-Alives
98
+ ### TCP Keep-Alives
41
99
 
42
- Apple Shove has the ability to maintain connections to Apple for long durations of time without sending a notification. These connections will generally stay open, however, intermediate NATs and firewalls may expire and close the connection prematurely.
100
+ AppleShove has the ability to maintain connections to Apple for long durations of time without sending a notification. These connections will generally stay open, however, intermediate NATs and firewalls may expire and close the connection prematurely.
43
101
 
44
- To combat this, Apple Shove enables keep-alive on all connections to Apple. Apple Shove is not able to set the interval between keep-alives, however, as this is generally managed by the operating system. If you are aware of a relatively short NAT or firewall timer, you can either manually shorten your OS's keep-alive timer to be shorter than the timer. As this likely breaks the portability of your code, you can alternatively change the `AppleShove::CONFIG[:reconnect_timer]` to a value less than the NAT/firewall timer. This will force Apple Shove to re-establish the SSL connection after enough idle time has passed.
102
+ To combat this, AppleShove enables keep-alive on all connections to Apple. AppleShove is not able to set the interval between keep-alives however, as this is generally managed by the operating system. If you are aware of a relatively short NAT or firewall timer, you can manually shorten your OS's keep-alive timer to be shorter than the timer. As this likely breaks the portability of your code, you can alternatively change the `AppleShove::CONFIG[:reconnect_timer]` to a value less than the NAT/firewall timer. This will force AppleShove to re-establish the SSL connection after enough idle time has passed.
45
103
 
46
104
  For reference, we have observed the following keep-alive timeout values:
47
105
 
@@ -51,7 +109,7 @@ For reference, we have observed the following keep-alive timeout values:
51
109
 
52
110
  Apple also seems to send a keep-alive packet if it sees the connection as idle for 10 minutes.
53
111
 
54
- ## Gotchas
112
+ ### Gotchas
55
113
 
56
114
  Due to the TCP/IP stack, AppleShove will only know about a broken pipe to APNS after it writes two notifications to the socket. When this occurs, AppleShove will re-transmit the first as well as the second notification. Because time may have elapsed between the first and second notification writes, a non-trivial delay in the delivery of the first notification may occur.
57
115
 
data/apple_shove.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["tboyko@unwiredrevolution.com"]
11
11
  spec.description = %q{APN Service Provider. More powerful than a push...}
12
12
  spec.summary = %q{}
13
- spec.homepage = ""
13
+ spec.homepage = "https://github.com/tboyko/apple_shove"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
@@ -1,3 +1,3 @@
1
1
  module AppleShove
2
- VERSION = "1.0.1"
2
+ VERSION = "1.0.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apple_shove
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-07 00:00:00.000000000 Z
12
+ date: 2013-05-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -138,7 +138,7 @@ files:
138
138
  - spec/notification_helper.rb
139
139
  - spec/notification_queue_spec.rb
140
140
  - spec/notification_spec.rb
141
- homepage: ''
141
+ homepage: https://github.com/tboyko/apple_shove
142
142
  licenses:
143
143
  - MIT
144
144
  post_install_message:
@@ -153,7 +153,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
153
153
  version: '0'
154
154
  segments:
155
155
  - 0
156
- hash: -1646100289206665010
156
+ hash: 3074046605150142324
157
157
  required_rubygems_version: !ruby/object:Gem::Requirement
158
158
  none: false
159
159
  requirements:
@@ -162,7 +162,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
162
162
  version: '0'
163
163
  segments:
164
164
  - 0
165
- hash: -1646100289206665010
165
+ hash: 3074046605150142324
166
166
  requirements: []
167
167
  rubyforge_project:
168
168
  rubygems_version: 1.8.24