miu 0.1.0 → 0.2.0
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/.rspec +2 -0
- data/.travis.yml +21 -0
- data/Gemfile +7 -0
- data/Guardfile +8 -0
- data/README.md +19 -2
- data/Rakefile +3 -0
- data/bin/miu +0 -2
- data/lib/miu/cli.rb +49 -24
- data/lib/miu/cli_base.rb +7 -0
- data/lib/miu/command.rb +19 -12
- data/lib/miu/errors.rb +22 -0
- data/lib/miu/forwarder.rb +54 -0
- data/lib/miu/logger.rb +11 -5
- data/lib/miu/messages/base.rb +14 -4
- data/lib/miu/messages/text.rb +4 -2
- data/lib/miu/messages/unknown.rb +11 -0
- data/lib/miu/messages.rb +17 -2
- data/lib/miu/{plugin.rb → node.rb} +10 -9
- data/lib/miu/nodes/.gitkeep +0 -0
- data/lib/miu/{plugins.rb → nodes.rb} +1 -1
- data/lib/miu/packet.rb +11 -18
- data/lib/miu/proxy.rb +57 -0
- data/lib/miu/publishable.rb +18 -0
- data/lib/miu/publisher.rb +16 -22
- data/lib/miu/resources/base.rb +2 -2
- data/lib/miu/resources/content.rb +1 -1
- data/lib/miu/resources/network.rb +1 -1
- data/lib/miu/resources/room.rb +1 -1
- data/lib/miu/resources/text_content.rb +3 -5
- data/lib/miu/resources/user.rb +1 -1
- data/lib/miu/server.rb +10 -25
- data/lib/miu/socket.rb +100 -28
- data/lib/miu/subscribable.rb +44 -0
- data/lib/miu/subscriber.rb +17 -48
- data/lib/miu/utility.rb +13 -8
- data/lib/miu/version.rb +1 -1
- data/lib/miu.rb +42 -25
- data/miu.gemspec +6 -4
- data/spec/miu/command_spec.rb +26 -0
- data/spec/miu/logger_spec.rb +39 -0
- data/spec/miu/messages/base_spec.rb +43 -0
- data/spec/miu/messages/text_spec.rb +35 -0
- data/spec/miu/node_spec.rb +31 -0
- data/spec/miu/packet_spec.rb +47 -0
- data/spec/miu/publishable_spec.rb +24 -0
- data/spec/miu/publisher_spec.rb +36 -0
- data/spec/miu/subscribable_spec.rb +44 -0
- data/spec/miu/subscriber_spec.rb +36 -0
- data/spec/miu/utility_spec.rb +60 -0
- data/spec/miu_spec.rb +23 -0
- data/spec/spec_helper.rb +15 -0
- metadata +86 -19
- data/lib/miu/plugins/null.rb +0 -59
- data/lib/templates/Gemfile +0 -8
data/.rspec
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
language: ruby
|
2
|
+
|
3
|
+
rvm:
|
4
|
+
- 1.9.3
|
5
|
+
- 2.0.0
|
6
|
+
|
7
|
+
before_install:
|
8
|
+
- sudo apt-get update -qq
|
9
|
+
- sudo apt-get install -qq libzmq3-dev
|
10
|
+
|
11
|
+
branches:
|
12
|
+
only:
|
13
|
+
- master
|
14
|
+
|
15
|
+
notifications:
|
16
|
+
irc:
|
17
|
+
channels:
|
18
|
+
- "irc.freenode.net#miu-dev"
|
19
|
+
use_notice: true
|
20
|
+
skip_join: true
|
21
|
+
|
data/Gemfile
CHANGED
@@ -1,4 +1,11 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
+
group :development do
|
4
|
+
gem 'guard-rspec'
|
5
|
+
gem 'rb-inotify', :require => false
|
6
|
+
gem 'rb-fsevent', :require => false
|
7
|
+
gem 'rb-fchange', :require => false
|
8
|
+
end
|
9
|
+
|
3
10
|
# Specify your gem's dependencies in miu.gemspec
|
4
11
|
gemspec
|
data/Guardfile
ADDED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Miu
|
1
|
+
# Miu [](https://travis-ci.org/yuijo/miu)
|
2
2
|
|
3
3
|
TODO: Write a gem description
|
4
4
|
|
@@ -18,7 +18,24 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
## Usage
|
20
20
|
|
21
|
-
|
21
|
+
### Setup
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
mkdir miu
|
25
|
+
cd miu
|
26
|
+
miu init
|
27
|
+
```
|
28
|
+
|
29
|
+
### Start
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
miu supervise
|
33
|
+
```
|
34
|
+
|
35
|
+
### Quit
|
36
|
+
```ruby
|
37
|
+
miu terminate
|
38
|
+
```
|
22
39
|
|
23
40
|
## Contributing
|
24
41
|
|
data/Rakefile
CHANGED
data/bin/miu
CHANGED
data/lib/miu/cli.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
require 'miu'
|
2
|
+
require 'miu/cli_base'
|
2
3
|
require 'thor'
|
3
4
|
|
4
5
|
module Miu
|
5
|
-
class CLI <
|
6
|
-
include ::Thor::Actions
|
7
|
-
add_runtime_options!
|
8
|
-
|
6
|
+
class CLI < CLIBase
|
9
7
|
class << self
|
10
8
|
def source_root
|
11
9
|
File.expand_path('../../templates', __FILE__)
|
@@ -17,7 +15,6 @@ module Miu
|
|
17
15
|
end
|
18
16
|
|
19
17
|
map ['--version', '-v'] => :version
|
20
|
-
|
21
18
|
desc 'version', 'Show version'
|
22
19
|
def version
|
23
20
|
say "Miu #{Miu::VERSION}"
|
@@ -25,7 +22,6 @@ module Miu
|
|
25
22
|
|
26
23
|
desc 'init', 'Generates a miu configuration files'
|
27
24
|
def init
|
28
|
-
copy_file 'Gemfile'
|
29
25
|
inside 'config' do
|
30
26
|
template 'miu.god'
|
31
27
|
end
|
@@ -33,49 +29,78 @@ module Miu
|
|
33
29
|
empty_directory 'tmp/pids'
|
34
30
|
end
|
35
31
|
|
36
|
-
desc 'list', 'Lists
|
32
|
+
desc 'list', 'Lists nodes'
|
37
33
|
def list
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
table = Miu.nodes.map do |name, node|
|
35
|
+
[name, "# #{node.description}"]
|
36
|
+
end
|
37
|
+
say 'Nodes:'
|
41
38
|
print_table table, :indent => 2, :truncate => true
|
42
|
-
say
|
43
39
|
end
|
44
40
|
|
45
|
-
desc 'start', 'Start miu'
|
41
|
+
desc 'start', 'Start miu server'
|
46
42
|
option 'pub-host', :type => :string, :default => '127.0.0.1', :desc => 'pub host'
|
47
43
|
option 'pub-port', :type => :numeric, :default => Miu.default_pub_port, :desc => 'pub port'
|
48
44
|
option 'sub-host', :type => :string, :default => '127.0.0.1', :desc => 'sub host'
|
49
45
|
option 'sub-port', :type => :numeric, :default => Miu.default_sub_port, :desc => 'sub port'
|
46
|
+
option 'bridge-host', :type => :string, :default => '127.0.0.1', :desc => 'bridge host'
|
47
|
+
option 'bridge-port', :type => :numeric, :desc => 'bridge port'
|
50
48
|
option 'verbose', :type => :boolean, :default => false, :desc => 'verbose output', :aliases => '-V'
|
51
49
|
def start
|
52
|
-
server = Miu::Server.new Miu::Utility.
|
50
|
+
server = Miu::Server.new Miu::Utility.optionify_keys(options)
|
53
51
|
server.run
|
54
52
|
end
|
55
53
|
|
56
|
-
desc 'cat
|
54
|
+
desc 'cat TAG ROOM TEXT', 'Okaka kakeyoune'
|
57
55
|
option 'host', :type => :string, :default => '127.0.0.1', :desc => 'miu sub host'
|
58
56
|
option 'port', :type => :numeric, :default => Miu.default_sub_port, :desc => 'miu sub port'
|
59
|
-
|
57
|
+
option 'network', :type => :string, :default => 'debug', :desc => 'miu network name'
|
58
|
+
def cat(tag, room, text)
|
59
|
+
require 'miu/messages'
|
60
60
|
require 'json'
|
61
61
|
publisher = Miu::Publisher.new :host => options[:host], :port => options[:port]
|
62
|
-
|
63
|
-
|
64
|
-
|
62
|
+
message = Miu::Messages::Text.new do |m|
|
63
|
+
m.network.name = options[:network]
|
64
|
+
m.content.tap do |c|
|
65
|
+
c.room.name = room
|
66
|
+
c.text = text
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
packet = publisher.write tag, message
|
71
|
+
Miu::Logger.info packet.inspect
|
72
|
+
rescue => e
|
73
|
+
Miu::Logger.exception e
|
65
74
|
end
|
66
75
|
|
67
|
-
desc 'supervise', 'Supervise miu and
|
76
|
+
desc 'supervise', 'Supervise miu and nodes'
|
68
77
|
def supervise(*args)
|
69
|
-
|
70
|
-
args
|
71
|
-
run args.join(' ')
|
78
|
+
args.unshift "-c #{Miu.default_god_config}"
|
79
|
+
run_god *args
|
72
80
|
end
|
73
81
|
|
74
|
-
desc '
|
82
|
+
desc 'terminate', 'Terminate miu and nodes'
|
83
|
+
def terminate(*args)
|
84
|
+
args.unshift "-p #{Miu.default_god_port} terminate"
|
85
|
+
run_god *args
|
86
|
+
end
|
87
|
+
|
88
|
+
desc 'god [ARGS]', 'Miu is a god'
|
75
89
|
def god(*args)
|
90
|
+
args.unshift "-p #{Miu.default_god_port}"
|
91
|
+
run_god *args
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def run_god(*args)
|
76
97
|
require 'god'
|
77
|
-
args.unshift
|
98
|
+
args.unshift 'god'
|
78
99
|
run args.join(' ')
|
79
100
|
end
|
80
101
|
end
|
81
102
|
end
|
103
|
+
|
104
|
+
# load miu nodes
|
105
|
+
Miu.load_nodes
|
106
|
+
|
data/lib/miu/cli_base.rb
ADDED
data/lib/miu/command.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
require 'miu'
|
2
|
+
require 'miu/cli_base'
|
2
3
|
|
3
4
|
module Miu
|
4
5
|
class Command
|
5
|
-
def self.new(name,
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
add_runtime_options!
|
6
|
+
def self.new(name, node, options = {}, &block)
|
7
|
+
Class.new Miu::CLIBase do
|
8
|
+
attr_accessor :node
|
9
|
+
@node = node
|
10
10
|
|
11
11
|
class << self
|
12
12
|
def source_root
|
13
|
-
|
13
|
+
@node.spec.full_gem_path rescue nil
|
14
14
|
end
|
15
15
|
|
16
16
|
def destination_root
|
@@ -21,14 +21,21 @@ module Miu
|
|
21
21
|
super task, namespace, subcommand || options.fetch(:subcommand, true)
|
22
22
|
end
|
23
23
|
|
24
|
-
def add_miu_pub_options
|
25
|
-
option '
|
26
|
-
option '
|
24
|
+
def add_miu_pub_options(name)
|
25
|
+
option 'pub-host', :type => :string, :default => '127.0.0.1', :desc => 'miu pub host'
|
26
|
+
option 'pub-port', :type => :numeric, :default => Miu.default_sub_port, :desc => 'miu pub port'
|
27
|
+
option 'pub-tag', :type => :string, :default => "miu.input.#{name}.", :desc => 'miu pub tag'
|
27
28
|
end
|
28
29
|
|
29
|
-
def add_miu_sub_options
|
30
|
-
option '
|
31
|
-
option '
|
30
|
+
def add_miu_sub_options(name)
|
31
|
+
option 'sub-host', :type => :string, :default => '127.0.0.1', :desc => 'miu sub host'
|
32
|
+
option 'sub-port', :type => :numeric, :default => Miu.default_pub_port, :desc => 'miu sub port'
|
33
|
+
option 'sub-tag', :type => :string, :default => "miu.output.#{name}.", :desc => 'miu sub tag'
|
34
|
+
end
|
35
|
+
|
36
|
+
def add_miu_pub_sub_options(name)
|
37
|
+
add_miu_pub_options name
|
38
|
+
add_miu_sub_options name
|
32
39
|
end
|
33
40
|
end
|
34
41
|
|
data/lib/miu/errors.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
module Miu
|
2
|
+
class Error < StandardError
|
3
|
+
end
|
4
|
+
|
5
|
+
class WrappedError < Error
|
6
|
+
attr_accessor :error
|
7
|
+
|
8
|
+
def initialize(error)
|
9
|
+
@error = error
|
10
|
+
super "#{@error.class}: #{@error.to_s}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class InvalidTypeError < Error
|
15
|
+
end
|
16
|
+
|
17
|
+
class PacketLoadError < WrappedError
|
18
|
+
end
|
19
|
+
|
20
|
+
class MessageLoadError < WrappedError
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'miu/socket'
|
2
|
+
require 'miu/proxy'
|
3
|
+
require 'ffi-rzmq'
|
4
|
+
|
5
|
+
module Miu
|
6
|
+
class Forwarder
|
7
|
+
def initialize(options = {})
|
8
|
+
@pub = pub_socket_class.new
|
9
|
+
@pub.bind Miu::Socket.build_address(options[:pub_host], options[:pub_port])
|
10
|
+
|
11
|
+
@sub = sub_socket_class.new
|
12
|
+
@sub.bind Miu::Socket.build_address(options[:sub_host], options[:sub_port])
|
13
|
+
@sub.subscribe ''
|
14
|
+
|
15
|
+
if options[:bridge_port]
|
16
|
+
@bridge = sub_socket_class.new
|
17
|
+
@bridge.connect Miu::Socket.build_address(options[:bridge_host], options[:bridge_port])
|
18
|
+
@bridge.subscribe ''
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def close
|
23
|
+
@bridge.close if @bridge
|
24
|
+
@sub.close
|
25
|
+
@pub.close
|
26
|
+
end
|
27
|
+
|
28
|
+
def run
|
29
|
+
frontends = [@sub, @bridge].compact
|
30
|
+
backends = [@pub]
|
31
|
+
|
32
|
+
proxy = Proxy.new frontends, backends
|
33
|
+
proxy.run
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def pub_socket_class
|
39
|
+
if ::ZMQ::LibZMQ.version3?
|
40
|
+
XPubSocket
|
41
|
+
else
|
42
|
+
PubSocket
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def sub_socket_class
|
47
|
+
if ::ZMQ::LibZMQ.version3?
|
48
|
+
XSubSocket
|
49
|
+
else
|
50
|
+
SubSocket
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/miu/logger.rb
CHANGED
@@ -5,19 +5,23 @@ module Miu
|
|
5
5
|
module_function
|
6
6
|
|
7
7
|
%w(debug info warn error fatal).each do |name|
|
8
|
-
|
8
|
+
eval <<-EOS
|
9
9
|
def #{name}(msg)
|
10
10
|
Miu.logger.#{name}(msg) if Miu.logger
|
11
11
|
end
|
12
12
|
EOS
|
13
13
|
end
|
14
14
|
|
15
|
-
def exception(
|
16
|
-
|
15
|
+
def exception(*args)
|
16
|
+
ex = args.pop
|
17
|
+
error [*args, format_exception(ex)].join("\n")
|
17
18
|
end
|
18
19
|
|
19
20
|
def format_exception(ex)
|
20
|
-
|
21
|
+
rows = []
|
22
|
+
rows << "#{ex.class}: #{ex.to_s}"
|
23
|
+
rows += ex.backtrace.map { |s| "\tfrom #{s}" }
|
24
|
+
rows.join("\n")
|
21
25
|
end
|
22
26
|
|
23
27
|
def formatter(severity, time, progname, msg)
|
@@ -26,9 +30,11 @@ module Miu
|
|
26
30
|
end
|
27
31
|
|
28
32
|
class << self
|
33
|
+
attr_accessor :default_logger
|
29
34
|
attr_accessor :logger
|
30
35
|
end
|
31
|
-
self.
|
36
|
+
self.default_logger = ::Logger.new(STDERR)
|
37
|
+
self.logger = self.default_logger
|
32
38
|
self.logger.level = ::Logger::INFO
|
33
39
|
self.logger.formatter = Miu::Logger.method(:formatter)
|
34
40
|
end
|
data/lib/miu/messages/base.rb
CHANGED
@@ -1,26 +1,36 @@
|
|
1
|
-
require 'miu/
|
1
|
+
require 'miu/messages'
|
2
2
|
require 'msgpack'
|
3
|
+
require 'securerandom'
|
3
4
|
|
4
5
|
module Miu
|
5
6
|
module Messages
|
6
7
|
class Base
|
8
|
+
attr_accessor :id, :time
|
7
9
|
attr_accessor :network, :type, :content
|
8
10
|
|
9
11
|
def initialize(options = {})
|
10
|
-
@
|
12
|
+
@id = options[:id] || SecureRandom.uuid
|
13
|
+
@time = options[:time] || Time.now.to_i
|
14
|
+
@network = Miu::Utility.adapt(Resources::Network, options[:network] || {})
|
11
15
|
@type = options[:type]
|
12
|
-
@type = [@type, *Array(options[:sub_type])].compact.join('.')
|
13
16
|
@content = options[:content]
|
14
17
|
yield self if block_given?
|
15
18
|
end
|
16
19
|
|
17
20
|
def to_hash
|
18
|
-
{
|
21
|
+
{
|
22
|
+
:network => @network.to_hash,
|
23
|
+
:type => @type,
|
24
|
+
:content => @content ? @content.to_hash : {}
|
25
|
+
}
|
19
26
|
end
|
20
27
|
|
21
28
|
def to_msgpack(*args)
|
22
29
|
to_hash.to_msgpack(*args)
|
23
30
|
end
|
24
31
|
end
|
32
|
+
|
33
|
+
class Unknown < Base
|
34
|
+
end
|
25
35
|
end
|
26
36
|
end
|
data/lib/miu/messages/text.rb
CHANGED
@@ -1,14 +1,16 @@
|
|
1
|
+
require 'miu/resources'
|
1
2
|
require 'miu/messages/base'
|
2
|
-
require 'miu/resources/text_content'
|
3
3
|
|
4
4
|
module Miu
|
5
5
|
module Messages
|
6
6
|
class Text < Base
|
7
7
|
def initialize(options = {})
|
8
8
|
options[:type] ||= 'text'
|
9
|
-
options[:content]
|
9
|
+
options[:content] = Miu::Utility.adapt(Resources::TextContent, options[:content] || {})
|
10
10
|
super
|
11
11
|
end
|
12
12
|
end
|
13
|
+
|
14
|
+
register :text, Text
|
13
15
|
end
|
14
16
|
end
|
data/lib/miu/messages.rb
CHANGED
@@ -1,6 +1,21 @@
|
|
1
1
|
module Miu
|
2
2
|
module Messages
|
3
|
-
|
4
|
-
|
3
|
+
class << self
|
4
|
+
def types
|
5
|
+
@types ||= {}
|
6
|
+
end
|
7
|
+
|
8
|
+
def register(type, klass)
|
9
|
+
types[type.to_s] = klass
|
10
|
+
end
|
11
|
+
|
12
|
+
def guess(type)
|
13
|
+
types[type.to_s] || Unknown
|
14
|
+
end
|
15
|
+
end
|
5
16
|
end
|
6
17
|
end
|
18
|
+
|
19
|
+
require 'miu/messages/base'
|
20
|
+
require 'miu/messages/unknown'
|
21
|
+
require 'miu/messages/text'
|
@@ -1,26 +1,27 @@
|
|
1
1
|
require 'miu'
|
2
2
|
|
3
3
|
module Miu
|
4
|
-
module
|
4
|
+
module Node
|
5
5
|
def self.included(base)
|
6
6
|
STDOUT.sync = true
|
7
7
|
STDERR.sync = true
|
8
|
-
|
9
8
|
base.extend ClassMethods
|
10
|
-
base.called_from = begin
|
11
|
-
call_stack = caller.map { |p| p.sub(/:\d+.*/, '') }
|
12
|
-
File.dirname(call_stack.detect { |p| p !~ %r(miu[\w.-]*/lib/miu/plugins) })
|
13
|
-
end
|
14
9
|
end
|
15
10
|
|
16
11
|
module ClassMethods
|
17
|
-
attr_accessor :
|
12
|
+
attr_accessor :spec
|
13
|
+
|
14
|
+
def description(value = nil)
|
15
|
+
@description ||= self.name
|
16
|
+
@description = value if value
|
17
|
+
@description
|
18
|
+
end
|
18
19
|
|
19
20
|
def register(*args, &block)
|
20
21
|
options = Miu::Utility.extract_options!(args)
|
21
22
|
name = args.shift
|
22
|
-
|
23
|
-
Miu.register name,
|
23
|
+
node = args.shift || self
|
24
|
+
Miu.register name, node, options, &block
|
24
25
|
end
|
25
26
|
end
|
26
27
|
end
|
File without changes
|
data/lib/miu/packet.rb
CHANGED
@@ -1,36 +1,29 @@
|
|
1
|
-
require 'miu'
|
2
|
-
require 'securerandom'
|
1
|
+
require 'miu/errors'
|
3
2
|
require 'msgpack'
|
4
3
|
|
5
4
|
module Miu
|
6
5
|
class Packet
|
7
|
-
attr_accessor :tag, :
|
6
|
+
attr_accessor :tag, :data
|
8
7
|
|
9
|
-
def initialize(tag,
|
8
|
+
def initialize(tag, data)
|
10
9
|
@tag = tag
|
11
|
-
@
|
12
|
-
@id = options[:id] || SecureRandom.uuid
|
13
|
-
@time = options[:time] || Time.now.to_i
|
10
|
+
@data = data
|
14
11
|
end
|
15
12
|
|
16
13
|
def dump
|
17
|
-
data
|
18
|
-
'body' => @body,
|
19
|
-
'id' => @id,
|
20
|
-
'time' => @time,
|
21
|
-
}
|
22
|
-
[@tag, data.to_msgpack]
|
14
|
+
[@tag.to_s, @data.to_msgpack]
|
23
15
|
end
|
24
16
|
|
25
17
|
def self.load(parts)
|
26
|
-
tag = parts
|
27
|
-
data = MessagePack.unpack(parts
|
28
|
-
|
29
|
-
|
18
|
+
tag = parts[0]
|
19
|
+
data = MessagePack.unpack(parts[1])
|
20
|
+
new tag, data
|
21
|
+
rescue => e
|
22
|
+
raise PacketLoadError, e
|
30
23
|
end
|
31
24
|
|
32
25
|
def inspect
|
33
|
-
inspection = [:tag, :
|
26
|
+
inspection = [:tag, :data].map do |name|
|
34
27
|
"#{name}: #{__send__(name).inspect}"
|
35
28
|
end.join(', ')
|
36
29
|
"#<#{self.class} #{inspection}>"
|
data/lib/miu/proxy.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'miu/socket'
|
2
|
+
require 'ffi-rzmq'
|
3
|
+
|
4
|
+
module Miu
|
5
|
+
class Proxy
|
6
|
+
attr_reader :frontends, :backends
|
7
|
+
attr_reader :poller
|
8
|
+
|
9
|
+
PROXY_TO = '@__proxy_to__'
|
10
|
+
|
11
|
+
def initialize(frontends, backends)
|
12
|
+
@frontends = Array(frontends).map { |s| unwrap s }
|
13
|
+
@backends = Array(backends).map { |s| unwrap s }
|
14
|
+
|
15
|
+
@frontends.each { |s| s.instance_variable_set PROXY_TO, @backends }
|
16
|
+
@backends.each { |s| s.instance_variable_set PROXY_TO, @frontends }
|
17
|
+
|
18
|
+
@poller = ::ZMQ::Poller.new
|
19
|
+
@frontends.each { |s| @poller.register_readable s }
|
20
|
+
@backends.each { |s| @poller.register_readable s }
|
21
|
+
end
|
22
|
+
|
23
|
+
def run
|
24
|
+
loop do
|
25
|
+
@poller.poll
|
26
|
+
@poller.readables.each do |from|
|
27
|
+
loop do
|
28
|
+
msg = ::ZMQ::Message.new
|
29
|
+
from.recvmsg msg
|
30
|
+
more = from.more_parts?
|
31
|
+
|
32
|
+
proxy_to = from.instance_variable_get PROXY_TO
|
33
|
+
proxy_to.each do |to|
|
34
|
+
ctrl = ::ZMQ::Message.new
|
35
|
+
ctrl.copy msg.pointer
|
36
|
+
to.sendmsg ctrl, (more ? ::ZMQ::SNDMORE : 0)
|
37
|
+
end
|
38
|
+
|
39
|
+
msg.close
|
40
|
+
break unless more
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def unwrap(socket)
|
49
|
+
case socket
|
50
|
+
when Miu::Socket
|
51
|
+
socket.socket
|
52
|
+
else
|
53
|
+
socket
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'miu/packet'
|
2
|
+
|
3
|
+
module Miu
|
4
|
+
module Publishable
|
5
|
+
def self.included(base)
|
6
|
+
base.class_eval do
|
7
|
+
def write_with_packet(tag, message)
|
8
|
+
packet = Packet.new tag, message
|
9
|
+
write_without_packet *packet.dump
|
10
|
+
packet
|
11
|
+
end
|
12
|
+
|
13
|
+
alias_method :write_without_packet, :write
|
14
|
+
alias_method :write, :write_with_packet
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|