pubnub 3.3.0.2 → 3.3.0.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of pubnub might be problematic. Click here for more details.

Files changed (3) hide show
  1. data/lib/pubnub.rb +87 -37
  2. data/lib/pubnub_request.rb +21 -3
  3. metadata +4 -3
data/lib/pubnub.rb CHANGED
@@ -28,6 +28,17 @@ require 'active_support/core_ext/object/blank'
28
28
 
29
29
  class Pubnub
30
30
 
31
+ SUCCESS_RESPONSE = 200
32
+
33
+ TIMEOUT_BAD_RESPONSE_CODE = 1
34
+ TIMEOUT_BAD_JSON_RESPONSE = 0.5
35
+ TIMEOUT_GENERAL_ERROR = 1
36
+ TIMEOUT_SUBSCRIBE = 310
37
+ TIMEOUT_NON_SUBSCRIBE = 5
38
+
39
+ PUBNUB_LOGGER = Logger.new("/tmp/pubnubError.log")
40
+ PUBNUB_LOGGER.level = Logger::DEBUG
41
+
31
42
  class PresenceError < RuntimeError;
32
43
  end
33
44
  class PublishError < RuntimeError;
@@ -39,10 +50,7 @@ class Pubnub
39
50
 
40
51
  attr_accessor :publish_key, :subscribe_key, :secret_key, :cipher_key, :ssl, :channel, :origin, :session_uuid
41
52
 
42
-
43
- #ORIGINS = %w(newcloud-virginia.pubnub.com newcloud-california.pubnub.com newcloud-ireland.pubnub.com newcloud-tokyo.pubnub.com)
44
53
  ORIGIN_HOST = 'pubsub.pubnub.com'
45
- #ORIGIN_HOST = 'newcloud-california.pubnub.com'
46
54
  #ORIGIN_HOST = 'test.pubnub.com'
47
55
 
48
56
  def initialize(*args)
@@ -85,6 +93,7 @@ class Pubnub
85
93
  #TODO: refactor into initializer code on request instantiation
86
94
 
87
95
  publish_request.ssl = @ssl
96
+ publish_request.set_origin(options)
88
97
  publish_request.set_channel(options)
89
98
  publish_request.set_callback(options)
90
99
  publish_request.set_cipher_key(options, self.cipher_key)
@@ -109,6 +118,7 @@ class Pubnub
109
118
  #TODO: refactor into initializer code on request instantiation
110
119
 
111
120
  subscribe_request.ssl = @ssl
121
+ subscribe_request.set_origin(options)
112
122
  subscribe_request.set_channel(options)
113
123
  subscribe_request.set_callback(options)
114
124
  subscribe_request.set_cipher_key(options, self.cipher_key) unless subscribe_request.operation == "presence"
@@ -267,51 +277,25 @@ class Pubnub
267
277
  end
268
278
 
269
279
  private
270
-
280
+
271
281
  def _request(request, is_reactor_running = false)
272
282
  request.format_url!
273
- #puts("- Fetching #{request.url}")
274
283
  Thread.new{
275
284
  begin
276
285
 
277
- conn = EM::HttpRequest.new(request.url, :inactivity_timeout => 310)#client times out in 310s unless the server returns or timeout first
286
+ operation_timeout = %w(subscribe presence).include?(request.operation) ? TIMEOUT_SUBSCRIBE : TIMEOUT_NON_SUBSCRIBE
287
+ conn = EM::HttpRequest.new(request.url, :inactivity_timeout => operation_timeout) #client times out in 310s unless the server returns or timeout first
278
288
  req = conn.get()
279
289
 
280
290
  req.errback{
281
- if req.response.blank?
282
- puts("#{Time.now}: Reconnecting from timeout.")
283
-
284
- EM::Timer.new(1) do
285
- _request(request, is_reactor_running)
286
- end
287
- else
288
- error_message = "Unknown Error: #{req.response.to_s}"
289
- puts(error_message)
290
- request.callback.call([0, error_message])
291
-
292
- EM.stop unless is_reactor_running
293
- end
291
+ logAndRetryGeneralError(is_reactor_running, req, request)
294
292
  }
295
293
 
296
294
  req.callback {
297
- request.package_response!(req.response)
298
- cycle = request.callback.call(request.response)
299
-
300
- only_success_status_is_acceptable = 200
301
-
302
- if (req.response_header.http_status.to_i != only_success_status_is_acceptable)
303
-
304
- error_message = "Server Error, status: #{req.response_header.http_status}, extended info: #{req.response}"
305
- puts(error_message)
306
- EM.stop unless is_reactor_running
295
+ if checkForBadJSON(req) == true
296
+ logAndRetryBadJSON(is_reactor_running, req, request)
307
297
  else
308
-
309
- if %w(subscribe presence).include?(request.operation) && (cycle != false || request.first_request?)
310
- _request(request, is_reactor_running)
311
- else
312
- EM.stop unless is_reactor_running
313
- end
314
-
298
+ processGoodResponse(is_reactor_running, req, request)
315
299
  end
316
300
  }
317
301
 
@@ -323,6 +307,72 @@ class Pubnub
323
307
  }
324
308
  end
325
309
 
310
+ def checkForBadJSON(req)
311
+ jsonError = false
312
+ begin
313
+ JSON.parse(req.response)
314
+ rescue => e
315
+ jsonError = true
316
+ end
317
+ jsonError
318
+ end
319
+
320
+ def processGoodResponse(is_reactor_running, req, request)
321
+
322
+ if (req.response_header.http_status.to_i != SUCCESS_RESPONSE)
323
+ logAndRetryBadResponseCode(is_reactor_running, req, request)
324
+ else
326
325
 
326
+ request.package_response!(req.response)
327
+ cycle = request.callback.call(request.response)
328
+
329
+ if %w(subscribe presence).include?(request.operation) && (cycle != false || request.first_request?)
330
+ _request(request, is_reactor_running)
331
+ else
332
+ EM.stop unless is_reactor_running
333
+ end
334
+ end
335
+ end
336
+
337
+ def logAndRetryGeneralError(is_reactor_running, req, request)
338
+ errMsg = "#{Time.now}: Network connectivity issue while attempting to reach #{request.url}"
339
+ logError(errMsg)
340
+ retryRequest(is_reactor_running, req, request, TIMEOUT_GENERAL_ERROR)
341
+ end
342
+
343
+ def logAndRetryBadJSON(is_reactor_running, req, request)
344
+ errMsg = "#{Time.now}: Retrying from bad JSON: #{req.response.to_s}"
345
+ logError(errMsg)
346
+ retryRequest(is_reactor_running, req, request, TIMEOUT_BAD_JSON_RESPONSE)
347
+ end
348
+
349
+ def logAndRetryBadResponseCode(is_reactor_running, req, request)
350
+ errMsg = "#{Time.now}: Retrying from bad server response code: (#{req.response_header.http_status.to_i}) #{req.response.to_s}"
351
+ logError(errMsg)
352
+ retryRequest(is_reactor_running, req, request, TIMEOUT_BAD_RESPONSE_CODE)
353
+ end
354
+
355
+ def logError(errMsg)
356
+ PUBNUB_LOGGER.debug(errMsg)
357
+ end
358
+
359
+ def retryRequest(is_reactor_running, req, request, delay)
360
+
361
+ if %w(subscribe presence).include?(request.operation)
362
+ EM::Timer.new(delay) do
363
+ _request(request, is_reactor_running)
364
+ end
365
+ else
366
+ error_msg = [0, "Request to #{request.url} failed."]
367
+
368
+ request.set_error(true)
369
+ request.callback.call(error_msg)
370
+
371
+ PUBNUB_LOGGER.debug(error_msg)
372
+
373
+ EM.stop unless is_reactor_running
374
+ end
375
+
376
+ end
327
377
 
328
- end
378
+ end
@@ -1,6 +1,6 @@
1
1
  class PubnubRequest
2
2
  attr_accessor :cipher_key, :host, :query, :response, :timetoken, :url, :operation, :callback, :publish_key, :subscribe_key, :secret_key, :channel, :jsonp, :message, :ssl, :port
3
- attr_accessor :history_limit, :history_count, :history_start, :history_end, :history_reverse, :session_uuid, :last_timetoken
3
+ attr_accessor :history_limit, :history_count, :history_start, :history_end, :history_reverse, :session_uuid, :last_timetoken, :origin, :error
4
4
 
5
5
  class RequestError < RuntimeError;
6
6
  end
@@ -40,6 +40,24 @@ class PubnubRequest
40
40
  self.channel == another.channel && self.message == another.message
41
41
  end
42
42
 
43
+ def set_error(options)
44
+ options = HashWithIndifferentAccess.new(options)
45
+
46
+ if options[:error].present?
47
+ self.error = true
48
+ end
49
+ self
50
+ end
51
+
52
+ def set_origin(options)
53
+ options = HashWithIndifferentAccess.new(options)
54
+
55
+ if options[:origin].present?
56
+ self.origin = options[:origin].to_s
57
+ self
58
+ end
59
+ end
60
+
43
61
  def set_channel(options)
44
62
  options = HashWithIndifferentAccess.new(options)
45
63
 
@@ -186,10 +204,10 @@ class PubnubRequest
186
204
  raise(Pubnub::PublishError, "Missing .operation in PubnubRequest object") if self.operation.blank?
187
205
 
188
206
  if @ssl.present?
189
- origin = 'https://' + Pubnub::ORIGIN_HOST
207
+ origin = 'https://' + (self.origin.present? ? self.origin : Pubnub::ORIGIN_HOST)
190
208
  @port = 443
191
209
  else
192
- origin = 'http://' + Pubnub::ORIGIN_HOST
210
+ origin = 'http://' + (self.origin.present? ? self.origin : Pubnub::ORIGIN_HOST)
193
211
  @port = 80
194
212
  end
195
213
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pubnub
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0.2
4
+ version: 3.3.0.5
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: 2012-11-01 00:00:00.000000000 Z
12
+ date: 2013-02-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -121,8 +121,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
121
  version: '0'
122
122
  requirements: []
123
123
  rubyforge_project:
124
- rubygems_version: 1.8.24
124
+ rubygems_version: 1.8.25
125
125
  signing_key:
126
126
  specification_version: 3
127
127
  summary: PubNub Official Ruby gem
128
128
  test_files: []
129
+ has_rdoc: