rxio 0.10.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e280e9488e6a0e8772dc1207a4f9ef2596a75800
4
+ data.tar.gz: a93e714f68bbf8b1a2b76d5eec9b0944489f8e2d
5
+ SHA512:
6
+ metadata.gz: ab635aa9b48db9a6fd09d480982187f9ecc7b272d5a94b88c2dd89d5ae960e46c7fe00c55f48ffde01da744ca0c1147c1f615a937ac3558964b106f5ebe7e425
7
+ data.tar.gz: 06a5b6087190d7ab29e9273b7c651f2c91b09aa9e9cc51782b7c6eb4899ebd59fc68483c18f625a227e93df0fa14ff844da2016643139ed8fe38e2008490a827
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ .idea
2
+ Gemfile.lock
3
+ pkg
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Paul Duncan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,237 @@
1
+ # RxIO
2
+
3
+ Reactive Sockets for Ruby
4
+
5
+ ## Presentation
6
+
7
+ This library is an implementation of the [Reactor Pattern](https://en.wikipedia.org/wiki/Reactor_pattern) for Ruby Sockets.
8
+ This allows easy development of fast, non-blocking services.
9
+
10
+ ## Installation
11
+
12
+ ### Gemfile
13
+ ```ruby
14
+ gem 'rxio'
15
+ ```
16
+
17
+ ### Terminal
18
+ ```bash
19
+ gem install -V rxio
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ A simple service is created by spawning an instance of the *RxIO::Service* class, passing a *Handler Module* as argument to its constructor and calling it's _run_ method.
25
+
26
+ This will execute the service's main loop. The handler module provides the specific protocol implementation through a set of methods.
27
+
28
+ The _run_ method is blocking and will only return after the service has terminated.
29
+
30
+ A _stop_ method is also provided to request the service to terminate.
31
+
32
+ ### Running in the background
33
+
34
+ While the _run_ / _stop_ methods offer a simple way to implement a single service within the current thread, some situations may require the wrapping of the service in a separate thread.
35
+
36
+ A dedicated interface is provided for exactly this: _startup_ / _shutdown_
37
+
38
+ #### *startup*
39
+
40
+ Calling this method will spawn a new thread around the _run_ method, effectively starting the service in the 'background'.
41
+
42
+ #### *shutdown*
43
+
44
+ Calling _shutdown_ will request the service to terminate (via the _stop_ method) and wait for the thread to complete (join).
45
+ Once this method returns, the service has completely terminated (thread dead, all clients disconnected).
46
+
47
+ ### Handler Interface
48
+
49
+ The following is a list of methods that should be implemented by the handler module in order to provide a valid interface to the RxIO::Service class that will use it.
50
+
51
+ #### *filter_input* _client_, _chunk_
52
+
53
+ This method is called any time a chunk of data is received from a client.
54
+ Its purpose is usually to filter protocol data and re-assemble messages.
55
+ Complete messages can be enqueued for processing by pushing them into the *client[:msgs]* array.
56
+
57
+ #### *handle_msg* _client_, _msg_
58
+
59
+ Messages in the *client[:msgs]* array are regularly de-queued and passed to the *handle_msg* method for handling.
60
+ This is usually the entry point to most of the service logic.
61
+
62
+ #### (OPTIONAL) *on_join* _client_
63
+
64
+ As soon as a client is registered by the service, it is passed as argument to the _on_join_ method of the handler module (if available).
65
+ This allows the handler module to perform any necessary initialization tasks related to this client.
66
+
67
+ #### (OPTIONAL) *on_drop* _client_
68
+
69
+ Called by the service whenever a client is about to be disconnected (if available).
70
+ This method should release any resources used by the client.
71
+
72
+ #### (OPTIONAL) *send_msg* _client_, _msg_
73
+
74
+ This method should wrap the message supplied as argument according to the desired protocol, and then add the result to the output buffer.
75
+ While not actually required by the service class, this method should be considered a best-practice for users to encapsulate data according to a protocol.
76
+
77
+ ### Handler Base
78
+
79
+ A base module is provided to facilitate implementation of new services and protocols.
80
+ The *RxIO::HandlerBase* module should be extended by the service handler module.
81
+ It provides two simple I/O methods:
82
+
83
+ #### *write* _client_, _*data_
84
+
85
+ Used to send one or more data chunks to a client.
86
+ This method pushes the chunk(s) to the output buffer, to be later sent to the client.
87
+
88
+ This method is *thread-safe* - while in most cases it will be called from within the main service loop (generally as a consequence of service logic in _handle_msg_), it is perfectly safe to call from any other thread. This can be useful in situations where a service might generate messages for the client _outside_ of the normal request-response cycle (such as an event-subscription service).
89
+
90
+ Note: this method does not perform any encoding or transformation on the data. It is the user's responsibility to provide protocol encoding, usually through the _send_msg_ method.
91
+
92
+ #### *buffer_input*, _client_, _chunk_
93
+
94
+ Used to add a data chunk to the client's input buffer.
95
+
96
+ ### Provided Filters
97
+
98
+ Some generic filters are provided as part of the *RxIO::IOFilters* module.
99
+ These can be extended directly in a custom service handler module to provide immediate handling of a variety of protocol types.
100
+ Most of the provided filters usually provide the _filter_input_ and _send_msg_ methods.
101
+
102
+ #### Binary-Delimiter (BinDelim)
103
+
104
+ The binary-delimiter filter is the simplest of all filters, splitting messages according to a fixed binary string.
105
+ After extending the *RxIO::IOFilters::BinDelim* module, the _msg_delim_ method should be called with the desired binary string as argument.
106
+
107
+ ##### Example
108
+
109
+ ```ruby
110
+ require 'rxio'
111
+
112
+ # Custom Service 'Foo'
113
+ class FooService < RxIO::Service
114
+
115
+ # Construct
116
+ def initialize addr, port
117
+ super addr, port, FooHandler
118
+ end
119
+
120
+ # Foo Service Handler Module
121
+ module FooHandler
122
+
123
+ # Extend BinDelim I/O Filter
124
+ extend RxIO::IOFilters::BinDelim
125
+
126
+ # Set Message Delimiter
127
+ msg_delim "\n"
128
+
129
+ # ...
130
+ end
131
+ end
132
+ ```
133
+
134
+ #### Message-Size (MsgSize)
135
+
136
+ the message-size filter is another very basic generic protocol filter, splitting messages according to a _4-byte unsigned big-endian integer_ *size* field, which prefixes every message and indicates its length in bytes.
137
+
138
+ ##### Example
139
+
140
+ ```ruby
141
+ require 'rxio'
142
+
143
+ # Custom Service 'Foo'
144
+ class FooService < RxIO::Service
145
+
146
+ # Construct
147
+ def initialize addr, port
148
+ super addr, port, FooHandler
149
+ end
150
+
151
+ # Foo Service Handler Module
152
+ module FooHandler
153
+
154
+ # Extend MsgSize I/O Filter
155
+ extend RxIO::IOFilters::MsgSize
156
+
157
+ # ...
158
+ end
159
+ end
160
+ ```
161
+
162
+ ## Examples
163
+
164
+ ### A simple echo service
165
+
166
+ ```ruby
167
+ #!/usr/bin/env ruby
168
+
169
+ require 'rxio'
170
+
171
+ # Echo Service Class
172
+ class EchoService < RxIO::Service
173
+
174
+ # Defaults
175
+ DEFAULT_ADDR = '0.0.0.0'
176
+ DEFAULT_PORT = 4444
177
+
178
+ # Construct
179
+ def initialize
180
+ super DEFAULT_ADDR, DEFAULT_PORT, EchoHandler
181
+ end
182
+
183
+ # Echo Service Handler Module
184
+ module EchoHandler
185
+
186
+ # Extend BinDelim I/O Filter
187
+ extend RxIO::IOFilters::BinDelim
188
+
189
+ # Set Message Delimiter
190
+ msg_delim "\n"
191
+
192
+ # On Join
193
+ def self.on_join client
194
+ puts "Client connected: #{client[:peer][:name]}:#{client[:peer][:port]}"
195
+ end
196
+
197
+ # On Drop
198
+ def self.on_drop client
199
+ puts "Client dropped: #{client[:peer][:name]}:#{client[:peer][:port]}"
200
+ end
201
+
202
+ # Handle Message
203
+ def self.handle_msg client, msg
204
+ msg.chomp! # Clean spurious \r
205
+ puts "Got message from client: #{client[:peer][:name]}:#{client[:peer][:port]} -> \"#{msg}\""
206
+ send_msg client, msg # Echo message back to client
207
+ end
208
+ end
209
+ end
210
+
211
+ # Run the service
212
+ es = EchoService.new
213
+ es.run
214
+ ```
215
+
216
+ ### Running a service in the background
217
+
218
+ ```ruby
219
+ # ...
220
+
221
+ # Run the service in the background
222
+ puts 'Service is starting up...'
223
+ es = EchoService.new
224
+ es.startup
225
+ puts 'Service is online!'
226
+
227
+ # Do something while the service is running...
228
+
229
+ # Shutdown the service
230
+ es.shutdown
231
+ puts 'Service has terminated!'
232
+
233
+ ```
234
+
235
+ ## License
236
+
237
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ task :default => :spec
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs << 'test'
8
+ end
@@ -0,0 +1,31 @@
1
+ # RxIO
2
+ # by Eresse <eresse@eresse.net>
3
+
4
+ # RxIO Module
5
+ module RxIO
6
+
7
+ # Handler Base Module
8
+ # Provides common abstractions to Service Handler implementations.
9
+ module HandlerBase
10
+
11
+ # Write
12
+ # Writes one or more chunks of data to the client's output buffer (:obuf).
13
+ # @param [Hash] client
14
+ # @param [String] data One or more chunks of data to be written to the ouput buffer
15
+ def write client, *data
16
+
17
+ # Add Data Chunks to Buffer
18
+ data.each { |c| client[:lock].synchronize { client[:obuf] << c } }
19
+ end
20
+
21
+ # Buffer Input Chunk
22
+ # Writes a chunk of data to the client's input buffer (:ibuf).
23
+ # @param [Hash] client
24
+ # @param [String] chunk
25
+ def buffer_input client, chunk
26
+
27
+ # Buffer Chunk
28
+ client[:ibuf] << chunk
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,70 @@
1
+ # RxIO
2
+ # by Eresse <eresse@eresse.net>
3
+
4
+ # Internal Includes
5
+ require 'rxio/handler_base'
6
+
7
+ # RxIO Module
8
+ module RxIO
9
+
10
+ # I/O Filters Module
11
+ module IOFilters
12
+
13
+ # Binary-Delimiter I/O Filter
14
+ # Splits messages according to a given fixed *binary delimiter*, which can be any number of bytes, defined through the _msg_delim_ method.
15
+ module BinDelim
16
+
17
+ # Inject Dependencies into Extending Module
18
+ # @param [Module] base
19
+ def self.extended base
20
+ base.extend RxIO::HandlerBase
21
+ end
22
+
23
+ # Set Message Delimiter
24
+ # Used to define the binary string used as message delimiter for this protocol.
25
+ # @param [String] v The message delimiter string
26
+ def msg_delim v
27
+ @msg_delim = v
28
+ end
29
+
30
+ # Filter Input
31
+ # Buffers data chunks sent by the client and extracts messages from them, according to the delimiter defined through _msg_delim_.
32
+ # @param [Hash] client
33
+ # @param [String] chunk
34
+ def filter_input client, chunk
35
+
36
+ # Buffer dat shit
37
+ buffer_input client, chunk
38
+
39
+ # Ensure Last Position is available
40
+ client[:bin_delim][:last_pos] ||= 0
41
+
42
+ # Loop over Messages
43
+ while true
44
+
45
+ # Find Delimiter
46
+ d = client[:ibuf].index @msg_delim, client[:bin_delim][:last_pos]
47
+ client[:bin_delim][:last_pos] = client[:ibuf].bytesize
48
+
49
+ # Check Delimiter
50
+ break unless d
51
+
52
+ # Slice out Message from Input Buffer
53
+ m = client[:ibuf].slice!(0, d + @msg_delim.bytesize).slice 0, d
54
+ client[:bin_delim][:last_pos] = 0
55
+
56
+ # Register Message
57
+ client[:msgs] << m
58
+ end
59
+ end
60
+
61
+ # Send Message
62
+ # Buffers a message to be sent to the client, after wrapping it according to the delimiter defined through _msg_delim_.
63
+ # @param [Hash] client
64
+ # @param [String] msg
65
+ def send_msg client, msg
66
+ write client, msg, @msg_delim
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,61 @@
1
+ # RxIO
2
+ # by Eresse <eresse@eresse.net>
3
+
4
+ # Internal Includes
5
+ require 'rxio/handler_base'
6
+
7
+ # RxIO Module
8
+ module RxIO
9
+
10
+ # I/O Filters Module
11
+ module IOFilters
12
+
13
+ # Message-Size I/O Filter
14
+ # Splits messages according to a _4-byte unsigned big-endian integer_ *size* field, which prefixes every message and indicates its length in bytes.
15
+ module MsgSize
16
+
17
+ # Inject Dependencies into Extending Module
18
+ # @param [Module] base
19
+ def self.extended base
20
+ base.extend RxIO::HandlerBase
21
+ end
22
+
23
+ # Filter Input
24
+ # Buffers data chunks sent by the client and extracts messages from them, according to the *size* field present at the beginning of each message.
25
+ # @param [Hash] client
26
+ # @param [String] chunk
27
+ def filter_input client, chunk
28
+
29
+ # Buffer dat shit
30
+ buffer_input client, chunk
31
+
32
+ # Loop over Messages
33
+ while true
34
+
35
+ # Check Buffer Size (can we at least determine the next message size?)
36
+ break unless client[:ibuf].bytesize >= 4
37
+
38
+ # Acquire Message Size
39
+ size = client[:ibuf][0, 4].unpack 'N'
40
+
41
+ # Check Buffer Size again (is the complete message present in the buffer?)
42
+ break unless client[:ibuf].bytesize >= 4 + size
43
+
44
+ # Slice out Message from Input Buffer
45
+ m = client[:ibuf].slice!(0, 4 + size)[4, size]
46
+
47
+ # Register Message
48
+ client[:msgs] << m
49
+ end
50
+ end
51
+
52
+ # Send Message
53
+ # Buffers a message to be sent to the client, after prefixing it with a _size_ field.
54
+ # @param [Hash] client
55
+ # @param [String] msg
56
+ def send_msg client, msg
57
+ write client, [msg.bytesize].pack('N'), msg
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,14 @@
1
+ # RxIO
2
+ # by Eresse <eresse@eresse.net>
3
+
4
+ # Internal Includes
5
+ require 'rxio/io_filters/bin_delim'
6
+
7
+ # RxIO Module
8
+ module RxIO
9
+
10
+ # I/O Filters Module
11
+ # This module provides a set of generic I/O Filters to be used for constructing services.
12
+ module IOFilters
13
+ end
14
+ end
@@ -0,0 +1,232 @@
1
+ # RxIO
2
+ # by Eresse <eresse@eresse.net>
3
+
4
+ # External Includes
5
+ require 'thread'
6
+ require 'socket'
7
+
8
+ # RxIO Module
9
+ module RxIO
10
+
11
+ # Service Class
12
+ class Service
13
+
14
+ # Chunk Size
15
+ CHUNK_SIZE = 1024
16
+
17
+ # Construct
18
+ # Builds a *Service* around a given _service_handler_ module, set to listen for incoming connections @ _addr_ on _port_.
19
+ # @param [String] addr
20
+ # @param [Fixnum] port
21
+ # @param [Module] service_handler
22
+ def initialize addr, port, service_handler
23
+
24
+ # Set Address & Port
25
+ @addr = addr
26
+ @port = port
27
+
28
+ # Set Service Handler Module
29
+ @service_handler = service_handler
30
+
31
+ # Create Sockets
32
+ @socks = []
33
+
34
+ # Create Clients
35
+ @clients = []
36
+
37
+ # Create Client Map
38
+ @cmap = {}
39
+ end
40
+
41
+ # Start up
42
+ # Spawns a new Thread around the _run_ method to execute the service in the background.
43
+ def startup
44
+ @thread = Thread.new { run }
45
+ end
46
+
47
+ # Shutdown
48
+ # Gracefully terminates the service, waiting for all resources to be released (returns once the service thread has completed).
49
+ def shutdown
50
+ @stop = true
51
+ @thread.join
52
+ @thread = nil
53
+ end
54
+
55
+ # Run
56
+ # Executes the main service loop, taking care of I/O scheduling, client management and message handling.
57
+ # Note: this method blocks until the service loop terminates.
58
+ def run
59
+
60
+ # Update Loop
61
+ begin
62
+
63
+ # Create TCP Socket Server
64
+ @serv = TCPServer.new @addr, @port
65
+ @socks << @serv
66
+
67
+ # Update Service
68
+ update until @stop
69
+ rescue Exception => e
70
+ puts "[!] ERROR - RxIO Service Update failed - #{e.inspect}"
71
+ e.backtrace.each { |b| puts " - #{b}" }
72
+ end
73
+
74
+ # Drop all Clients
75
+ @service_handler.on_drop @clients.pop until @clients.empty?
76
+ @cmap = {}
77
+
78
+ # Close all Sockets
79
+ @socks.each { |s| s.close }
80
+ @socks = []
81
+
82
+ # Drop Server
83
+ @serv = nil
84
+ end
85
+
86
+ # Stop
87
+ # Requests the service loop to stop executing.
88
+ # The _run_ method should return shortly after calling _stop_
89
+ def stop
90
+ @stop = true
91
+ end
92
+
93
+ # Privates
94
+ private
95
+
96
+ # Update
97
+ # Serves as the service loop main method, performing I/O scheduling, client management and message handling.
98
+ def update
99
+
100
+ # Collect Sockets with Output
101
+ ws = @clients.reject { |c| c[:lock].synchronize { c[:obuf].empty? } }.collect { |c| c[:sock] }
102
+
103
+ # Select Sockets
104
+ rd, wr = IO.select @socks, ws
105
+
106
+ # Handle I/O
107
+ rd.each { |s| s == @serv ? acpt_sock(s) : read_sock(s) }
108
+ wr.each { |s| write_sock s }
109
+ end
110
+
111
+ # Process Input
112
+ # Processes Input from a client, in the form of a data chunk
113
+ # @param [Hash] client
114
+ # @param [String] chunk A chunk of data, as received by the socket
115
+ def process_input client, chunk
116
+
117
+ # Pass through Service Handler Module
118
+ @service_handler.filter_input client, chunk
119
+
120
+ # Process Messages
121
+ @service_handler.handle_msg client, client[:msgs].shift until client[:msgs].empty?
122
+ end
123
+
124
+ # Register Client
125
+ # Creates a new Client around a given socket _s_ and registers it.
126
+ # Also, notifies the Handler Module if the _on_join_ method is available.
127
+ # @param [TCPSocket] s
128
+ def add_client s
129
+
130
+ # Register Socket
131
+ @socks << s
132
+
133
+ # Acquire Peer Address
134
+ peer = s.peeraddr
135
+
136
+ # Create Client
137
+ c = {
138
+ sock: s,
139
+ peer: {
140
+ port: peer[1],
141
+ name: peer[2],
142
+ addr: peer[3]
143
+ },
144
+ ibuf: '',
145
+ obuf: '',
146
+ lock: Mutex.new,
147
+ msgs: []
148
+ }
149
+
150
+ # Register Client
151
+ @clients << c
152
+
153
+ # Map Client
154
+ @cmap[s] = c
155
+
156
+ # Notify Service Handler
157
+ @service_handler.on_join c if @service_handler.respond_to? :on_join
158
+ end
159
+
160
+ # Drop Client
161
+ # Unregisters a Client and closes the associated socket.
162
+ # Also, notifies the Handler Module if the _on_drop_ method is available.
163
+ # @param [Hash] c
164
+ def drop_client c
165
+
166
+ # Notify Service Handler
167
+ @service_handler.on_drop c if @service_handler.respond_to? :on_drop
168
+
169
+ # Drop Client
170
+ @cmap.delete c[:sock]
171
+ @socks.delete c[:sock]
172
+ @clients.delete c
173
+
174
+ # Kill Socket
175
+ c[:sock].close rescue nil
176
+ end
177
+
178
+ # Accept Socket
179
+ # Tries to accept any queued connection request in a non-blocking manner.
180
+ # Registers a new Client through _add_client_ around the newly-accepted socket if present.
181
+ # @param [TCPServer] s
182
+ def acpt_sock s
183
+
184
+ # Accept
185
+ ns = s.accept_nonblock
186
+
187
+ # Register Client
188
+ add_client ns if ns
189
+ end
190
+
191
+ # Read Socket
192
+ # Attempts to read as many bytes as possible (up to CHUNK_SIZE) from a given socket _s_, passing the data chunks to _process_input_.
193
+ # @param [TCPSocket] s
194
+ def read_sock s
195
+
196
+ # Acquire Client
197
+ c = @cmap[s]
198
+
199
+ # Check Client
200
+ return unless c
201
+
202
+ # Read Chunk from Socket
203
+ chunk = s.read_nonblock CHUNK_SIZE rescue nil
204
+
205
+ # Drop Client & Abort on Error
206
+ return drop_client c unless chunk
207
+
208
+ # Process Input
209
+ process_input c, chunk
210
+ end
211
+
212
+ # Write Socket
213
+ # Attempts to write as many bytes as possible to a given socket _s_ from the associated client's output buffer.
214
+ # @param [TCPSocket] s
215
+ def write_sock s
216
+
217
+ # Acquire Client
218
+ c = @cmap[s]
219
+
220
+ # Check Client
221
+ return unless c
222
+
223
+ # Synchronize Client
224
+ c[:lock].synchronize do
225
+
226
+ # Write as much as possible
227
+ size = s.write_nonblock c[:obuf]
228
+ c[:obuf].slice! 0, size if size > 0
229
+ end
230
+ end
231
+ end
232
+ end
@@ -0,0 +1,9 @@
1
+ # RxIO
2
+ # by Eresse <eresse@eresse.net>
3
+
4
+ # RxIO Module
5
+ module RxIO
6
+
7
+ # Version
8
+ VERSION = '0.10.0'
9
+ end
data/lib/rxio.rb ADDED
@@ -0,0 +1,13 @@
1
+ # RxIO
2
+ # by Eresse <eresse@eresse.net>
3
+
4
+ # Internal Includes
5
+ require 'rxio/version'
6
+ require 'rxio/service'
7
+ require 'rxio/handler_base'
8
+ require 'rxio/io_filters'
9
+
10
+ # RxIO Module
11
+ # Root Module for RxIO
12
+ module RxIO
13
+ end
data/rxio.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rxio/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'rxio'
8
+ spec.version = RxIO::VERSION
9
+ spec.authors = ['Eresse']
10
+ spec.email = ['eresse@eresse.net']
11
+
12
+ spec.summary = 'Reactive Sockets for Ruby'
13
+ spec.description = 'Provides an implementation of the Reactor Pattern for Ruby Sockets.'
14
+ spec.homepage = 'http://redmine.eresse.net/projects/rxio'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = 'exe'
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_development_dependency 'bundler'
23
+ spec.add_development_dependency 'rake'
24
+ spec.add_runtime_dependency 'minitest'
25
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rxio
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.10.0
5
+ platform: ruby
6
+ authors:
7
+ - Eresse
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-01-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Provides an implementation of the Reactor Pattern for Ruby Sockets.
56
+ email:
57
+ - eresse@eresse.net
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - lib/rxio.rb
68
+ - lib/rxio/handler_base.rb
69
+ - lib/rxio/io_filters.rb
70
+ - lib/rxio/io_filters/bin_delim.rb
71
+ - lib/rxio/io_filters/msg_size.rb
72
+ - lib/rxio/service.rb
73
+ - lib/rxio/version.rb
74
+ - rxio.gemspec
75
+ homepage: http://redmine.eresse.net/projects/rxio
76
+ licenses:
77
+ - MIT
78
+ metadata: {}
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 2.6.10
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: Reactive Sockets for Ruby
99
+ test_files: []