bundesstrasse 0.0.9
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/lib/bundesstrasse/context.rb +33 -0
- data/lib/bundesstrasse/device.rb +37 -0
- data/lib/bundesstrasse/devices.rb +43 -0
- data/lib/bundesstrasse/errors.rb +31 -0
- data/lib/bundesstrasse/socket.rb +98 -0
- data/lib/bundesstrasse/sockets.rb +70 -0
- data/lib/bundesstrasse/version.rb +3 -0
- data/lib/bundesstrasse.rb +8 -0
- metadata +115 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
module Bundesstrasse
|
3
|
+
class Context
|
4
|
+
include Errors
|
5
|
+
|
6
|
+
def initialize(zmq_context)
|
7
|
+
@zmq_context = zmq_context
|
8
|
+
end
|
9
|
+
|
10
|
+
def socket(socket_class, options={})
|
11
|
+
raise ContextError.new("Context terminated") if terminated?
|
12
|
+
zmq_socket = error_check { @zmq_context.socket(socket_class.type) }
|
13
|
+
socket = socket_class.new(zmq_socket, options)
|
14
|
+
rescue ZMQError => e
|
15
|
+
ContextError.raise_error(e)
|
16
|
+
end
|
17
|
+
|
18
|
+
def terminate!
|
19
|
+
@zmq_context.terminate
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
def terminated?
|
24
|
+
@zmq_context.context.nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.create(options={})
|
28
|
+
new ZMQ::Context.create(options[:io_threads] || 1)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
ContextError = Class.new(ZMQError)
|
33
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
|
2
|
+
module Bundesstrasse
|
3
|
+
class Device
|
4
|
+
include Errors
|
5
|
+
|
6
|
+
attr_reader :frontend, :backend
|
7
|
+
def initialize(type, frontend, backend)
|
8
|
+
@type = type
|
9
|
+
@frontend = frontend
|
10
|
+
@backend = backend
|
11
|
+
end
|
12
|
+
|
13
|
+
def start
|
14
|
+
error_check do
|
15
|
+
ZMQ::LibZMQ.zmq_device(@type, @frontend.pointer, @backend.pointer)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def close!
|
22
|
+
@frontend.close!
|
23
|
+
@backend.close!
|
24
|
+
end
|
25
|
+
|
26
|
+
def error_check(&block)
|
27
|
+
super
|
28
|
+
rescue ZMQError => e
|
29
|
+
case e.error_code
|
30
|
+
when ZMQ::ETERM then close!
|
31
|
+
else DeviceError.raise_error(e)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
DeviceError = Class.new(ZMQError)
|
37
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Bundesstrasse
|
2
|
+
class QueueDevice < Device
|
3
|
+
attr_reader :context
|
4
|
+
def initialize(context, frontend, backend)
|
5
|
+
super(ZMQ::QUEUE, frontend, backend)
|
6
|
+
@context = context
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_endpoint!(options={})
|
10
|
+
@context.socket(RepSocket, options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.create(context)
|
14
|
+
frontend = context.socket(RouterSocket)
|
15
|
+
backend = context.socket(DealerSocket)
|
16
|
+
new(context, frontend, backend)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class ForwarderDevice < Device
|
21
|
+
def initialize(frontend, backend)
|
22
|
+
super(ZMQ::FORWARDER, frontend, backend)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.create(context)
|
26
|
+
frontend = context.socket(SubSocket)
|
27
|
+
backend = context.socket(PubSocket)
|
28
|
+
new(frontend, backend)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class StreamerDevice < Device
|
33
|
+
def initialize(frontend, backend)
|
34
|
+
super(ZMQ::STREAMER, frontend, backend)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.create(context)
|
38
|
+
frontend = context.socket(PullSocket)
|
39
|
+
backend = context.socket(PushSocket)
|
40
|
+
new(frontend, backend)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Bundesstrasse
|
2
|
+
class ZMQError < StandardError
|
3
|
+
attr_reader :error_code
|
4
|
+
def initialize(message, error_code=-1)
|
5
|
+
@error_code = error_code
|
6
|
+
super(message)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.raise_error(e)
|
10
|
+
raise new(e.message, e.error_code)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module Errors
|
15
|
+
def errno
|
16
|
+
ZMQ::Util.errno
|
17
|
+
end
|
18
|
+
|
19
|
+
def error_string
|
20
|
+
ZMQ::Util.error_string
|
21
|
+
end
|
22
|
+
|
23
|
+
def error_check(&block)
|
24
|
+
if (res = block.call).is_a? Fixnum
|
25
|
+
res = res >= 0
|
26
|
+
end
|
27
|
+
raise ZMQError.new(error_string, errno) unless res
|
28
|
+
res
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Bundesstrasse
|
2
|
+
class Socket
|
3
|
+
include Errors
|
4
|
+
|
5
|
+
def initialize(socket, options={})
|
6
|
+
@socket = socket
|
7
|
+
setup!(options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def bind(address)
|
11
|
+
@connected = error_check { @socket.bind(address) }
|
12
|
+
end
|
13
|
+
|
14
|
+
def connect(address)
|
15
|
+
@connected = error_check { @socket.connect(address) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def close!
|
19
|
+
!(@connected = !error_check { @socket.close })
|
20
|
+
end
|
21
|
+
|
22
|
+
def read(buffer='')
|
23
|
+
connected_error_check { @socket.recv_string buffer }
|
24
|
+
buffer
|
25
|
+
end
|
26
|
+
|
27
|
+
def write(message)
|
28
|
+
connected_error_check { @socket.send_string(message) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def read_nonblocking(buffer='')
|
32
|
+
connected_error_check { @socket.recv_string(buffer, ZMQ::NonBlocking) }
|
33
|
+
buffer
|
34
|
+
end
|
35
|
+
|
36
|
+
def write_nonblocking(message)
|
37
|
+
connected_error_check { @socket.send_string(message, ZMQ::NonBlocking) }
|
38
|
+
end
|
39
|
+
|
40
|
+
def read_multipart
|
41
|
+
messages = []
|
42
|
+
connected_error_check { @socket.recv_strings(messages) }
|
43
|
+
messages
|
44
|
+
end
|
45
|
+
|
46
|
+
def write_multipart(*parts)
|
47
|
+
connected_error_check { @socket.send_strings(parts) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def more_parts?
|
51
|
+
@socket.more_parts?
|
52
|
+
end
|
53
|
+
|
54
|
+
def pointer
|
55
|
+
@socket.socket
|
56
|
+
end
|
57
|
+
alias_method :socket, :pointer
|
58
|
+
|
59
|
+
def connected?
|
60
|
+
@connected
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.type
|
64
|
+
raise NotImplementedError, 'Subclasses must override Socket::type'
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def connected_error_check(&block)
|
70
|
+
raise SocketError, 'Not connected' unless connected?
|
71
|
+
error_check(&block)
|
72
|
+
end
|
73
|
+
|
74
|
+
def error_check(&block)
|
75
|
+
super
|
76
|
+
rescue ZMQError => e
|
77
|
+
case e.error_code
|
78
|
+
when ZMQ::ETERM then close! && TermError.raise_error(e)
|
79
|
+
when ZMQ::EAGAIN then AgainError.raise_error(e)
|
80
|
+
else SocketError.raise_error(e)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def setup!(options)
|
85
|
+
options.each do |option, value|
|
86
|
+
begin
|
87
|
+
error_check { @socket.setsockopt ZMQ.const_get(option.upcase), value }
|
88
|
+
rescue NameError => e
|
89
|
+
raise ArgumentError, "Unknown socket option '#{option}'", e.backtrace
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
SocketError = Class.new(ZMQError)
|
96
|
+
TermError = Class.new(ZMQError)
|
97
|
+
AgainError = Class.new(ZMQError)
|
98
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
|
2
|
+
module Bundesstrasse
|
3
|
+
class ReqSocket < Socket
|
4
|
+
def self.type
|
5
|
+
ZMQ::REQ
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class RepSocket < Socket
|
10
|
+
def self.type
|
11
|
+
ZMQ::REP
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class DealerSocket < Socket
|
16
|
+
def self.type
|
17
|
+
ZMQ::DEALER
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class RouterSocket < Socket
|
22
|
+
def self.type
|
23
|
+
ZMQ::ROUTER
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class PushSocket < Socket
|
28
|
+
def self.type
|
29
|
+
ZMQ::PUSH
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class PullSocket < Socket
|
34
|
+
def self.type
|
35
|
+
ZMQ::PULL
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class PubSocket < Socket
|
40
|
+
def self.type
|
41
|
+
ZMQ::PUB
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class SubSocket < Socket
|
46
|
+
def self.type
|
47
|
+
ZMQ::SUB
|
48
|
+
end
|
49
|
+
|
50
|
+
def subscribe(topic)
|
51
|
+
error_check { @socket.setsockopt(ZMQ::SUBSCRIBE, topic) }
|
52
|
+
end
|
53
|
+
|
54
|
+
def unsubscribe(topic)
|
55
|
+
error_check { @socket.setsockopt(ZMQ::UNSUBSCRIBE, topic) }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class XPubSocket < Socket
|
60
|
+
def self.type
|
61
|
+
ZMQ::XPUB
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class XSubSocket < SubSocket
|
66
|
+
def self.type
|
67
|
+
ZMQ::XSUB
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bundesstrasse
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.9
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Joel Segerlind
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-03-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ffi-rzmq
|
16
|
+
version_requirements: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: !binary |-
|
21
|
+
MA==
|
22
|
+
none: false
|
23
|
+
requirement: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: !binary |-
|
28
|
+
MA==
|
29
|
+
none: false
|
30
|
+
prerelease: false
|
31
|
+
type: :runtime
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: rspec
|
34
|
+
version_requirements: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: !binary |-
|
39
|
+
MA==
|
40
|
+
none: false
|
41
|
+
requirement: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: !binary |-
|
46
|
+
MA==
|
47
|
+
none: false
|
48
|
+
prerelease: false
|
49
|
+
type: :development
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: rake
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: !binary |-
|
57
|
+
MA==
|
58
|
+
none: false
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: !binary |-
|
64
|
+
MA==
|
65
|
+
none: false
|
66
|
+
prerelease: false
|
67
|
+
type: :development
|
68
|
+
description: Basic ZeroMQ wrapper for JRuby
|
69
|
+
email:
|
70
|
+
- joel@kogito.se
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files: []
|
74
|
+
files:
|
75
|
+
- lib/bundesstrasse.rb
|
76
|
+
- lib/bundesstrasse/context.rb
|
77
|
+
- lib/bundesstrasse/device.rb
|
78
|
+
- lib/bundesstrasse/devices.rb
|
79
|
+
- lib/bundesstrasse/errors.rb
|
80
|
+
- lib/bundesstrasse/socket.rb
|
81
|
+
- lib/bundesstrasse/sockets.rb
|
82
|
+
- lib/bundesstrasse/version.rb
|
83
|
+
homepage: https://github.com/jowl/bundesstrasse
|
84
|
+
licenses: []
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
segments:
|
94
|
+
- 0
|
95
|
+
version: !binary |-
|
96
|
+
MA==
|
97
|
+
hash: 2
|
98
|
+
none: false
|
99
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
segments:
|
104
|
+
- 0
|
105
|
+
version: !binary |-
|
106
|
+
MA==
|
107
|
+
hash: 2
|
108
|
+
none: false
|
109
|
+
requirements: []
|
110
|
+
rubyforge_project:
|
111
|
+
rubygems_version: 1.8.24
|
112
|
+
signing_key:
|
113
|
+
specification_version: 3
|
114
|
+
summary: A thin wrapper around ffi-rzmq, providing basic functionality
|
115
|
+
test_files: []
|