neighborparrot 0.3.1 → 0.3.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/Gemfile +4 -5
- data/Gemfile.lock +16 -0
- data/VERSION +1 -1
- data/lib/neighborparrot/callbacks.rb +20 -0
- data/lib/neighborparrot/config.rb +57 -0
- data/lib/neighborparrot/helpers/url_helpers.rb +20 -0
- data/lib/neighborparrot/open.rb +66 -0
- data/lib/neighborparrot/reactor.rb +109 -0
- data/lib/neighborparrot/send.rb +39 -22
- data/lib/neighborparrot.rb +5 -35
- data/neighborparrot.gemspec +20 -6
- data/spec/{esparrot_spec.rb → integration/neighborparrot_spec.rb} +10 -11
- data/spec/reactor_spec.rb +68 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/callbacks_spec.rb +17 -0
- metadata +52 -14
- data/lib/neighborparrot/esparrot.rb +0 -92
- data/spec/neighborparrot_spec.rb +0 -41
data/Gemfile
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
source "http://rubygems.org"
|
2
|
-
# Add dependencies required to use your gem here.
|
3
|
-
# Example:
|
4
|
-
# gem "activesupport", ">= 2.3.5"
|
5
2
|
|
6
|
-
|
7
|
-
|
3
|
+
gem 'eventmachine'
|
4
|
+
gem 'em-http-request'
|
5
|
+
gem 'em-eventsource'
|
6
|
+
|
8
7
|
group :development do
|
9
8
|
gem "rspec", "~> 2.3.0"
|
10
9
|
gem "bundler", "~> 1.0.0"
|
data/Gemfile.lock
CHANGED
@@ -1,10 +1,23 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
+
addressable (2.2.6)
|
4
5
|
diff-lcs (1.1.3)
|
6
|
+
em-eventsource (0.1.5)
|
7
|
+
em-http-request (~> 1.0.0)
|
8
|
+
eventmachine (~> 1.0.0.beta3)
|
9
|
+
em-http-request (1.0.0)
|
10
|
+
addressable (>= 2.2.3)
|
11
|
+
em-socksify
|
12
|
+
eventmachine (>= 1.0.0.beta.3)
|
13
|
+
http_parser.rb (>= 0.5.2)
|
14
|
+
em-socksify (0.1.0)
|
15
|
+
eventmachine
|
16
|
+
eventmachine (1.0.0.beta.4)
|
5
17
|
faker (1.0.1)
|
6
18
|
i18n (~> 0.4)
|
7
19
|
git (1.2.5)
|
20
|
+
http_parser.rb (0.5.3)
|
8
21
|
i18n (0.6.0)
|
9
22
|
jeweler (1.6.4)
|
10
23
|
bundler (~> 1.0)
|
@@ -26,6 +39,9 @@ PLATFORMS
|
|
26
39
|
|
27
40
|
DEPENDENCIES
|
28
41
|
bundler (~> 1.0.0)
|
42
|
+
em-eventsource
|
43
|
+
em-http-request
|
44
|
+
eventmachine
|
29
45
|
faker
|
30
46
|
jeweler (~> 1.6.4)
|
31
47
|
rcov
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.2
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Callbacks used by the client
|
2
|
+
module Neighborparrot
|
3
|
+
@@module_event_block = {}
|
4
|
+
|
5
|
+
EVENTS = %w(message error close connect success timeout)
|
6
|
+
|
7
|
+
# Callbacks helpers are auto generated
|
8
|
+
#===============================================
|
9
|
+
|
10
|
+
# Generate class helpers
|
11
|
+
EVENTS.each do |event|
|
12
|
+
clazz = class << self; self; end
|
13
|
+
clazz.send :define_method, "on_#{event}" do |&block|
|
14
|
+
@@module_event_block[event] = block
|
15
|
+
end
|
16
|
+
clazz.send :define_method, "trigger_#{event}" do |*args|
|
17
|
+
@@module_event_block[event].call *args
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# Configuration settings and methods
|
2
|
+
module Neighborparrot
|
3
|
+
|
4
|
+
# Setup the configuration options
|
5
|
+
# * :api_id => Your api ID in neighborparrot.com
|
6
|
+
# * :api_key => Your api key
|
7
|
+
# * :server => Server to connect (Only for development)
|
8
|
+
# * :dummy_tests => See neighboparrot/helpers/url_helpers
|
9
|
+
def self.configure(params={})
|
10
|
+
@@config.merge! params
|
11
|
+
end
|
12
|
+
|
13
|
+
# Return settings
|
14
|
+
def self.configuration
|
15
|
+
@@config
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
DEFAULT_SERVER = 'https://neighborparrot.net'
|
21
|
+
ASSETS_SERVER = 'https://neighborparrot.com'
|
22
|
+
DEFAULT_SEND_TIMEOUT = 5
|
23
|
+
|
24
|
+
def self.default_values
|
25
|
+
{
|
26
|
+
:server => DEFAULT_SERVER ,
|
27
|
+
:assets_server => ASSETS_SERVER,
|
28
|
+
:send_timeout => DEFAULT_SEND_TIMEOUT
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
@@config = self.default_values
|
34
|
+
|
35
|
+
# Return true if neighborparrot is in dummy connection mode
|
36
|
+
def dummy_connections?
|
37
|
+
@@config[:dummy_tests] && in_rails? && Rails.env.test?
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
# Chen mandatory parameters
|
42
|
+
# @param [Hash] parameters
|
43
|
+
# @param [Symbol] action [:send/:open]
|
44
|
+
def check_params(p, action=:send)
|
45
|
+
trigger_on_error "Channel can't be nil" if p[:channel].nil? || p[:channel].length == 0
|
46
|
+
trigger_on_error "ERROR# Neighborparrot: api_id can't be nil" if p[:api_id].nil? || p[:api_id].length == 0
|
47
|
+
if action == :send
|
48
|
+
trigger_on_error "ERROR# Neighborparrot: api_key can't be nil" if p[:api_key].nil? || p[:api_key].length == 0
|
49
|
+
end
|
50
|
+
true
|
51
|
+
end
|
52
|
+
|
53
|
+
# In rails?
|
54
|
+
def in_rails?
|
55
|
+
defined?(Rails) == 'constant'
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ActionView
|
2
|
+
module Helpers
|
3
|
+
module AssetTagHelper
|
4
|
+
|
5
|
+
NEIGHBORPARROT_JS_API = '/js/parrot.js'
|
6
|
+
NEIGHBORPARROT_JS_DUMMY_API = '/js/dummy-parrot.js'
|
7
|
+
|
8
|
+
# URL helper for the parrot js client
|
9
|
+
# If :dummy_tests is true, use a dummy parrot
|
10
|
+
# avoiding connections with the server but
|
11
|
+
# triggering onconnect
|
12
|
+
def neighborparrot_include_tag
|
13
|
+
config = Neighborparrot.configuration
|
14
|
+
parrot_js = config[:dummy_connections] ? NEIGHBORPARROT_JS_DUMMY_API : NEIGHBORPARROT_JS_API
|
15
|
+
src = "#{config[:assets_server]}#{parrot_js}"
|
16
|
+
content_tag(:script, nil, { :type => 'text/javascript', :src => src })
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'em-eventsource'
|
2
|
+
module Neighborparrot
|
3
|
+
|
4
|
+
# Open a persistent connection to the Neighbor in a new
|
5
|
+
# thread and return true if all works unless :foreground
|
6
|
+
# options is true.
|
7
|
+
# Current options to the connectio are:
|
8
|
+
#
|
9
|
+
# @param [String] channel to connect
|
10
|
+
# @param [Hash] Params for the connection. this params can be:
|
11
|
+
# * :foreground [Boolean] run the connection in the foreground
|
12
|
+
# stoping the clode flow until the connection is closed by server or
|
13
|
+
# another thread call close
|
14
|
+
# * :api_id => Your api ID in neighborparrot.com
|
15
|
+
# * :api_key => Your api key
|
16
|
+
# * :server => Server to connect (Only for development)
|
17
|
+
def open_connection(params)
|
18
|
+
params = Neighborparrot.configuration.merge params
|
19
|
+
return unless check_params params, :post
|
20
|
+
return if dummy_connections?
|
21
|
+
uri = URI.parse(params[:server])
|
22
|
+
channel = params[:channel]
|
23
|
+
url = "#{params[:server]}/open"
|
24
|
+
|
25
|
+
@source = EM::EventSource.new(url, :channel => channel )
|
26
|
+
@source.inactivity_timeout = 120
|
27
|
+
@source.message do |message|
|
28
|
+
EM.next_tick { trigger_message message }
|
29
|
+
end
|
30
|
+
@source.error do |error|
|
31
|
+
EM.next_tick { trigger_error error }
|
32
|
+
end
|
33
|
+
|
34
|
+
@source.open do
|
35
|
+
EM.next_tick { trigger_connect }
|
36
|
+
end
|
37
|
+
|
38
|
+
@source.start
|
39
|
+
end
|
40
|
+
|
41
|
+
def connected?
|
42
|
+
@source && @source.ready_state == EM::EventSource::OPEN
|
43
|
+
end
|
44
|
+
|
45
|
+
def close
|
46
|
+
return unless connected?
|
47
|
+
@source.close
|
48
|
+
end
|
49
|
+
|
50
|
+
# Static helper. Create a EM Reactor and open the connexion on it
|
51
|
+
def self.open(params={})
|
52
|
+
EM.run do
|
53
|
+
parrot = Neighborparrot::Reactor.new
|
54
|
+
parrot.on_error do |error|
|
55
|
+
puts "Error: #{error}"
|
56
|
+
EM.stop
|
57
|
+
end
|
58
|
+
parrot.on_message do |message|
|
59
|
+
puts "Received: #{message}"
|
60
|
+
end
|
61
|
+
parrot.on_connect { puts "Connected" }
|
62
|
+
|
63
|
+
parrot.open params
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
require 'em-http'
|
3
|
+
|
4
|
+
module Neighborparrot
|
5
|
+
@@class_reactor = nil
|
6
|
+
# Static a module reactor and keeping running and waiting
|
7
|
+
def self.reactor_start
|
8
|
+
if @@class_reactor.nil?
|
9
|
+
return @@class_reactor = Reactor.new
|
10
|
+
end
|
11
|
+
@@class_reactor.start
|
12
|
+
end
|
13
|
+
|
14
|
+
# Stop the module reactor
|
15
|
+
def self.reactor_stop
|
16
|
+
return unless @@class_reactor
|
17
|
+
@@class_reactor.stop
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return true if module reactor running
|
21
|
+
def self.reactor_running?
|
22
|
+
@@class_reactor && @@class_reactor.running?
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
# Reactor class
|
27
|
+
#=====================================
|
28
|
+
class Reactor
|
29
|
+
include Neighborparrot
|
30
|
+
|
31
|
+
# Start the reactor in a new thead and prepare
|
32
|
+
def initialize
|
33
|
+
reactor_start
|
34
|
+
define_event_helpers
|
35
|
+
end
|
36
|
+
|
37
|
+
# generate events helpers for instances
|
38
|
+
# This define tho methods:
|
39
|
+
# on_event(&block): Setup a block for the event
|
40
|
+
# trigger_event(*args): Trigger the event
|
41
|
+
def define_event_helpers
|
42
|
+
@event_block = {}
|
43
|
+
EVENTS.each do |event|
|
44
|
+
clazz = class << self; self; end
|
45
|
+
clazz.send :define_method, "on_#{event}" do |&block|
|
46
|
+
@event_block[event] = block
|
47
|
+
end
|
48
|
+
clazz.send :define_method, "trigger_#{event}" do |*args|
|
49
|
+
@event_block[event].call *args if @event_block[event]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Start the reactor if not running
|
56
|
+
def start
|
57
|
+
reactor_start unless running?
|
58
|
+
end
|
59
|
+
|
60
|
+
# Stop the reactor
|
61
|
+
def stop
|
62
|
+
EM.schedule { EM.stop }
|
63
|
+
end
|
64
|
+
# @return true if reactor running
|
65
|
+
def running?
|
66
|
+
EM.reactor_running?
|
67
|
+
end
|
68
|
+
|
69
|
+
# Send a message to a channel
|
70
|
+
# If empty data, refuse to send nothing
|
71
|
+
# @param [Hash] params
|
72
|
+
# * :api_id => Your api ID in neighborparrot.com
|
73
|
+
# * :api_key => Your api key
|
74
|
+
# * :server => Server to connect (Only for development)
|
75
|
+
# * :channel => The channel name
|
76
|
+
# * :data => Your payload
|
77
|
+
# @return [Boolean] true if sended
|
78
|
+
def send(params)
|
79
|
+
EM.schedule { @out_queue.push params }
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
# Open a Event Source connection with the broker
|
84
|
+
def open(params)
|
85
|
+
EM.schedule { open_connection params }
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
# Create a thread for the reactor and startit
|
90
|
+
def reactor_start
|
91
|
+
if EM.reactor_running?
|
92
|
+
return init_queue unless @out_queue
|
93
|
+
end
|
94
|
+
@em_thread = Thread.new {
|
95
|
+
EM.run { init_queue }
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
# Prepare the sent queue for send the message to the broker
|
100
|
+
# as soon as possible
|
101
|
+
def init_queue
|
102
|
+
@out_queue = EM::Queue.new
|
103
|
+
processor = proc { |msg|
|
104
|
+
send_to_broker msg
|
105
|
+
@out_queue.pop(&processor)
|
106
|
+
}
|
107
|
+
@out_queue.pop(&processor)
|
108
|
+
end
|
109
|
+
end
|
data/lib/neighborparrot/send.rb
CHANGED
@@ -1,30 +1,47 @@
|
|
1
|
+
require 'pp'
|
1
2
|
module Neighborparrot
|
2
3
|
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
# * :server => Server to connect (Only for development)
|
10
|
-
# * :channel => The channel name
|
11
|
-
# * :data => Your payload
|
12
|
-
# @return [Boolean] true if sended
|
4
|
+
# Send the message to the broker.
|
5
|
+
# Create a new reactor and run the request inside
|
6
|
+
# Any output is printed in the standard output.
|
7
|
+
# If you start a module reactor in some point in your program
|
8
|
+
# the request is scheduled in this reactor and return
|
9
|
+
# the control to your program. Module callbacks are used in this case.
|
13
10
|
def self.send(params={})
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
11
|
+
if self.reactor_running?
|
12
|
+
return @@class_reactor.send params
|
13
|
+
end
|
14
|
+
EM.run do
|
15
|
+
parrot = Neighborparrot::Reactor.new
|
16
|
+
parrot.on_error do |error|
|
17
|
+
puts "Error: #{error}"
|
18
|
+
parrot.stop
|
19
|
+
end
|
20
|
+
parrot.on_success do |resp|
|
21
|
+
puts "=> #{resp}"
|
22
|
+
parrot.stop
|
23
|
+
end
|
24
|
+
parrot.send params
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
27
|
-
|
28
|
-
|
28
|
+
private
|
29
|
+
# Send the message to the broker
|
30
|
+
def send_to_broker(params={})
|
31
|
+
params = Neighborparrot.configuration.merge params
|
32
|
+
return unless check_params params
|
33
|
+
return if params[:data].nil? || params[:data].length == 0
|
34
|
+
return if params[:dummy_connections]
|
35
|
+
url = "#{params[:server]}/send"
|
36
|
+
http = EventMachine::HttpRequest.new(url).post :body => params
|
37
|
+
http.errback{ |msg| trigger_error msg }
|
38
|
+
http.callback do
|
39
|
+
if http.response_header.status == 200
|
40
|
+
trigger_success http.response, params
|
41
|
+
else
|
42
|
+
trigger_error http.response
|
43
|
+
end
|
44
|
+
end
|
29
45
|
end
|
46
|
+
|
30
47
|
end
|
data/lib/neighborparrot.rb
CHANGED
@@ -1,38 +1,8 @@
|
|
1
|
-
require 'net/http'
|
2
|
-
require 'net/https'
|
3
1
|
require 'uri'
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
# * :api_id => Your api ID in neighborparrot.com
|
9
|
-
# * :api_key => Your api key
|
10
|
-
# * :server => Server to connect (Only for development)
|
11
|
-
def self.configure(params={})
|
12
|
-
@@config.merge! params
|
13
|
-
end
|
14
|
-
|
15
|
-
# Return settings
|
16
|
-
def self.configuration
|
17
|
-
@@config
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
DEFAULT_SERVER = 'https://neighborparrot.net'
|
23
|
-
@@config = { :server => DEFAULT_SERVER }
|
24
|
-
|
25
|
-
# Chen mandatory parameters
|
26
|
-
# @param [Hash] parameters
|
27
|
-
# @param [Symbol] action [:send/:open]
|
28
|
-
def self.check_params(p, action=:send)
|
29
|
-
raise "Channel can't be nil" if p[:channel].nil? || p[:channel].length == 0
|
30
|
-
raise "ERROR# Neighborparrot: api_id can't be nil" if p[:api_id].nil? || p[:api_id].length == 0
|
31
|
-
if action == :send
|
32
|
-
raise "ERROR# Neighborparrot: api_key can't be nil" if p[:api_key].nil? || p[:api_key].length == 0
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
3
|
+
require 'neighborparrot/config'
|
4
|
+
require 'neighborparrot/callbacks'
|
5
|
+
require 'neighborparrot/reactor'
|
37
6
|
require 'neighborparrot/send'
|
38
|
-
require 'neighborparrot/
|
7
|
+
require 'neighborparrot/open'
|
8
|
+
require 'neighborparrot/helpers/url_helpers'
|
data/neighborparrot.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "neighborparrot"
|
8
|
-
s.version = "0.3.
|
8
|
+
s.version = "0.3.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Eloy Gomez"]
|
12
|
-
s.date = "2012-01-
|
12
|
+
s.date = "2012-01-11"
|
13
13
|
s.description = "Send messages to the neighborparrot event source service"
|
14
14
|
s.email = "eloy@indeos.es"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -26,13 +26,18 @@ Gem::Specification.new do |s|
|
|
26
26
|
"Rakefile",
|
27
27
|
"VERSION",
|
28
28
|
"lib/neighborparrot.rb",
|
29
|
-
"lib/neighborparrot/
|
29
|
+
"lib/neighborparrot/callbacks.rb",
|
30
|
+
"lib/neighborparrot/config.rb",
|
31
|
+
"lib/neighborparrot/helpers/url_helpers.rb",
|
32
|
+
"lib/neighborparrot/open.rb",
|
33
|
+
"lib/neighborparrot/reactor.rb",
|
30
34
|
"lib/neighborparrot/send.rb",
|
31
35
|
"neighborparrot.gemspec",
|
32
|
-
"spec/
|
33
|
-
"spec/
|
36
|
+
"spec/integration/neighborparrot_spec.rb",
|
37
|
+
"spec/reactor_spec.rb",
|
34
38
|
"spec/spec_helper.rb",
|
35
|
-
"spec/support/helpers.rb"
|
39
|
+
"spec/support/helpers.rb",
|
40
|
+
"spec/unit/callbacks_spec.rb"
|
36
41
|
]
|
37
42
|
s.homepage = "http://neighborparrot.com"
|
38
43
|
s.licenses = ["MIT"]
|
@@ -44,17 +49,26 @@ Gem::Specification.new do |s|
|
|
44
49
|
s.specification_version = 3
|
45
50
|
|
46
51
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
52
|
+
s.add_runtime_dependency(%q<eventmachine>, [">= 0"])
|
53
|
+
s.add_runtime_dependency(%q<em-http-request>, [">= 0"])
|
54
|
+
s.add_runtime_dependency(%q<em-eventsource>, [">= 0"])
|
47
55
|
s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
|
48
56
|
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
49
57
|
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
50
58
|
s.add_development_dependency(%q<rcov>, [">= 0"])
|
51
59
|
else
|
60
|
+
s.add_dependency(%q<eventmachine>, [">= 0"])
|
61
|
+
s.add_dependency(%q<em-http-request>, [">= 0"])
|
62
|
+
s.add_dependency(%q<em-eventsource>, [">= 0"])
|
52
63
|
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
53
64
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
54
65
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
55
66
|
s.add_dependency(%q<rcov>, [">= 0"])
|
56
67
|
end
|
57
68
|
else
|
69
|
+
s.add_dependency(%q<eventmachine>, [">= 0"])
|
70
|
+
s.add_dependency(%q<em-http-request>, [">= 0"])
|
71
|
+
s.add_dependency(%q<em-eventsource>, [">= 0"])
|
58
72
|
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
59
73
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
60
74
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
2
|
|
3
3
|
describe "Neighborparrot::ESParrot" do
|
4
4
|
before :all do
|
@@ -9,12 +9,13 @@ describe "Neighborparrot::ESParrot" do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
before :each do
|
12
|
-
@parrot =
|
12
|
+
@parrot = Neighborparrot::Reactor.new
|
13
|
+
@parrot.on_error { |e| raise e }
|
13
14
|
end
|
14
15
|
|
15
16
|
describe "Neighborparrot::ESParrot#open" do
|
16
17
|
after :each do
|
17
|
-
@parrot.
|
18
|
+
@parrot.stop
|
18
19
|
end
|
19
20
|
|
20
21
|
it "should open a connection with correct values" do
|
@@ -23,7 +24,7 @@ describe "Neighborparrot::ESParrot" do
|
|
23
24
|
connected = true
|
24
25
|
end
|
25
26
|
@parrot.open(:channel => @channel)
|
26
|
-
sleep
|
27
|
+
sleep 1
|
27
28
|
connected.should be_true
|
28
29
|
end
|
29
30
|
|
@@ -33,16 +34,15 @@ describe "Neighborparrot::ESParrot" do
|
|
33
34
|
received = msg
|
34
35
|
end
|
35
36
|
@parrot.open(:channel => @channel)
|
36
|
-
|
37
|
+
|
37
38
|
text = Faker::Lorem.paragraph(30)
|
38
|
-
|
39
|
-
sleep
|
39
|
+
@parrot.send(:channel => 'test', :data => text)
|
40
|
+
sleep 1
|
40
41
|
received.should eq text
|
41
42
|
end
|
42
43
|
|
43
44
|
it "should return false if already a connection active" do
|
44
45
|
@parrot.open(:channel => @channel)
|
45
|
-
sleep(2)
|
46
46
|
@parrot.open(:channel => 'other test').should be_false
|
47
47
|
end
|
48
48
|
end
|
@@ -50,8 +50,7 @@ describe "Neighborparrot::ESParrot" do
|
|
50
50
|
describe "Neighborparrot::ESParrot#close" do
|
51
51
|
it "should close a connection" do
|
52
52
|
@parrot.open(:channel => @channel)
|
53
|
-
|
54
|
-
@parrot.close()
|
53
|
+
@parrot.stop
|
55
54
|
@parrot.connected?.should be_false
|
56
55
|
end
|
57
56
|
end
|
@@ -64,7 +63,7 @@ describe "Neighborparrot::ESParrot" do
|
|
64
63
|
|
65
64
|
it "should be true when connected" do
|
66
65
|
@parrot.open(:channel => @channel)
|
67
|
-
sleep
|
66
|
+
sleep 2
|
68
67
|
@parrot.connected?.should be_true
|
69
68
|
@parrot.close
|
70
69
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Neighborparrot::Reactor do
|
4
|
+
|
5
|
+
describe 'class reactor' do
|
6
|
+
after :each do
|
7
|
+
Neighborparrot.reactor_stop
|
8
|
+
end
|
9
|
+
describe 'Neighborparrot#reactor_start' do
|
10
|
+
it 'should not have a static reactor by default' do
|
11
|
+
Neighborparrot.reactor_running?.should be_false
|
12
|
+
end
|
13
|
+
it 'should create a static reator' do
|
14
|
+
Neighborparrot.reactor_start
|
15
|
+
sleep 1
|
16
|
+
Neighborparrot.reactor_running?.should be_true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
describe 'Neighborparrot#reactor_stop' do
|
20
|
+
it 'should stop the static reator' do
|
21
|
+
Neighborparrot.reactor_start
|
22
|
+
Neighborparrot.reactor_stop
|
23
|
+
sleep 1
|
24
|
+
Neighborparrot.reactor_running?.should be_false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
describe 'Reactor#define_event_helpers' do
|
29
|
+
before :each do
|
30
|
+
@parrot = Neighborparrot::Reactor.new
|
31
|
+
end
|
32
|
+
Neighborparrot::EVENTS.each do |event|
|
33
|
+
it "Shold respond to on_#{event}" do
|
34
|
+
@parrot.respond_to?("on_#{event}").should be_true
|
35
|
+
end
|
36
|
+
|
37
|
+
it "Shold respond to trigger_#{event}" do
|
38
|
+
@parrot.respond_to?("trigger_#{event}").should be_true
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should trigger defined blocks to events' do
|
42
|
+
received = nil
|
43
|
+
message = 'test string'
|
44
|
+
@parrot.on_message { |m| received = m }
|
45
|
+
@parrot.trigger_message message
|
46
|
+
received.should eq message
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'Reactor#initialize' do
|
52
|
+
it 'should create a new reactor unless skeep start'
|
53
|
+
it 'should not start the reactor if skeep start'
|
54
|
+
end
|
55
|
+
|
56
|
+
describe 'Reactor#start' do
|
57
|
+
it 'should start the reactor'
|
58
|
+
end
|
59
|
+
|
60
|
+
describe 'Reactor#stop' do
|
61
|
+
it 'should stop the reactor'
|
62
|
+
end
|
63
|
+
|
64
|
+
describe 'Reactor#send' do
|
65
|
+
it 'should send a message to the broker'
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -10,7 +10,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../lib/neighborparrot')
|
|
10
10
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
11
11
|
|
12
12
|
# Setup server on localhost
|
13
|
-
Neighborparrot.configure :server => 'http://127.0.0.1:9000'
|
13
|
+
# Neighborparrot.configure :server => 'http://127.0.0.1:9000'
|
14
14
|
|
15
15
|
RSpec.configure do |config|
|
16
16
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe 'Callbacks' do
|
4
|
+
|
5
|
+
describe 'class helpers' do
|
6
|
+
Neighborparrot::EVENTS.each do |event|
|
7
|
+
it "Shold respond to on_#{event}" do
|
8
|
+
Neighborparrot.respond_to?("on_#{event}").should be_true
|
9
|
+
end
|
10
|
+
|
11
|
+
it "Shold respond to trigger_#{event}" do
|
12
|
+
Neighborparrot.respond_to?("trigger_#{event}").should be_true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: neighborparrot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,44 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-01-
|
12
|
+
date: 2012-01-11 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: eventmachine
|
16
|
+
requirement: &27578960 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *27578960
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: em-http-request
|
27
|
+
requirement: &27577740 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *27577740
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: em-eventsource
|
38
|
+
requirement: &27576580 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *27576580
|
14
47
|
- !ruby/object:Gem::Dependency
|
15
48
|
name: rspec
|
16
|
-
requirement: &
|
49
|
+
requirement: &27575720 !ruby/object:Gem::Requirement
|
17
50
|
none: false
|
18
51
|
requirements:
|
19
52
|
- - ~>
|
@@ -21,10 +54,10 @@ dependencies:
|
|
21
54
|
version: 2.3.0
|
22
55
|
type: :development
|
23
56
|
prerelease: false
|
24
|
-
version_requirements: *
|
57
|
+
version_requirements: *27575720
|
25
58
|
- !ruby/object:Gem::Dependency
|
26
59
|
name: bundler
|
27
|
-
requirement: &
|
60
|
+
requirement: &27574720 !ruby/object:Gem::Requirement
|
28
61
|
none: false
|
29
62
|
requirements:
|
30
63
|
- - ~>
|
@@ -32,10 +65,10 @@ dependencies:
|
|
32
65
|
version: 1.0.0
|
33
66
|
type: :development
|
34
67
|
prerelease: false
|
35
|
-
version_requirements: *
|
68
|
+
version_requirements: *27574720
|
36
69
|
- !ruby/object:Gem::Dependency
|
37
70
|
name: jeweler
|
38
|
-
requirement: &
|
71
|
+
requirement: &27573720 !ruby/object:Gem::Requirement
|
39
72
|
none: false
|
40
73
|
requirements:
|
41
74
|
- - ~>
|
@@ -43,10 +76,10 @@ dependencies:
|
|
43
76
|
version: 1.6.4
|
44
77
|
type: :development
|
45
78
|
prerelease: false
|
46
|
-
version_requirements: *
|
79
|
+
version_requirements: *27573720
|
47
80
|
- !ruby/object:Gem::Dependency
|
48
81
|
name: rcov
|
49
|
-
requirement: &
|
82
|
+
requirement: &27572860 !ruby/object:Gem::Requirement
|
50
83
|
none: false
|
51
84
|
requirements:
|
52
85
|
- - ! '>='
|
@@ -54,7 +87,7 @@ dependencies:
|
|
54
87
|
version: '0'
|
55
88
|
type: :development
|
56
89
|
prerelease: false
|
57
|
-
version_requirements: *
|
90
|
+
version_requirements: *27572860
|
58
91
|
description: Send messages to the neighborparrot event source service
|
59
92
|
email: eloy@indeos.es
|
60
93
|
executables: []
|
@@ -72,13 +105,18 @@ files:
|
|
72
105
|
- Rakefile
|
73
106
|
- VERSION
|
74
107
|
- lib/neighborparrot.rb
|
75
|
-
- lib/neighborparrot/
|
108
|
+
- lib/neighborparrot/callbacks.rb
|
109
|
+
- lib/neighborparrot/config.rb
|
110
|
+
- lib/neighborparrot/helpers/url_helpers.rb
|
111
|
+
- lib/neighborparrot/open.rb
|
112
|
+
- lib/neighborparrot/reactor.rb
|
76
113
|
- lib/neighborparrot/send.rb
|
77
114
|
- neighborparrot.gemspec
|
78
|
-
- spec/
|
79
|
-
- spec/
|
115
|
+
- spec/integration/neighborparrot_spec.rb
|
116
|
+
- spec/reactor_spec.rb
|
80
117
|
- spec/spec_helper.rb
|
81
118
|
- spec/support/helpers.rb
|
119
|
+
- spec/unit/callbacks_spec.rb
|
82
120
|
homepage: http://neighborparrot.com
|
83
121
|
licenses:
|
84
122
|
- MIT
|
@@ -94,7 +132,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
94
132
|
version: '0'
|
95
133
|
segments:
|
96
134
|
- 0
|
97
|
-
hash:
|
135
|
+
hash: 4307022084171942048
|
98
136
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
137
|
none: false
|
100
138
|
requirements:
|
@@ -1,92 +0,0 @@
|
|
1
|
-
class ESParrot
|
2
|
-
include Neighborparrot
|
3
|
-
|
4
|
-
# Open a persistent connection to the Neighbor in a new
|
5
|
-
# thread and return true if all works unless :foreground
|
6
|
-
# options is true.
|
7
|
-
# Current options to the connectio are:
|
8
|
-
#
|
9
|
-
# @param [String] channel to connect
|
10
|
-
# @param [Hash] Params for the connection. this params can be:
|
11
|
-
# * :foreground [Boolean] run the connection in the foreground
|
12
|
-
# stoping the clode flow until the connection is closed by server or
|
13
|
-
# another thread call close
|
14
|
-
# * :api_id => Your api ID in neighborparrot.com
|
15
|
-
# * :api_key => Your api key
|
16
|
-
# * :server => Server to connect (Only for development)
|
17
|
-
def open(params={})
|
18
|
-
params = Neighborparrot.configuration.merge(params)
|
19
|
-
Neighborparrot.check_params params, :open
|
20
|
-
return false if connected?
|
21
|
-
if ! params[:foreground] == true
|
22
|
-
close if @current_thread # If previus thread but closed connection, kill it
|
23
|
-
@current_thread = Thread.new(params) do | params|
|
24
|
-
open_connection params
|
25
|
-
end
|
26
|
-
return true
|
27
|
-
else
|
28
|
-
open_connection params
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# @return true if a connection exists and is started
|
33
|
-
def connected?
|
34
|
-
@connection && @connection.started?
|
35
|
-
end
|
36
|
-
|
37
|
-
# close the active connection
|
38
|
-
def close
|
39
|
-
return unless connected?
|
40
|
-
@connection.finish()
|
41
|
-
@current_thread.kill
|
42
|
-
@current_thread = nil
|
43
|
-
end
|
44
|
-
|
45
|
-
# Define a block called on message received
|
46
|
-
# The received message is passed to the block as a var
|
47
|
-
def on_message(&block)
|
48
|
-
@on_message_blk = block
|
49
|
-
end
|
50
|
-
|
51
|
-
# Define a block called on error
|
52
|
-
# An optional param with the error should be pass if present
|
53
|
-
def on_error(&block)
|
54
|
-
@on_error_blk = block
|
55
|
-
end
|
56
|
-
|
57
|
-
# Define a block called on connection closed
|
58
|
-
def on_close(&block)
|
59
|
-
@on_close_blk = block
|
60
|
-
end
|
61
|
-
|
62
|
-
# Define a block called on connect
|
63
|
-
def on_connect(&block)
|
64
|
-
@on_connect_blk = block
|
65
|
-
end
|
66
|
-
|
67
|
-
private
|
68
|
-
|
69
|
-
# Open a persistent connection to the neighbor
|
70
|
-
# TODO: Refactor, EM??
|
71
|
-
def open_connection(params)
|
72
|
-
begin
|
73
|
-
uri = URI(params[:server])
|
74
|
-
Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
|
75
|
-
http.read_timeout = 9999999999999999 # TODO Fix this
|
76
|
-
request = Net::HTTP::Get.new URI.escape("/open?channel=#{params[:channel]}")
|
77
|
-
@connection = http
|
78
|
-
@on_connect_blk.call if @on_connect_blk
|
79
|
-
http.request request do |response|
|
80
|
-
response.read_body do |chunk|
|
81
|
-
if chunk.start_with? "data:"
|
82
|
-
@on_message_blk.call(chunk[5..-3]) if @on_message_blk # Remove data: and \n\n
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
rescue
|
88
|
-
@on_error_blk.call($!) if @on_error_blk
|
89
|
-
end
|
90
|
-
@on_close_blk.call if @on_close_blk
|
91
|
-
end
|
92
|
-
end
|
data/spec/neighborparrot_spec.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
|
3
|
-
describe "Neighborparrot" do
|
4
|
-
before :each do
|
5
|
-
api_id = 'test-id'
|
6
|
-
api_key = 'api_key'
|
7
|
-
Neighborparrot.configure({ :api_id => api_id, :api_key => :api_key })
|
8
|
-
end
|
9
|
-
|
10
|
-
describe "Neigborparrot#post" do
|
11
|
-
it 'should return true if no errors' do
|
12
|
-
send_test.should be_true
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should rails exception without id" do
|
16
|
-
Neighborparrot.configure({ :api_key => nil })
|
17
|
-
expect { send_test }.to raise_error
|
18
|
-
end
|
19
|
-
|
20
|
-
it "should rails exception without key" do
|
21
|
-
Neighborparrot.configure({:api_id => nil})
|
22
|
-
expect { send_test }.to raise_error
|
23
|
-
end
|
24
|
-
|
25
|
-
it "should raise exception with nill channel" do
|
26
|
-
expect { Neighborparrot.send(:channel => nil, :data => 'test string') }.to raise_error
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should raise exception with empty channel" do
|
30
|
-
expect { Neighborparrot.send(:channel => '', :data => 'test string') }.to raise_error
|
31
|
-
end
|
32
|
-
|
33
|
-
it "should not send message with nil data" do
|
34
|
-
Neighborparrot.send(:channel => 'test-channel', :data => nil).should be_false
|
35
|
-
end
|
36
|
-
|
37
|
-
it "should not send message with empty data" do
|
38
|
-
Neighborparrot.send(:channel => 'test-channel', :data => '').should be_false
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|