miu 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://travis-ci.org/yuijo/miu.png?branch=master)](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
|