horobi 0.0.1
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/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +28 -0
- data/LICENSE.txt +20 -0
- data/README.mkd +108 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/examples/twitter/hub.rb +8 -0
- data/examples/twitter/pub1.rb +24 -0
- data/examples/twitter/pub2.rb +18 -0
- data/examples/twitter/sub1.rb +16 -0
- data/lib/horobi.rb +47 -0
- data/lib/horobi/hub.rb +79 -0
- data/lib/horobi/pub.rb +51 -0
- data/lib/horobi/sub.rb +52 -0
- data/spec/horobi_spec.rb +7 -0
- data/spec/spec_helper.rb +12 -0
- metadata +122 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "rspec", "~> 2.3.0"
|
10
|
+
gem "bundler", "~> 1.0.0"
|
11
|
+
gem "jeweler", "~> 1.5.2"
|
12
|
+
gem "rcov", ">= 0"
|
13
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
diff-lcs (1.1.2)
|
5
|
+
git (1.2.5)
|
6
|
+
jeweler (1.5.2)
|
7
|
+
bundler (~> 1.0.0)
|
8
|
+
git (>= 1.2.5)
|
9
|
+
rake
|
10
|
+
rake (0.8.7)
|
11
|
+
rcov (0.9.9)
|
12
|
+
rspec (2.3.0)
|
13
|
+
rspec-core (~> 2.3.0)
|
14
|
+
rspec-expectations (~> 2.3.0)
|
15
|
+
rspec-mocks (~> 2.3.0)
|
16
|
+
rspec-core (2.3.1)
|
17
|
+
rspec-expectations (2.3.0)
|
18
|
+
diff-lcs (~> 1.1.2)
|
19
|
+
rspec-mocks (2.3.0)
|
20
|
+
|
21
|
+
PLATFORMS
|
22
|
+
ruby
|
23
|
+
|
24
|
+
DEPENDENCIES
|
25
|
+
bundler (~> 1.0.0)
|
26
|
+
jeweler (~> 1.5.2)
|
27
|
+
rcov
|
28
|
+
rspec (~> 2.3.0)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 uu59
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.mkd
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
# horobi
|
2
|
+
|
3
|
+
Horobi is very flexible mesh network builder with ZeroMQ.
|
4
|
+
|
5
|
+

|
6
|
+
|
7
|
+
Virtual realtime web.
|
8
|
+
|
9
|
+

|
10
|
+
|
11
|
+
Scalable logging architecture.
|
12
|
+
|
13
|
+

|
14
|
+
|
15
|
+
Or, you can do all on one machine.
|
16
|
+
|
17
|
+

|
18
|
+
|
19
|
+
# Node Type
|
20
|
+
|
21
|
+
|
22
|
+
## Pub
|
23
|
+
|
24
|
+
Pub-node push some interesting data to Hub-node.
|
25
|
+
|
26
|
+
#!/usr/bin/env ruby
|
27
|
+
require "rubygems"
|
28
|
+
require "horobi"
|
29
|
+
|
30
|
+
loop do
|
31
|
+
Horobi::Pub.send(Time.now.to_s)
|
32
|
+
sleep 1
|
33
|
+
end
|
34
|
+
|
35
|
+
Real world sample as below:
|
36
|
+
|
37
|
+
#!/usr/bin/env ruby
|
38
|
+
require "rubygems"
|
39
|
+
require "twitter/json_stream" # https://github.com/voloko/twitter-stream
|
40
|
+
require "horobi"
|
41
|
+
|
42
|
+
EM.run do
|
43
|
+
stream = Twitter::JSONStream.connect(
|
44
|
+
:path => '/1/statuses/filter.json?track=ruby',
|
45
|
+
:auth => 'LOGIN:PASSWORD'
|
46
|
+
)
|
47
|
+
|
48
|
+
stream.each_item do |json|
|
49
|
+
Horobi::Pub.send("twitter " + json)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
## Hub
|
54
|
+
|
55
|
+
Hub-node get data from Pub-node, and push to Sub-node.
|
56
|
+
|
57
|
+
#!/usr/bin/env ruby
|
58
|
+
require "rubygems"
|
59
|
+
require "horobi"
|
60
|
+
|
61
|
+
Horobi::Hub.start
|
62
|
+
|
63
|
+
## Sub
|
64
|
+
|
65
|
+
Sub-node get data from Hub-node and do some stuff.
|
66
|
+
|
67
|
+
#!/usr/bin/env ruby
|
68
|
+
require "rubygems"
|
69
|
+
require "notify" # https://github.com/jugyo/notify
|
70
|
+
require "json"
|
71
|
+
require "horobi"
|
72
|
+
|
73
|
+
Horobi::Sub.listen("twitter") do |data|
|
74
|
+
tweet = JSON.parse(data)
|
75
|
+
Notify.notify(tweet["user"]["screen_name"], tweet["text"])
|
76
|
+
end
|
77
|
+
|
78
|
+
# Example
|
79
|
+
|
80
|
+
Please see example/ directory.
|
81
|
+
|
82
|
+
# launch pub node with background job, stream push to tcp://127.0.0.1:5551. if you don't want to log messages, use -l /dev/null option
|
83
|
+
$ SCREEN_NAME=uu59 PASSWORD=xxxx ruby example/twitter/pub1.rb -o tcp://127.0.0.1:5551 ruby & # tracking twitter stream with "ruby"
|
84
|
+
$ ruby example/twitter/pub2.rb -o tcp://127.0.0.1:5551 & # fake stream
|
85
|
+
|
86
|
+
# launch hub node as daemon(-d), ZeroMQ PULL socket listen to tcp://127.0.0.1:5551 (-i 5551) and PUB socket is tcp://127.0.0.1:5552 (-o 5552)
|
87
|
+
$ ruby example/twitter/hub.rb -d -i 5551 -o 5552
|
88
|
+
|
89
|
+
# get data from tcp://127.0.0.1:5552. you'll get mixed stream of twitter and fake.
|
90
|
+
$ ruby example/twitter/sub1.rb -i tcp://127.0.0.1:5552
|
91
|
+
|
92
|
+
You can ignore launch sequence to Pub/Sub/Hub nodes.
|
93
|
+
|
94
|
+
# Contributing to horobi
|
95
|
+
|
96
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
97
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
98
|
+
* Fork the project
|
99
|
+
* Start a feature/bugfix branch
|
100
|
+
* Commit and push until you are happy with your contribution
|
101
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
102
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
103
|
+
|
104
|
+
# Copyright
|
105
|
+
|
106
|
+
Copyright (c) 2011 uu59. See LICENSE.txt for
|
107
|
+
further details.
|
108
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "horobi"
|
16
|
+
gem.homepage = "http://github.com/tt25/horobi"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{TODO: one-line summary of your gem}
|
19
|
+
gem.description = %Q{TODO: longer description of your gem}
|
20
|
+
gem.email = "a@tt25.org"
|
21
|
+
gem.authors = ["uu59"]
|
22
|
+
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
23
|
+
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
24
|
+
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
25
|
+
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
26
|
+
end
|
27
|
+
Jeweler::RubygemsDotOrgTasks.new
|
28
|
+
|
29
|
+
require 'rspec/core'
|
30
|
+
require 'rspec/core/rake_task'
|
31
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
32
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
33
|
+
end
|
34
|
+
|
35
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
36
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
37
|
+
spec.rcov = true
|
38
|
+
end
|
39
|
+
|
40
|
+
task :default => :spec
|
41
|
+
|
42
|
+
require 'rake/rdoctask'
|
43
|
+
Rake::RDocTask.new do |rdoc|
|
44
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
45
|
+
|
46
|
+
rdoc.rdoc_dir = 'rdoc'
|
47
|
+
rdoc.title = "horobi #{version}"
|
48
|
+
rdoc.rdoc_files.include('README*')
|
49
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
50
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -- coding: utf-8
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "eventmachine"
|
6
|
+
require "twitter/json_stream"
|
7
|
+
|
8
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', '..', 'lib'))
|
9
|
+
require "horobi"
|
10
|
+
|
11
|
+
EM.run do
|
12
|
+
stream = Twitter::JSONStream.connect(
|
13
|
+
:path => "/1/statuses/filter.json?track=#{ARGV.first}",
|
14
|
+
:auth => "#{ENV["SCREEN_NAME"]}:#{ENV["PASSWORD"]}"
|
15
|
+
)
|
16
|
+
stream.each_item do |json|
|
17
|
+
Horobi::Pub.send(json)
|
18
|
+
end
|
19
|
+
|
20
|
+
stream.on_error do |message|
|
21
|
+
p message
|
22
|
+
EM.stop
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -- coding: utf-8
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "json"
|
6
|
+
|
7
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', '..', 'lib'))
|
8
|
+
require "horobi"
|
9
|
+
|
10
|
+
loop do
|
11
|
+
Horobi::Pub.send({
|
12
|
+
"user" => {
|
13
|
+
"screen_name" => "fake",
|
14
|
+
},
|
15
|
+
"text" => "this is fake tweet!"
|
16
|
+
}.to_json)
|
17
|
+
sleep 1
|
18
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -- coding: utf-8
|
3
|
+
|
4
|
+
|
5
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', '..', 'lib'))
|
6
|
+
require "horobi"
|
7
|
+
require "json"
|
8
|
+
|
9
|
+
Horobi::Sub.listen do |msg|
|
10
|
+
begin
|
11
|
+
tw = JSON.parse(msg)
|
12
|
+
puts tw["user"]["screen_name"] + ": " + tw["text"]
|
13
|
+
rescue
|
14
|
+
next
|
15
|
+
end
|
16
|
+
end
|
data/lib/horobi.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "logger"
|
4
|
+
require "optparse"
|
5
|
+
require "rubygems"
|
6
|
+
require "yaml"
|
7
|
+
require "zmq"
|
8
|
+
|
9
|
+
module Horobi
|
10
|
+
attr_accessor :logger
|
11
|
+
attr_reader :config
|
12
|
+
@logger = Logger.new(nil)
|
13
|
+
@closes = []
|
14
|
+
|
15
|
+
def daemonize
|
16
|
+
exit! if fork
|
17
|
+
Process.setsid
|
18
|
+
exit! if fork
|
19
|
+
|
20
|
+
STDIN.reopen('/dev/null', 'r+')
|
21
|
+
STDOUT.reopen('/dev/null', 'a')
|
22
|
+
STDERR.reopen('/dev/null', 'a')
|
23
|
+
end
|
24
|
+
|
25
|
+
def close_hooks(&block)
|
26
|
+
@closes << block
|
27
|
+
end
|
28
|
+
|
29
|
+
%w!INT TERM!.each{|sig|
|
30
|
+
Signal.trap(sig) do
|
31
|
+
@closes.each{|destruct|
|
32
|
+
begin
|
33
|
+
destruct.call
|
34
|
+
ensure
|
35
|
+
next
|
36
|
+
end
|
37
|
+
}
|
38
|
+
exit!
|
39
|
+
end
|
40
|
+
}
|
41
|
+
|
42
|
+
extend self
|
43
|
+
end
|
44
|
+
|
45
|
+
require "#{File.dirname(__FILE__)}/horobi/hub.rb"
|
46
|
+
require "#{File.dirname(__FILE__)}/horobi/sub.rb"
|
47
|
+
require "#{File.dirname(__FILE__)}/horobi/pub.rb"
|
data/lib/horobi/hub.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# -- coding: utf-8
|
2
|
+
|
3
|
+
require "rubygems"
|
4
|
+
|
5
|
+
module Horobi
|
6
|
+
module Hub
|
7
|
+
def start
|
8
|
+
|
9
|
+
@options = {
|
10
|
+
"logfile" => STDERR,
|
11
|
+
"input" => "5551",
|
12
|
+
"output" => "5552",
|
13
|
+
}
|
14
|
+
OptionParser.new do |op|
|
15
|
+
op.on('-p VAL','--pidfile=VAL','pidfile path'){|v| @options["pidfile"] = v}
|
16
|
+
op.on('-l VAL','--logfile=VAL','logfile path'){|v| @options["logfile"] = (v == "-" ? STDOUT : v)}
|
17
|
+
op.on('-i VAL','--input-port=VAL','input(pull) point such as 5551'){|v| @options["input"] = v}
|
18
|
+
op.on('-o VAL','--output-port=VAL','output(pub) point such as 5552'){|v| @options["output"] = v}
|
19
|
+
op.on('-d','--daemonize','daemonize this script'){ @options["daemonize"] = true }
|
20
|
+
op.parse!(ARGV)
|
21
|
+
end
|
22
|
+
|
23
|
+
@logger = Logger.new(@options["logfile"])
|
24
|
+
|
25
|
+
if @options["daemonize"]
|
26
|
+
Horobi.daemonize
|
27
|
+
@logger.debug("mainloop running ##{Process.pid}")
|
28
|
+
end
|
29
|
+
|
30
|
+
if @options["pidfile"]
|
31
|
+
File.open(@options["pidfile"],"w"){|fp| fp.write Process.pid}
|
32
|
+
end
|
33
|
+
|
34
|
+
begin
|
35
|
+
@context = ZMQ::Context.new
|
36
|
+
@input = @context.socket(ZMQ::PULL)
|
37
|
+
@input.bind("tcp://127.0.0.1:#{@options["input"]}")
|
38
|
+
@logger.info("input socket listen at #{@options["input"]}")
|
39
|
+
@output = @context.socket(ZMQ::PUB)
|
40
|
+
@output.bind("tcp://127.0.0.1:#{@options["output"]}")
|
41
|
+
@logger.info("output socket listen at #{@options["output"]}")
|
42
|
+
rescue TypeError => ex
|
43
|
+
puts "invalid port. input:#{@options["input"]}, output:#{@options["output"]}"
|
44
|
+
exit!
|
45
|
+
end
|
46
|
+
|
47
|
+
Horobi.close_hooks do
|
48
|
+
@logger.info("hub stopping")
|
49
|
+
stop
|
50
|
+
end
|
51
|
+
|
52
|
+
loop do
|
53
|
+
sleep 0.1
|
54
|
+
next unless inp = @input.recv(ZMQ::NOBLOCK)
|
55
|
+
@output.send(inp)
|
56
|
+
@logger.debug(inp)
|
57
|
+
end
|
58
|
+
|
59
|
+
exit!
|
60
|
+
end
|
61
|
+
|
62
|
+
def stop
|
63
|
+
begin
|
64
|
+
@logger.info("stopping..")
|
65
|
+
@input.close if @input
|
66
|
+
@output.close if @output
|
67
|
+
rescue IOError
|
68
|
+
# in `recv': closed socket (IOError)
|
69
|
+
ensure
|
70
|
+
if @options["pidfile"]
|
71
|
+
File.delete(@options["pidfile"])
|
72
|
+
end
|
73
|
+
@context.close
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
extend self
|
78
|
+
end
|
79
|
+
end
|
data/lib/horobi/pub.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# -- coding: utf-8
|
2
|
+
|
3
|
+
module Horobi
|
4
|
+
module Pub
|
5
|
+
attr_reader :sock
|
6
|
+
|
7
|
+
def self.init
|
8
|
+
@context ||= ZMQ::Context.new
|
9
|
+
options = {
|
10
|
+
"logfile" => STDERR,
|
11
|
+
"outputs" => [],
|
12
|
+
}
|
13
|
+
OptionParser.new do |op|
|
14
|
+
op.on('-p VAL','--pidfile=VAL','pidfile path'){|v| options["pidfile"] = v}
|
15
|
+
op.on('-l VAL','--logfile=VAL','logfile path'){|v| options["logfile"] = (v == "-" ? STDOUT : v)}
|
16
|
+
op.on('-o VAL','--ouput-points=VAL',
|
17
|
+
"output(hub's input) point(s) such as 'tcp://127.0.0.1:5551,tcp://127.0.11.1:5551'"){|v| options["outputs"] = v.split(",")}
|
18
|
+
op.on('-d','--daemonize','daemonize this script'){ options["daemon"] = true }
|
19
|
+
op.parse!(ARGV)
|
20
|
+
end
|
21
|
+
@options = options
|
22
|
+
if @options["outputs"].compact.length < 1
|
23
|
+
raise "pub output points are undefined"
|
24
|
+
end
|
25
|
+
@logger = Logger.new(options["logfile"])
|
26
|
+
@sock ||= begin
|
27
|
+
sock = @context.socket(ZMQ::PUSH)
|
28
|
+
@options["outputs"].each do |point|
|
29
|
+
@logger.info("connecting to #{point}")
|
30
|
+
sock.connect(point)
|
31
|
+
end
|
32
|
+
sock.setsockopt(ZMQ::LINGER, 100)
|
33
|
+
sock
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.send(msg, flags=nil) # flags = ZMQ::NOBLOCK | ZMQ::SNDMORE
|
38
|
+
if @options.nil?
|
39
|
+
init
|
40
|
+
end
|
41
|
+
|
42
|
+
@logger.debug("message send to #{@options["inputs"]}: " + msg)
|
43
|
+
@sock.send(msg, flags)
|
44
|
+
end
|
45
|
+
|
46
|
+
Horobi.close_hooks do
|
47
|
+
@sock.close if @sock
|
48
|
+
@context.close if @context
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/horobi/sub.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# -- coding: utf-8
|
2
|
+
|
3
|
+
module Horobi
|
4
|
+
module Sub
|
5
|
+
@context = ZMQ::Context.new
|
6
|
+
|
7
|
+
def self.init
|
8
|
+
options = {
|
9
|
+
"logfile" => STDERR,
|
10
|
+
"inputs" => [],
|
11
|
+
}
|
12
|
+
OptionParser.new do |op|
|
13
|
+
op.on('-p VAL','--pidfile=VAL','pidfile path'){|v| options["pidfile"] = v}
|
14
|
+
op.on('-l VAL','--logfile=VAL','logfile path'){|v| options["logfile"] = (v == "-" ? STDOUT : v)}
|
15
|
+
op.on('-i VAL','--input-points=VAL',
|
16
|
+
"input(hub's output) point(s) such as 'tcp://127.0.0.1:5551,tcp://127.0.11.1:5551'"){|v| options["inputs"] = v.split(",")}
|
17
|
+
#op.on('-d','--daemonize','daemonize this script'){ options["daemon"] = true }
|
18
|
+
op.parse!(ARGV)
|
19
|
+
end
|
20
|
+
@options = options
|
21
|
+
if @options["inputs"].compact.length < 1
|
22
|
+
raise "subscribe input points are undefined"
|
23
|
+
end
|
24
|
+
@logger = Logger.new(options["logfile"])
|
25
|
+
@sock ||= begin
|
26
|
+
sock = @context.socket(ZMQ::SUB)
|
27
|
+
@options["inputs"].each do |point|
|
28
|
+
@logger.info("connecting to #{point}")
|
29
|
+
sock.connect(point)
|
30
|
+
end
|
31
|
+
sock.setsockopt(ZMQ::LINGER, 100)
|
32
|
+
sock
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.listen(filter=nil, &block)
|
37
|
+
init unless @sock
|
38
|
+
@sock.setsockopt(ZMQ::SUBSCRIBE, filter.to_s)
|
39
|
+
|
40
|
+
Horobi.close_hooks do
|
41
|
+
@input.close
|
42
|
+
@context.close
|
43
|
+
end
|
44
|
+
|
45
|
+
loop do
|
46
|
+
buf = @sock.recv(ZMQ::NOBLOCK)
|
47
|
+
block.call(buf) if buf
|
48
|
+
sleep 0.1
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/spec/horobi_spec.rb
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
require 'horobi'
|
5
|
+
|
6
|
+
# Requires supporting files with custom matchers and macros, etc,
|
7
|
+
# in ./support/ and its subdirectories.
|
8
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: horobi
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- uu59
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-04-08 00:00:00 +09:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rspec
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ~>
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 2.3.0
|
25
|
+
type: :development
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ~>
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 1.0.0
|
36
|
+
type: :development
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: jeweler
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 1.5.2
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: rcov
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
type: :development
|
59
|
+
version_requirements: *id004
|
60
|
+
description: mesh network builder with ZeroMQ
|
61
|
+
email: a@tt25.org
|
62
|
+
executables: []
|
63
|
+
|
64
|
+
extensions: []
|
65
|
+
|
66
|
+
extra_rdoc_files:
|
67
|
+
- LICENSE.txt
|
68
|
+
- README.mkd
|
69
|
+
files:
|
70
|
+
- .document
|
71
|
+
- .rspec
|
72
|
+
- Gemfile
|
73
|
+
- Gemfile.lock
|
74
|
+
- LICENSE.txt
|
75
|
+
- README.mkd
|
76
|
+
- Rakefile
|
77
|
+
- VERSION
|
78
|
+
- examples/twitter/hub.rb
|
79
|
+
- examples/twitter/pub1.rb
|
80
|
+
- examples/twitter/pub2.rb
|
81
|
+
- examples/twitter/sub1.rb
|
82
|
+
- lib/horobi.rb
|
83
|
+
- lib/horobi/hub.rb
|
84
|
+
- lib/horobi/pub.rb
|
85
|
+
- lib/horobi/sub.rb
|
86
|
+
- spec/horobi_spec.rb
|
87
|
+
- spec/spec_helper.rb
|
88
|
+
has_rdoc: true
|
89
|
+
homepage: http://github.com/uu59/horobi
|
90
|
+
licenses:
|
91
|
+
- MIT
|
92
|
+
post_install_message:
|
93
|
+
rdoc_options: []
|
94
|
+
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: "0"
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: "0"
|
109
|
+
requirements: []
|
110
|
+
|
111
|
+
rubyforge_project:
|
112
|
+
rubygems_version: 1.6.2
|
113
|
+
signing_key:
|
114
|
+
specification_version: 3
|
115
|
+
summary: mesh network builder with ZeroMQ
|
116
|
+
test_files:
|
117
|
+
- examples/twitter/hub.rb
|
118
|
+
- examples/twitter/pub1.rb
|
119
|
+
- examples/twitter/pub2.rb
|
120
|
+
- examples/twitter/sub1.rb
|
121
|
+
- spec/horobi_spec.rb
|
122
|
+
- spec/spec_helper.rb
|