jubilee 0.5.0 → 1.0.0.beta1
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/README.md +57 -12
- data/Rakefile +3 -3
- data/VERSION +1 -1
- data/bin/jubilee_d +6 -3
- data/examples/client/sockjs-0.3.4.min.js +27 -0
- data/examples/client/vertxbus.js +216 -0
- data/examples/jubilee.conf.rb +18 -0
- data/jars/hazelcast-2.6.jar +0 -0
- data/jars/jackson-annotations-2.2.2.jar +0 -0
- data/jars/jackson-databind-2.2.2.jar +0 -0
- data/java/src/org/jruby/jubilee/Server.java +138 -119
- data/java/src/org/jruby/jubilee/vertx/JubileeVertx.java +38 -0
- data/jubilee.gemspec +16 -6
- data/lib/jubilee/cli.rb +30 -18
- data/lib/jubilee/configuration.rb +130 -18
- data/lib/jubilee/jubilee.jar +0 -0
- data/lib/jubilee.rb +3 -0
- data/lib/vertx/README.md +7 -0
- data/lib/vertx/buffer.rb +251 -0
- data/lib/vertx/event_bus.rb +206 -0
- data/lib/vertx/shared_data.rb +214 -0
- data/lib/vertx.rb +26 -0
- data/test/jubilee/{test_config.rb → test_configuration.rb} +2 -1
- metadata +17 -10
- data/examples/ssl/ServerTest.java +0 -19
- data/examples/ssl/webroot/index.html +0 -10
data/lib/vertx/buffer.rb
ADDED
@@ -0,0 +1,251 @@
|
|
1
|
+
# Copyright 2011-2012 the original author or authors.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'vertx/shared_data'
|
16
|
+
|
17
|
+
module Vertx
|
18
|
+
|
19
|
+
# A Buffer represents a sequence of zero or more bytes that can be written to or read from, and which expands
|
20
|
+
# as necessary to accomodate any bytes written to it.
|
21
|
+
#
|
22
|
+
# Buffers are used in many places in vert.x, for example to read/write data to/from {NetSocket}, {AsyncFile},
|
23
|
+
# {WebSocket}, {HttpClientRequest}, {HttpClientResponse}, {HttpServerRequest}, {HttpServerResponse} etc.
|
24
|
+
#
|
25
|
+
# There are two ways to write data to a Buffer: The first method involves methods that take the form set_XXX.
|
26
|
+
# These methods write data into the buffer starting at the specified position. The position does not have to be inside data that
|
27
|
+
# has already been written to the buffer; the buffer will automatically expand to encompass the position plus any data that needs
|
28
|
+
# to be written. All positions are measured in bytes and start with zero.
|
29
|
+
#
|
30
|
+
# The second method involves methods that take the form append-XXX; these methods append data at the end of the buffer.
|
31
|
+
# Methods exist to both set and append all primitive types, String and other instances of Buffer.
|
32
|
+
#
|
33
|
+
# Data can be read from a buffer by invoking methods which take the form get_XXX. These methods take a parameter
|
34
|
+
# representing the position in the Buffer from where to read data.
|
35
|
+
#
|
36
|
+
# @author {http://tfox.org Tim Fox}
|
37
|
+
class Buffer
|
38
|
+
|
39
|
+
# @private
|
40
|
+
def initialize(j_buffer)
|
41
|
+
@buffer = j_buffer
|
42
|
+
end
|
43
|
+
|
44
|
+
# Creates a new empty buffer. The {#length} of the buffer immediately after creation will be zero.
|
45
|
+
# @param initial_size_hint [FixNum] is a hint to the system for how much memory
|
46
|
+
# to initially allocate to the buffer to prevent excessive automatic re-allocations as data is written to it.
|
47
|
+
def Buffer.create(initial_size_hint = 0)
|
48
|
+
Buffer.new(org.vertx.java.core.buffer.Buffer.new(initial_size_hint))
|
49
|
+
end
|
50
|
+
|
51
|
+
# Create a new Buffer from a String
|
52
|
+
# @param str [String] The String to encode into the Buffer
|
53
|
+
# @param enc [String] Encoding to use. Defaults to "UTF-8"
|
54
|
+
def Buffer.create_from_str(str, enc = "UTF-8")
|
55
|
+
Buffer.new(org.vertx.java.core.buffer.Buffer.new(str, enc))
|
56
|
+
end
|
57
|
+
|
58
|
+
# Return a String representation of the buffer.
|
59
|
+
# @param enc [String] The encoding to use. Defaults to "UTF-8"
|
60
|
+
# @return [String] a String representation of the buffer.
|
61
|
+
def to_s(enc = "UTF-8")
|
62
|
+
@buffer.toString(enc)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Get the byte at position pos in the buffer.
|
66
|
+
# @param pos [FixNum] the position in the buffer from where to retrieve the byte
|
67
|
+
# @return [FixNum] the byte
|
68
|
+
def get_byte(pos)
|
69
|
+
@buffer.getByte(pos)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Get the FixNum represented by a sequence of bytes starting at position pos in the buffer.
|
73
|
+
# @param pos [FixNum] the position in the buffer from where to retrieve the FixNum.
|
74
|
+
# @param bytes [FixNum] the number of bytes to retrieve from position pos to create the FixNum. Valid values are 1, 2, 4 and 8.
|
75
|
+
# @return [FixNum] the FixNum
|
76
|
+
def get_fixnum(pos, bytes)
|
77
|
+
case bytes
|
78
|
+
when 1
|
79
|
+
@buffer.getByte(pos)
|
80
|
+
when 2
|
81
|
+
@buffer.getShort(pos)
|
82
|
+
when 4
|
83
|
+
@buffer.getInt(pos)
|
84
|
+
when 8
|
85
|
+
@buffer.getLong(pos)
|
86
|
+
else
|
87
|
+
raise "bytes must be 1, 2, 4, or 8"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Get the Float represented by a sequence of bytes starting at position pos in the buffer.
|
92
|
+
# @param pos [Float] the position in the buffer from where to retrieve the Float.
|
93
|
+
# @param bytes [Float] the number of bytes to retrieve from position pos to create the Float. Valid values are 4 and 8.
|
94
|
+
# @return [Float] the Float
|
95
|
+
def get_float(pos, bytes)
|
96
|
+
case bytes
|
97
|
+
when 4
|
98
|
+
@buffer.getFloat(pos)
|
99
|
+
when 8
|
100
|
+
@buffer.getDouble(pos)
|
101
|
+
else
|
102
|
+
raise "bytes must be 4 or 8"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Return bytes from the buffer interpreted as a String
|
107
|
+
# @param pos [FixNum] the position in the buffer from where to start reading
|
108
|
+
# @param end_pos [FixNum] the position in the buffer to end reading
|
109
|
+
# @param enc [String] The encoding to use
|
110
|
+
# @return [String] the String
|
111
|
+
def get_string(pos, end_pos, enc = 'UTF-8')
|
112
|
+
@buffer.getString(pos, end_pos, enc)
|
113
|
+
end
|
114
|
+
|
115
|
+
# Return bytes in the buffer as a Buffer
|
116
|
+
# @param start_pos [FixNum] - the position in this buffer from where to start the copy.
|
117
|
+
# @param end_pos [FixNum] - the copy will be made up to index end_pos - 1
|
118
|
+
# @return [Buffer] the copy
|
119
|
+
def get_buffer(pos, end_pos)
|
120
|
+
j_buff = @buffer.getBuffer(pos, end_pos)
|
121
|
+
Buffer.new(j_buff)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Appends another buffer to the end of this buffer. The buffer will expand as necessary to accomodate any bytes
|
125
|
+
# written.
|
126
|
+
# @param buff [Buffer] the buffer to append.
|
127
|
+
# @return [Buffer] a reference to self so multiple operations can be appended together.
|
128
|
+
def append_buffer(buff)
|
129
|
+
@buffer.appendBuffer(buff._to_java_buffer)
|
130
|
+
self
|
131
|
+
end
|
132
|
+
|
133
|
+
# Appends a FixNum to the end of this buffer. The buffer will expand as necessary to accomodate any bytes written.
|
134
|
+
# @param num [FixNum] the fixnum to append.
|
135
|
+
# @param bytes [FixNum] the number of bytes to write in the buffer to represent the fixnum. Valid values are 1, 2, 4 and 8.
|
136
|
+
# @return [Buffer] a reference to self so multiple operations can be appended together.
|
137
|
+
def append_fixnum(num, bytes)
|
138
|
+
case bytes
|
139
|
+
when 1
|
140
|
+
@buffer.appendByte(num)
|
141
|
+
when 2
|
142
|
+
@buffer.appendShort(num)
|
143
|
+
when 4
|
144
|
+
@buffer.appendInt(num)
|
145
|
+
when 8
|
146
|
+
@buffer.appendLong(num)
|
147
|
+
else
|
148
|
+
raise "bytes must be 1, 2, 4, or 8"
|
149
|
+
end
|
150
|
+
self
|
151
|
+
end
|
152
|
+
|
153
|
+
# Appends a Float to the end of this buffer. The buffer will expand as necessary to accomodate any bytes written.
|
154
|
+
# @param num [Float] the float to append.
|
155
|
+
# @param bytes [FixNum] the number of bytes to write in the buffer to represent the float. Valid values are 4 and 8.
|
156
|
+
# @return [Buffer] a reference to self so multiple operations can be appended together.
|
157
|
+
def append_float(num, bytes)
|
158
|
+
case bytes
|
159
|
+
when 4
|
160
|
+
@buffer.appendFloat(num)
|
161
|
+
when 8
|
162
|
+
@buffer.appendDouble(num)
|
163
|
+
else
|
164
|
+
raise "bytes must be 4 or 8"
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
# Appends a string to the end of this buffer. The buffer will expand as necessary to accomodate any bytes written.
|
169
|
+
# @param str [String] the string to append.
|
170
|
+
# @param enc [String] the encoding to use. Defaults to "UTF-8"
|
171
|
+
# @return [Buffer] a reference to self so multiple operations can be appended together.
|
172
|
+
def append_str(str, enc = "UTF-8")
|
173
|
+
@buffer.appendString(str, enc)
|
174
|
+
self
|
175
|
+
end
|
176
|
+
|
177
|
+
# Sets bytes in the buffer to a representation of a FixNum. The buffer will expand as necessary to accomodate any bytes written.
|
178
|
+
# @param pos [FixNum] - the position in the buffer from where to start writing the FixNum
|
179
|
+
# @param num [FixNum] - the FixNum to write
|
180
|
+
# @param bytes [FixNum] - the number of bytes to write to represent the FixNum. Valid values are 1, 2, 4, and 8
|
181
|
+
# @return [Buffer] a reference to self so multiple operations can be appended together.
|
182
|
+
def set_fixnum(pos, num, bytes)
|
183
|
+
case bytes
|
184
|
+
when 1
|
185
|
+
@buffer.setByte(pos, num)
|
186
|
+
when 2
|
187
|
+
@buffer.setShort(pos, num)
|
188
|
+
when 4
|
189
|
+
@buffer.setInt(pos, num)
|
190
|
+
when 8
|
191
|
+
@buffer.setLong(pos, num)
|
192
|
+
else
|
193
|
+
raise "bytes must be 1, 2, 4, or 8"
|
194
|
+
end
|
195
|
+
self
|
196
|
+
end
|
197
|
+
|
198
|
+
# Sets bytes in the buffer to a representation of a Float. The buffer will expand as necessary to accomodate any bytes written.
|
199
|
+
# @param pos [FixNum] - the position in the buffer from where to start writing the Float
|
200
|
+
# @param num [Float] - the Float to write
|
201
|
+
# @param bytes [FixNum] - the number of bytes to write to represent the Float. Valid values are 4 and 8
|
202
|
+
# @return [Buffer] a reference to self so multiple operations can be appended together.
|
203
|
+
def set_float(pos, num, bytes)
|
204
|
+
case bytes
|
205
|
+
when 4
|
206
|
+
@buffer.setFloat(pos, num)
|
207
|
+
when 8
|
208
|
+
@buffer.setDouble(pos, num)
|
209
|
+
else
|
210
|
+
raise "bytes must be 4 or 8"
|
211
|
+
end
|
212
|
+
self
|
213
|
+
end
|
214
|
+
|
215
|
+
# Sets bytes in this buffer to the bytes of the specified buffer. The buffer will expand as necessary to accomodate any bytes written.
|
216
|
+
# @param pos [FixNum] - the position in this buffer from where to start writing the buffer
|
217
|
+
# @param buff [Buffer] - the buffer to write into this buffer
|
218
|
+
# @return [Buffer] a reference to self so multiple operations can be appended together.
|
219
|
+
def set_buffer(pos, buff)
|
220
|
+
@buffer.setBytes(pos, buff._to_java_buffer)
|
221
|
+
self
|
222
|
+
end
|
223
|
+
|
224
|
+
# Set bytes in the buffer to the string encoding in the specified encoding
|
225
|
+
# @param pos [FixNum] - the position in this buffer from where to start writing the string
|
226
|
+
# @param str [String] the string
|
227
|
+
# @param enc [String] the encoding
|
228
|
+
# @return [Buffer] a reference to self so multiple operations can be appended together.
|
229
|
+
def set_string(pos, str, enc = 'UTF-8')
|
230
|
+
@buffer.setString(pos, str, enc)
|
231
|
+
self
|
232
|
+
end
|
233
|
+
|
234
|
+
# @return [FixNum] the length of this buffer, in bytes.
|
235
|
+
def length
|
236
|
+
@buffer.length
|
237
|
+
end
|
238
|
+
|
239
|
+
# Get a copy of the entire buffer.
|
240
|
+
# @return [Buffer] the copy
|
241
|
+
def copy
|
242
|
+
Buffer.new(@buffer.copy())
|
243
|
+
end
|
244
|
+
|
245
|
+
# @private
|
246
|
+
def _to_java_buffer
|
247
|
+
@buffer
|
248
|
+
end
|
249
|
+
|
250
|
+
end
|
251
|
+
end
|
@@ -0,0 +1,206 @@
|
|
1
|
+
# Copyright 2011 the original author or authors.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'rubygems'
|
16
|
+
require 'json'
|
17
|
+
|
18
|
+
module Vertx
|
19
|
+
|
20
|
+
# This class represents a distributed lightweight event bus which can encompass multiple vert.x instances.
|
21
|
+
# It is very useful for otherwise isolated vert.x application instances to communicate with each other.
|
22
|
+
#
|
23
|
+
# The event bus implements both publish / subscribe network and point to point messaging.
|
24
|
+
#
|
25
|
+
# For publish / subscribe, messages can be published to an address using one of the publish methods. An
|
26
|
+
# address is a simple String instance. Handlers are registered against an address. There can be multiple handlers
|
27
|
+
# registered against each address, and a particular handler can be registered against multiple addresses.
|
28
|
+
# The event bus will route a sent message to all handlers which are registered against that address.
|
29
|
+
|
30
|
+
# For point to point messaging, messages can be sent to an address using the send method.
|
31
|
+
# The messages will be delivered to a single handler, if one is registered on that address. If more than one
|
32
|
+
# handler is registered on the same address, Vert.x will choose one and deliver the message to that. Vert.x will
|
33
|
+
# aim to fairly distribute messages in a round-robin way, but does not guarantee strict round-robin under all
|
34
|
+
# circumstances.
|
35
|
+
#
|
36
|
+
# All messages sent over the bus are transient. On event of failure of all or part of the event bus messages
|
37
|
+
# may be lost. Applications should be coded to cope with lost messages, e.g. by resending them,
|
38
|
+
# and making application services idempotent.
|
39
|
+
#
|
40
|
+
# The order of messages received by any specific handler from a specific sender should match the order of messages
|
41
|
+
# sent from that sender.
|
42
|
+
#
|
43
|
+
# When sending a message, a reply handler can be provided. If so, it will be called when the reply from the receiver
|
44
|
+
# has been received. Reply messages can also be replied to, etc, ad infinitum.
|
45
|
+
#
|
46
|
+
# Different event bus instances can be clustered together over a network, to give a single logical event bus.
|
47
|
+
#
|
48
|
+
# When receiving a message in a handler the received object is an instance of EventBus::Message - this contains
|
49
|
+
# the actual message plus a reply method which can be used to reply to it.
|
50
|
+
#
|
51
|
+
# @author {http://tfox.org Tim Fox}
|
52
|
+
class EventBus
|
53
|
+
|
54
|
+
@@handler_map = {}
|
55
|
+
|
56
|
+
@@j_eventbus = org.jruby.jubilee.vertx.JubileeVertx.vertx().eventBus()
|
57
|
+
|
58
|
+
# Send a message on the event bus
|
59
|
+
# @param message [Hash] The message to send
|
60
|
+
# @param reply_handler [Block] An optional reply handler.
|
61
|
+
# It will be called when the reply from a receiver is received.
|
62
|
+
def EventBus.send(address, message, &reply_handler)
|
63
|
+
EventBus.send_or_pub(true, address, message, reply_handler)
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
# Publish a message on the event bus
|
68
|
+
# @param message [Hash] The message to publish
|
69
|
+
def EventBus.publish(address, message)
|
70
|
+
EventBus.send_or_pub(false, address, message)
|
71
|
+
self
|
72
|
+
end
|
73
|
+
|
74
|
+
# @private
|
75
|
+
def EventBus.send_or_pub(send, address, message, reply_handler = nil)
|
76
|
+
raise "An address must be specified" if !address
|
77
|
+
raise "A message must be specified" if message == nil
|
78
|
+
message = convert_msg(message)
|
79
|
+
if send
|
80
|
+
if reply_handler != nil
|
81
|
+
@@j_eventbus.send(address, message, InternalHandler.new(reply_handler))
|
82
|
+
else
|
83
|
+
@@j_eventbus.send(address, message)
|
84
|
+
end
|
85
|
+
else
|
86
|
+
@@j_eventbus.publish(address, message)
|
87
|
+
end
|
88
|
+
self
|
89
|
+
end
|
90
|
+
|
91
|
+
# Register a handler.
|
92
|
+
# @param address [String] The address to register for. Messages sent to that address will be
|
93
|
+
# received by the handler. A single handler can be registered against many addresses.
|
94
|
+
# @param local_only [Boolean] If true then handler won't be propagated across cluster
|
95
|
+
# @param message_hndlr [Block] The handler
|
96
|
+
# @return [FixNum] id of the handler which can be used in {EventBus.unregister_handler}
|
97
|
+
def EventBus.register_handler(address, local_only = false, &message_hndlr)
|
98
|
+
raise "An address must be specified" if !address
|
99
|
+
raise "A message handler must be specified" if !message_hndlr
|
100
|
+
internal = InternalHandler.new(message_hndlr)
|
101
|
+
if local_only
|
102
|
+
@@j_eventbus.registerLocalHandler(address, internal)
|
103
|
+
else
|
104
|
+
@@j_eventbus.registerHandler(address, internal)
|
105
|
+
end
|
106
|
+
id = java.util.UUID.randomUUID.toString
|
107
|
+
@@handler_map[id] = [address, internal]
|
108
|
+
id
|
109
|
+
end
|
110
|
+
|
111
|
+
# Registers a handler against a uniquely generated address, the address is returned as the id
|
112
|
+
# received by the handler. A single handler can be registered against many addresses.
|
113
|
+
# @param local_only [Boolean] If true then handler won't be propagated across cluster
|
114
|
+
# @param message_hndlr [Block] The handler
|
115
|
+
# @return [FixNum] id of the handler which can be used in {EventBus.unregister_handler}
|
116
|
+
def EventBus.register_simple_handler(local_only = false, &message_hndlr)
|
117
|
+
raise "A message handler must be specified" if !message_hndlr
|
118
|
+
internal = InternalHandler.new(message_hndlr)
|
119
|
+
id = java.util.UUID.randomUUID.toString
|
120
|
+
if local_only
|
121
|
+
@@j_eventbus.registerLocalHandler(id, internal)
|
122
|
+
else
|
123
|
+
@@j_eventbus.registerHandler(id, internal)
|
124
|
+
end
|
125
|
+
@@handler_map[id] = [id, internal]
|
126
|
+
id
|
127
|
+
end
|
128
|
+
|
129
|
+
# Unregisters a handler
|
130
|
+
# @param handler_id [FixNum] The id of the handler to unregister. Returned from {EventBus.register_handler}
|
131
|
+
def EventBus.unregister_handler(handler_id)
|
132
|
+
raise "A handler_id must be specified" if !handler_id
|
133
|
+
tuple = @@handler_map.delete(handler_id)
|
134
|
+
raise "Cannot find handler for id #{handler_id}" if !tuple
|
135
|
+
@@j_eventbus.unregisterHandler(tuple.first, tuple.last)
|
136
|
+
self
|
137
|
+
end
|
138
|
+
|
139
|
+
# @private
|
140
|
+
def EventBus.convert_msg(message)
|
141
|
+
if message.is_a? Hash
|
142
|
+
message = org.vertx.java.core.json.JsonObject.new(JSON.generate(message))
|
143
|
+
elsif message.is_a? Buffer
|
144
|
+
message = message._to_java_buffer
|
145
|
+
elsif message.is_a? Fixnum
|
146
|
+
message = java.lang.Long.new(message)
|
147
|
+
elsif message.is_a? Float
|
148
|
+
message = java.lang.Double.new(message)
|
149
|
+
end
|
150
|
+
message
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
# @private
|
156
|
+
class InternalHandler
|
157
|
+
include org.vertx.java.core.Handler
|
158
|
+
|
159
|
+
def initialize(hndlr)
|
160
|
+
@hndlr = hndlr
|
161
|
+
end
|
162
|
+
|
163
|
+
def handle(message)
|
164
|
+
@hndlr.call(Message.new(message))
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
# Represents a message received from the event bus
|
169
|
+
# @author {http://tfox.org Tim Fox}
|
170
|
+
class Message
|
171
|
+
|
172
|
+
attr_reader :body
|
173
|
+
|
174
|
+
# @private
|
175
|
+
def initialize(message)
|
176
|
+
|
177
|
+
@j_del = message
|
178
|
+
if message.body.is_a? org.vertx.java.core.json.JsonObject
|
179
|
+
@body = JSON.parse(message.body.encode)
|
180
|
+
elsif message.body.is_a? org.vertx.java.core.buffer.Buffer
|
181
|
+
@body = Buffer.new(message.body)
|
182
|
+
else
|
183
|
+
@body = message.body
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# Reply to this message. If the message was sent specifying a receipt handler, that handler will be
|
188
|
+
# called when it has received a reply. If the message wasn't sent specifying a receipt handler
|
189
|
+
# this method does nothing.
|
190
|
+
# Replying to a message this way is equivalent to sending a message to an address which is the same as the message id
|
191
|
+
# of the original message.
|
192
|
+
# @param [Hash] Message send as reply
|
193
|
+
def reply(reply, &reply_handler)
|
194
|
+
raise "A reply message must be specified" if reply == nil
|
195
|
+
reply = EventBus.convert_msg(reply)
|
196
|
+
if reply_handler != nil
|
197
|
+
@j_del.reply(reply, InternalHandler.new(reply_handler))
|
198
|
+
else
|
199
|
+
@j_del.reply(reply)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
|
@@ -0,0 +1,214 @@
|
|
1
|
+
# Copyright 2011 the original author or authors.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'delegate'
|
16
|
+
|
17
|
+
module Vertx
|
18
|
+
|
19
|
+
# Sometimes it is desirable to share immutable data between different event loops, for example to implement a
|
20
|
+
# cache of data.
|
21
|
+
#
|
22
|
+
# This class allows data structures to be looked up and used from different event loops.
|
23
|
+
# The data structures themselves will only allow certain data types to be stored into them. This shields the
|
24
|
+
# user from worrying about any thread safety issues might occur if mutable objects were shared between event loops.
|
25
|
+
#
|
26
|
+
# The following types can be stored in a shareddata data structure:
|
27
|
+
#
|
28
|
+
# String
|
29
|
+
# FixNum
|
30
|
+
# Float
|
31
|
+
# {Buffer} this will be automatically copied, and the copy will be stored in the structure.
|
32
|
+
#
|
33
|
+
# @author {http://tfox.org Tim Fox}
|
34
|
+
class SharedData
|
35
|
+
|
36
|
+
@@j_sd = org.jruby.jubilee.vertx.JubileeVertx.vertx().sharedData()
|
37
|
+
|
38
|
+
# Return a Hash with the specific name. All invocations of this method with the same value of name
|
39
|
+
# are guaranteed to return the same Hash instance.
|
40
|
+
# @param [String] key. Get the hash with the key.
|
41
|
+
# @return [Hash] the hash.
|
42
|
+
def SharedData.get_hash(key)
|
43
|
+
map = @@j_sd.getMap(key)
|
44
|
+
SharedHash.new(map)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Return a Set with the specific name. All invocations of this method with the same value of name
|
48
|
+
# are guaranteed to return the same Set instance.
|
49
|
+
# @param [String] key. Get the set with the key.
|
50
|
+
# @return [SharedSet] the set.
|
51
|
+
def SharedData.get_set(key)
|
52
|
+
set = @@j_sd.getSet(key)
|
53
|
+
SharedSet.new(set)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Remove the hash
|
57
|
+
# @param [String] key. The key of the hash.
|
58
|
+
def SharedData.remove_hash(key)
|
59
|
+
@@j_sd.removeMap(key)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Remove the set
|
63
|
+
# @param [String] key. The key of the set.
|
64
|
+
def SharedData.remove_set(key)
|
65
|
+
@@j_sd.removeSet(key)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Convert to corresponding Java objects
|
69
|
+
# And make copies where appropriate (the underlying java map will also make copies for some data types too)
|
70
|
+
# @private
|
71
|
+
def SharedData.check_obj(obj)
|
72
|
+
if obj.is_a?(Buffer)
|
73
|
+
obj = obj._to_java_buffer
|
74
|
+
end
|
75
|
+
obj
|
76
|
+
end
|
77
|
+
|
78
|
+
# @private
|
79
|
+
class SharedHash < DelegateClass(Hash)
|
80
|
+
|
81
|
+
def initialize(hash)
|
82
|
+
@hash = hash
|
83
|
+
# Pass the object to be delegated to the superclass.
|
84
|
+
super(@hash)
|
85
|
+
end
|
86
|
+
|
87
|
+
def []=(key, val)
|
88
|
+
key = SharedData.check_obj(key)
|
89
|
+
val = SharedData.check_obj(val)
|
90
|
+
super(key, val)
|
91
|
+
end
|
92
|
+
|
93
|
+
alias store []=
|
94
|
+
|
95
|
+
def [](key)
|
96
|
+
# We call the java class directly
|
97
|
+
obj = @hash.get(key)
|
98
|
+
obj = Buffer.new(obj) if obj.is_a? org.vertx.java.core.buffer.Buffer
|
99
|
+
obj
|
100
|
+
end
|
101
|
+
|
102
|
+
def ==(other)
|
103
|
+
if other.is_a?(SharedHash)
|
104
|
+
@hash.equal?(other._to_java_map)
|
105
|
+
else
|
106
|
+
false
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def _to_java_map
|
111
|
+
@hash
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
#
|
117
|
+
# @private
|
118
|
+
class SharedSet
|
119
|
+
|
120
|
+
# @private
|
121
|
+
def initialize(j_set)
|
122
|
+
@j_set = j_set
|
123
|
+
end
|
124
|
+
|
125
|
+
def ==(other)
|
126
|
+
if other.is_a?(SharedSet)
|
127
|
+
@j_set.equal?(other._to_java_set)
|
128
|
+
else
|
129
|
+
false
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Add an object to the set
|
134
|
+
# @param [Object] obj. The object to add
|
135
|
+
# @return [SharedSet} self
|
136
|
+
def add(obj)
|
137
|
+
obj = SharedData.check_obj(obj)
|
138
|
+
@j_set.add(obj)
|
139
|
+
self
|
140
|
+
end
|
141
|
+
|
142
|
+
# Add an object to the set
|
143
|
+
# @param [Object] obj. The object to add
|
144
|
+
# @return [SharedSet] self if the object is not already in the set, otherwise nil
|
145
|
+
def add?(obj)
|
146
|
+
obj = SharedData.check_obj(obj)
|
147
|
+
if !@j_set.contains(obj)
|
148
|
+
@j_set.add(obj)
|
149
|
+
self
|
150
|
+
else
|
151
|
+
nil
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# Clear the set
|
156
|
+
def clear
|
157
|
+
@j_set.clear
|
158
|
+
end
|
159
|
+
|
160
|
+
# Delete an object from the set
|
161
|
+
# @param [Object] obj. The object to delete
|
162
|
+
def delete(obj)
|
163
|
+
@j_set.remove(obj)
|
164
|
+
end
|
165
|
+
|
166
|
+
# Delete an object from the set
|
167
|
+
# @param [Object] obj. The object to delete
|
168
|
+
# @return [SharedSet] self if the object was in the set before the remove, nil otherwise.
|
169
|
+
def delete?(obj)
|
170
|
+
if @j_set.contains(obj)
|
171
|
+
@j_set.remove(obj)
|
172
|
+
self
|
173
|
+
else
|
174
|
+
nil
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
# Call the block for every element of the set
|
179
|
+
# @param [Blovk] block. The block to call.
|
180
|
+
def each(&block)
|
181
|
+
iter = @j_set.iterator
|
182
|
+
while iter.hasNext do
|
183
|
+
obj = iter.next
|
184
|
+
obj = Buffer.new(obj) if obj.is_a? org.vertx.java.core.buffer.Buffer
|
185
|
+
block.call(obj)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
# @return [Boolean] true if the set is empty
|
190
|
+
def empty?
|
191
|
+
@j_set.isEmpty
|
192
|
+
end
|
193
|
+
|
194
|
+
# Does the set contain an element?
|
195
|
+
# @param [Object] obj, the object to check if the set contains
|
196
|
+
# @return [Boolean] true if the object is contained in the set
|
197
|
+
def include?(obj)
|
198
|
+
obj = obj._to_java_buffer if obj.is_a? Buffer
|
199
|
+
@j_set.contains(obj)
|
200
|
+
end
|
201
|
+
|
202
|
+
# @return [FixNum] The number of elements in the set
|
203
|
+
def size
|
204
|
+
@j_set.size
|
205
|
+
end
|
206
|
+
|
207
|
+
# @private
|
208
|
+
def _to_java_set
|
209
|
+
@j_set
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
data/lib/vertx.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# Copyright 2011 the original author or authors.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
include Java
|
16
|
+
|
17
|
+
require 'vertx/buffer'
|
18
|
+
require 'vertx/event_bus'
|
19
|
+
|
20
|
+
# This is the module for vertx related feature like EventBus and SharedData,
|
21
|
+
# these features are built into jubilee server, by requiring 'vertx' in your
|
22
|
+
# rack application, you get access to the functionalities offered by vertx
|
23
|
+
# platform.
|
24
|
+
|
25
|
+
module Vertx
|
26
|
+
end
|