0mq 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 773f90d7147a3cbb26b3a5d5133c16e36ec81da5
4
+ data.tar.gz: 5a241ddd18035b6d933ae28ac328062351d31d48
5
+ SHA512:
6
+ metadata.gz: 6c986fc018852a26c27241a1f256f20f6066177d9c4590b1da43f35240c33b50522e0cf1e13aa0afe7f9e24027650f3fc424c3d7a8ba7626e8dcd3cbd3c306b3
7
+ data.tar.gz: d8d5fbc4bd75afa98b4a8101335eda0744a5cd21a73f699c71f3f12650ebd9746bf48b0801bbc71f688d1953f07e59ac8f35c548f88bd793c18ff5d7f9c05e54
@@ -0,0 +1,7 @@
1
+ require 'ffi-rzmq-core'
2
+
3
+ require_relative '0mq/error_map'
4
+
5
+ require_relative '0mq/context'
6
+ require_relative '0mq/socket'
7
+ require_relative '0mq/proxy'
@@ -0,0 +1,15 @@
1
+
2
+ module ZMQ
3
+
4
+ class Context
5
+ attr_reader :ptr
6
+
7
+ def initialize
8
+ @ptr = LibZMQ.zmq_ctx_new
9
+ end
10
+
11
+ end
12
+
13
+ DefaultContext = Context.new
14
+
15
+ end
@@ -0,0 +1,20 @@
1
+
2
+ module ZMQ
3
+
4
+ ErrorMap = Hash.new
5
+
6
+ Errno.constants
7
+ .map { |x| Errno.const_get x }
8
+ .select { |x| x.is_a?(Class) && x < SystemCallError }
9
+ .each { |x| ErrorMap[x.const_get(:Errno)] = x }
10
+
11
+ def self.error_check(adjust_backtrace=false)
12
+ errno = LibZMQ.zmq_errno
13
+ return true if errno == 25
14
+
15
+ # str = LibZMQ.zmq_strerror(errno).read_string
16
+ str = ''
17
+ raise ErrorMap[errno], str, caller[0...-2]
18
+ end
19
+
20
+ end
@@ -0,0 +1,19 @@
1
+
2
+ module ZMQ
3
+
4
+ class Proxy
5
+
6
+ def initialize(frontend, backend, capture = nil)
7
+ @frontend = frontend.nil? ? nil : frontend.ptr
8
+ @backend = backend.nil? ? nil : backend.ptr
9
+ @capture = capture.nil? ? nil : capture.ptr
10
+ end
11
+
12
+ # Block the current thread with the event loop of the proxy
13
+ def run
14
+ LibZMQ.zmq_proxy @frontend, @backend, @capture
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,259 @@
1
+
2
+ module ZMQ
3
+
4
+ class Socket
5
+ attr_reader :ptr
6
+ attr_reader :context
7
+ attr_reader :type
8
+
9
+ def initialize(type, context:ZMQ::DefaultContext)
10
+ @context = context
11
+ @type = type
12
+ @ptr = LibZMQ.zmq_socket @context.ptr, @type
13
+
14
+ @msgptr = FFI::MemoryPointer.new LibZMQ::Message.size, 1, false
15
+
16
+ ObjectSpace.define_finalizer self,
17
+ self.class.finalizer(@socket, Process.pid)
18
+ end
19
+
20
+ # Close the socket
21
+ def close
22
+ if @ptr
23
+ ObjectSpace.undefine_finalizer self
24
+ @temp_buffers.clear if @temp_buffers
25
+
26
+ rc = LibZMQ.zmq_close @ptr
27
+ ZMQ.error_check true if rc==-1
28
+
29
+ @ptr = nil
30
+ end
31
+ end
32
+
33
+ # Create a safe finalizer for the socket ptr to close on GC of the object
34
+ def self.finalizer(ptr, pid)
35
+ Proc.new { LibZMQ.zmq_close ptr if Process.pid == pid }
36
+ end
37
+
38
+ # Get the socket type name as a symbol
39
+ def type_sym
40
+ ZMQ::SocketTypeNameMap[type].to_sym
41
+ end
42
+
43
+ # Bind to an endpoint
44
+ def bind(endpoint)
45
+ rc = LibZMQ.zmq_bind @ptr, endpoint
46
+ ZMQ.error_check true if rc==-1
47
+ end
48
+
49
+ # Connect to an endpoint
50
+ def connect(endpoint)
51
+ rc = LibZMQ.zmq_connect @ptr, endpoint
52
+ ZMQ.error_check true if rc==-1
53
+ end
54
+
55
+ # Unbind from an endpoint
56
+ def unbind(endpoint)
57
+ rc = LibZMQ.zmq_unbind @ptr, endpoint
58
+ ZMQ.error_check true if rc==-1
59
+ end
60
+
61
+ # Disconnect to an endpoint
62
+ def disconnect(endpoint)
63
+ rc = LibZMQ.zmq_disconnect @ptr, endpoint
64
+ ZMQ.error_check true if rc==-1
65
+ end
66
+
67
+ # Send a string to the socket
68
+ def send_string(string, flags = 0)
69
+ size = string.respond_to?(:bytesize) ? string.bytesize : string.size
70
+ @msgbuf = LibC.malloc size
71
+ @msgbuf.write_string string, size
72
+
73
+ rc = LibZMQ.zmq_msg_init_data @msgptr, @msgbuf, size, LibC::Free, nil
74
+ ZMQ.error_check true if rc==-1
75
+
76
+ rc = LibZMQ.zmq_sendmsg @ptr, @msgptr, flags
77
+ ZMQ.error_check true if rc==-1
78
+
79
+ rc = LibZMQ.zmq_msg_close @msgptr
80
+ ZMQ.error_check true if rc==-1
81
+ end
82
+
83
+ # Receive a string from the socket
84
+ def recv_string(flags = 0)
85
+ rc = LibZMQ.zmq_msg_init @msgptr
86
+ ZMQ.error_check true if rc==-1
87
+
88
+ rc = LibZMQ.zmq_recvmsg @ptr, @msgptr, flags
89
+ ZMQ.error_check true if rc==-1
90
+
91
+ str = LibZMQ.zmq_msg_data(@msgptr)
92
+ .read_string(LibZMQ.zmq_msg_size(@msgptr))
93
+
94
+ rc = LibZMQ.zmq_msg_close @msgptr
95
+ ZMQ.error_check true if rc==-1
96
+
97
+ str
98
+ end
99
+
100
+ # Send a multipart message as an array of strings
101
+ def send_array(ary)
102
+ last = ary.last
103
+
104
+ ary[0...-1].each { |str| send_string str, ZMQ::SNDMORE }
105
+ send_string last
106
+ end
107
+
108
+ # Receive a multipart message as an array of strings
109
+ def recv_array
110
+ [].tap do |ary|
111
+ loop do
112
+ ary << recv_string
113
+ break unless get_opt(ZMQ::RCVMORE)
114
+ end
115
+ end
116
+ end
117
+
118
+ # Set a socket option
119
+ def set_opt(option, value)
120
+ type = @@option_types.fetch(option) \
121
+ { raise ArgumentError, "Unknown option: #{option}" }
122
+
123
+ unless type == :string
124
+ if type == :bool
125
+ valptr = FFI::MemoryPointer.new(:int)
126
+ valptr.write_int(value ? 1 : 0)
127
+ else
128
+ valptr = FFI::MemoryPointer.new(type)
129
+ valptr.send :"write_#{type}", value
130
+ end
131
+ value = valptr
132
+ end
133
+
134
+ rc = LibZMQ.zmq_setsockopt @ptr, option, value, value.size
135
+ ZMQ.error_check true if rc==-1
136
+
137
+ value
138
+ end
139
+
140
+ # Get a socket option
141
+ def get_opt(option)
142
+ type = @@option_types.fetch(option) \
143
+ { raise ArgumentError, "Unknown option: #{option}" }
144
+
145
+ value, size = get_opt_pointers type
146
+
147
+ rc = LibZMQ.zmq_getsockopt @ptr, option, value, size
148
+ ZMQ.error_check true if rc==-1
149
+
150
+ if type == :string
151
+ value.read_string(size.read_int-1)
152
+ elsif type == :bool
153
+ value.read_int == 1
154
+ else
155
+ value.send :"read_#{type}"
156
+ end
157
+ end
158
+
159
+ private
160
+
161
+ def get_opt_pointers(type)
162
+ type = :int if type == :bool
163
+
164
+ @temp_buffers ||= { string: [
165
+ FFI::MemoryPointer.new(255),
166
+ FFI::MemoryPointer.new(:size_t).write_int(255)
167
+ ] }
168
+ @temp_buffers[type] ||= [
169
+ FFI::MemoryPointer.new(type),
170
+ FFI::MemoryPointer.new(:size_t).write_int(FFI.type_size(type))
171
+ ]
172
+ end
173
+
174
+ @@option_types = {
175
+ # Get options
176
+ ZMQ::RCVMORE => :bool,
177
+ ZMQ::RCVHWM => :int,
178
+ ZMQ::AFFINITY => :uint64,
179
+ ZMQ::IDENTITY => :string,
180
+ ZMQ::RATE => :int,
181
+ ZMQ::RECOVERY_IVL => :int,
182
+ ZMQ::SNDBUF => :int,
183
+ ZMQ::RCVBUF => :int,
184
+ ZMQ::LINGER => :int,
185
+ ZMQ::RECONNECT_IVL => :int,
186
+ ZMQ::RECONNECT_IVL_MAX => :int,
187
+ ZMQ::BACKLOG => :int,
188
+ ZMQ::MAXMSGSIZE => :int64,
189
+ ZMQ::MULTICAST_HOPS => :int,
190
+ ZMQ::RCVTIMEO => :int,
191
+ ZMQ::SNDTIMEO => :int,
192
+ ZMQ::IPV6 => :bool,
193
+ ZMQ::IPV4ONLY => :bool,
194
+ ZMQ::IMMEDIATE => :bool,
195
+ ZMQ::FD => :int,
196
+ ZMQ::EVENTS => :int,
197
+ ZMQ::LAST_ENDPOINT => :string,
198
+ ZMQ::TCP_KEEPALIVE => :int,
199
+ ZMQ::TCP_KEEPALIVE_IDLE => :int,
200
+ ZMQ::TCP_KEEPALIVE_CNT => :int,
201
+ ZMQ::TCP_KEEPALIVE_INTVL => :int,
202
+ ZMQ::MECHANISM => :int,
203
+ ZMQ::PLAIN_SERVER => :int,
204
+ ZMQ::PLAIN_USERNAME => :string,
205
+ ZMQ::PLAIN_PASSWORD => :string,
206
+ ZMQ::CURVE_PUBLICKEY => :string,
207
+ ZMQ::CURVE_SECRETKEY => :string,
208
+ ZMQ::CURVE_SERVERKEY => :string,
209
+ ZMQ::ZAP_DOMAIN => :string,
210
+ }.merge({
211
+ # Set options
212
+ ZMQ::SNDHWM => :int,
213
+ ZMQ::RCVHWM => :int,
214
+ ZMQ::AFFINITY => :uint64,
215
+ ZMQ::SUBSCRIBE => :string,
216
+ ZMQ::UNSUBSCRIBE => :string,
217
+ ZMQ::IDENTITY => :string,
218
+ ZMQ::RATE => :int,
219
+ ZMQ::RECOVERY_IVL => :int,
220
+ ZMQ::SNDBUF => :int,
221
+ ZMQ::RCVBUF => :int,
222
+ ZMQ::LINGER => :int,
223
+ ZMQ::RECONNECT_IVL => :int,
224
+ ZMQ::RECONNECT_IVL_MAX => :int,
225
+ ZMQ::RECONNECT_IVL => :int,
226
+ ZMQ::BACKLOG => :int,
227
+ ZMQ::MAXMSGSIZE => :int64,
228
+ ZMQ::MULTICAST_HOPS => :int,
229
+ ZMQ::RCVTIMEO => :int,
230
+ ZMQ::SNDTIMEO => :int,
231
+ ZMQ::IPV6 => :bool,
232
+ ZMQ::IPV4ONLY => :bool,
233
+ ZMQ::IMMEDIATE => :bool,
234
+ ZMQ::ROUTER_HANDOVER => :int,
235
+ ZMQ::ROUTER_MANDATORY => :int,
236
+ ZMQ::ROUTER_RAW => :int,
237
+ ZMQ::PROBE_ROUTER => :int,
238
+ ZMQ::XPUB_VERBOSE => :int,
239
+ ZMQ::REQ_CORRELATE => :int,
240
+ ZMQ::REQ_RELAXED => :int,
241
+ ZMQ::TCP_KEEPALIVE => :int,
242
+ ZMQ::TCP_KEEPALIVE_IDLE => :int,
243
+ ZMQ::TCP_KEEPALIVE_CNT => :int,
244
+ ZMQ::TCP_KEEPALIVE_INTVL => :int,
245
+ ZMQ::TCP_ACCEPT_FILTER => :string,
246
+ ZMQ::PLAIN_SERVER => :int,
247
+ ZMQ::PLAIN_USERNAME => :string,
248
+ ZMQ::PLAIN_PASSWORD => :string,
249
+ ZMQ::CURVE_SERVER => :int,
250
+ ZMQ::CURVE_PUBLICKEY => :string,
251
+ ZMQ::CURVE_SECRETKEY => :string,
252
+ ZMQ::CURVE_SERVERKEY => :string,
253
+ ZMQ::ZAP_DOMAIN => :string,
254
+ ZMQ::CONFLATE => :bool,
255
+ })
256
+
257
+ end
258
+
259
+ end
metadata ADDED
@@ -0,0 +1,148 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: 0mq
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Joe McIlvain
8
+ - Alex McLain
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-02-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ffi-rzmq-core
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: bundler
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: pry
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: pry-rescue
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rspec
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: fivemat
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ description: A Ruby-like wrapper for ffi-rzmq-core (ZeroMQ)
113
+ email: joe.eli.mac@gmail.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - lib/0mq.rb
119
+ - lib/0mq/context.rb
120
+ - lib/0mq/error_map.rb
121
+ - lib/0mq/proxy.rb
122
+ - lib/0mq/socket.rb
123
+ homepage: https://github.com/jemc/0mq/
124
+ licenses:
125
+ - MIT
126
+ metadata: {}
127
+ post_install_message:
128
+ rdoc_options: []
129
+ require_paths:
130
+ - lib
131
+ required_ruby_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ requirements: []
142
+ rubyforge_project:
143
+ rubygems_version: 2.2.0
144
+ signing_key:
145
+ specification_version: 4
146
+ summary: 0mq
147
+ test_files: []
148
+ has_rdoc: