rubysl-gserver 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b59a46b0c246f54cb0d7b5e2cf785afc32e39a31
4
+ data.tar.gz: 4fd286c7d23568841c76702b13b8240ee0a8c998
5
+ SHA512:
6
+ metadata.gz: d3138998f198e787b8bfed1d5ecaf987ffd43642b7593c73681e6c0e8f8ae7700f246a9793fedde42252234f719734e164e7b94ac27909d135ad1211479e32f3
7
+ data.tar.gz: 41909ba24a7494f19c47172dca23aed0ff807b5a9074b8e1faec8d060f0cccae3e10a85f01694ae11f3375d5805b336f32dd7e6d3f696b59d1c3545cbf41f5a4
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ before_install:
3
+ - gem update --system
4
+ - gem --version
5
+ - gem install rubysl-bundler
6
+ script: bundle exec mspec spec
7
+ rvm:
8
+ - rbx-nightly-18mode
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rubysl-gserver.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ Copyright (c) 2013, Brian Shirai
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+ 2. Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ 3. Neither the name of the library nor the names of its contributors may be
13
+ used to endorse or promote products derived from this software without
14
+ specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT,
20
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,29 @@
1
+ # Rubysl::Gserver
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'rubysl-gserver'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install rubysl-gserver
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1 @@
1
+ require "rubysl/gserver"
@@ -0,0 +1,2 @@
1
+ require "rubysl/gserver/gserver"
2
+ require "rubysl/gserver/version"
@@ -0,0 +1,253 @@
1
+ #
2
+ # Copyright (C) 2001 John W. Small All Rights Reserved
3
+ #
4
+ # Author:: John W. Small
5
+ # Documentation:: Gavin Sinclair
6
+ # Licence:: Freeware.
7
+ #
8
+ # See the class GServer for documentation.
9
+ #
10
+
11
+ require "socket"
12
+ require "thread"
13
+
14
+ #
15
+ # GServer implements a generic server, featuring thread pool management,
16
+ # simple logging, and multi-server management. See HttpServer in
17
+ # <tt>xmlrpc/httpserver.rb</tt> in the Ruby standard library for an example of
18
+ # GServer in action.
19
+ #
20
+ # Any kind of application-level server can be implemented using this class.
21
+ # It accepts multiple simultaneous connections from clients, up to an optional
22
+ # maximum number. Several _services_ (i.e. one service per TCP port) can be
23
+ # run simultaneously, and stopped at any time through the class method
24
+ # <tt>GServer.stop(port)</tt>. All the threading issues are handled, saving
25
+ # you the effort. All events are optionally logged, but you can provide your
26
+ # own event handlers if you wish.
27
+ #
28
+ # === Example
29
+ #
30
+ # Using GServer is simple. Below we implement a simple time server, run it,
31
+ # query it, and shut it down. Try this code in +irb+:
32
+ #
33
+ # require 'gserver'
34
+ #
35
+ # #
36
+ # # A server that returns the time in seconds since 1970.
37
+ # #
38
+ # class TimeServer < GServer
39
+ # def initialize(port=10001, *args)
40
+ # super(port, *args)
41
+ # end
42
+ # def serve(io)
43
+ # io.puts(Time.now.to_i)
44
+ # end
45
+ # end
46
+ #
47
+ # # Run the server with logging enabled (it's a separate thread).
48
+ # server = TimeServer.new
49
+ # server.audit = true # Turn logging on.
50
+ # server.start
51
+ #
52
+ # # *** Now point your browser to http://localhost:10001 to see it working ***
53
+ #
54
+ # # See if it's still running.
55
+ # GServer.in_service?(10001) # -> true
56
+ # server.stopped? # -> false
57
+ #
58
+ # # Shut the server down gracefully.
59
+ # server.shutdown
60
+ #
61
+ # # Alternatively, stop it immediately.
62
+ # GServer.stop(10001)
63
+ # # or, of course, "server.stop".
64
+ #
65
+ # All the business of accepting connections and exception handling is taken
66
+ # care of. All we have to do is implement the method that actually serves the
67
+ # client.
68
+ #
69
+ # === Advanced
70
+ #
71
+ # As the example above shows, the way to use GServer is to subclass it to
72
+ # create a specific server, overriding the +serve+ method. You can override
73
+ # other methods as well if you wish, perhaps to collect statistics, or emit
74
+ # more detailed logging.
75
+ #
76
+ # connecting
77
+ # disconnecting
78
+ # starting
79
+ # stopping
80
+ #
81
+ # The above methods are only called if auditing is enabled.
82
+ #
83
+ # You can also override +log+ and +error+ if, for example, you wish to use a
84
+ # more sophisticated logging system.
85
+ #
86
+ class GServer
87
+
88
+ DEFAULT_HOST = "127.0.0.1"
89
+
90
+ def serve(io)
91
+ end
92
+
93
+ @@services = {} # Hash of opened ports, i.e. services
94
+ @@servicesMutex = Mutex.new
95
+
96
+ def GServer.stop(port, host = DEFAULT_HOST)
97
+ @@servicesMutex.synchronize {
98
+ @@services[host][port].stop
99
+ }
100
+ end
101
+
102
+ def GServer.in_service?(port, host = DEFAULT_HOST)
103
+ @@services.has_key?(host) and
104
+ @@services[host].has_key?(port)
105
+ end
106
+
107
+ def stop
108
+ @connectionsMutex.synchronize {
109
+ if @tcpServerThread
110
+ @tcpServerThread.raise "stop"
111
+ end
112
+ }
113
+ end
114
+
115
+ def stopped?
116
+ @tcpServerThread == nil
117
+ end
118
+
119
+ def shutdown
120
+ @shutdown = true
121
+ end
122
+
123
+ def connections
124
+ @connections.size
125
+ end
126
+
127
+ def join
128
+ @tcpServerThread.join if @tcpServerThread
129
+ end
130
+
131
+ attr_reader :port, :host, :maxConnections
132
+ attr_accessor :stdlog, :audit, :debug
133
+
134
+ def connecting(client)
135
+ addr = client.peeraddr
136
+ log("#{self.class.to_s} #{@host}:#{@port} client:#{addr[1]} " +
137
+ "#{addr[2]}<#{addr[3]}> connect")
138
+ true
139
+ end
140
+
141
+ def disconnecting(clientPort)
142
+ log("#{self.class.to_s} #{@host}:#{@port} " +
143
+ "client:#{clientPort} disconnect")
144
+ end
145
+
146
+ protected :connecting, :disconnecting
147
+
148
+ def starting()
149
+ log("#{self.class.to_s} #{@host}:#{@port} start")
150
+ end
151
+
152
+ def stopping()
153
+ log("#{self.class.to_s} #{@host}:#{@port} stop")
154
+ end
155
+
156
+ protected :starting, :stopping
157
+
158
+ def error(detail)
159
+ log(detail.backtrace.join("\n"))
160
+ end
161
+
162
+ def log(msg)
163
+ if @stdlog
164
+ @stdlog.puts("[#{Time.new.ctime}] %s" % msg)
165
+ @stdlog.flush
166
+ end
167
+ end
168
+
169
+ protected :error, :log
170
+
171
+ def initialize(port, host = DEFAULT_HOST, maxConnections = 4,
172
+ stdlog = $stderr, audit = false, debug = false)
173
+ @tcpServerThread = nil
174
+ @port = port
175
+ @host = host
176
+ @maxConnections = maxConnections
177
+ @connections = []
178
+ @connectionsMutex = Mutex.new
179
+ @connectionsCV = ConditionVariable.new
180
+ @stdlog = stdlog
181
+ @audit = audit
182
+ @debug = debug
183
+ end
184
+
185
+ def start(maxConnections = -1)
186
+ raise "running" if !stopped?
187
+ @shutdown = false
188
+ @maxConnections = maxConnections if maxConnections > 0
189
+ @@servicesMutex.synchronize {
190
+ if GServer.in_service?(@port,@host)
191
+ raise "Port already in use: #{host}:#{@port}!"
192
+ end
193
+ @tcpServer = TCPServer.new(@host,@port)
194
+ @port = @tcpServer.addr[1]
195
+ @@services[@host] = {} unless @@services.has_key?(@host)
196
+ @@services[@host][@port] = self;
197
+ }
198
+ @tcpServerThread = Thread.new {
199
+ begin
200
+ starting if @audit
201
+ while !@shutdown
202
+ @connectionsMutex.synchronize {
203
+ while @connections.size >= @maxConnections
204
+ @connectionsCV.wait(@connectionsMutex)
205
+ end
206
+ }
207
+ client = @tcpServer.accept
208
+ @connections << Thread.new(client) { |myClient|
209
+ begin
210
+ myPort = myClient.peeraddr[1]
211
+ serve(myClient) if !@audit or connecting(myClient)
212
+ rescue => detail
213
+ error(detail) if @debug
214
+ ensure
215
+ begin
216
+ myClient.close
217
+ rescue
218
+ end
219
+ @connectionsMutex.synchronize {
220
+ @connections.delete(Thread.current)
221
+ @connectionsCV.signal
222
+ }
223
+ disconnecting(myPort) if @audit
224
+ end
225
+ }
226
+ end
227
+ rescue => detail
228
+ error(detail) if @debug
229
+ ensure
230
+ begin
231
+ @tcpServer.close
232
+ rescue
233
+ end
234
+ if @shutdown
235
+ @connectionsMutex.synchronize {
236
+ while @connections.size > 0
237
+ @connectionsCV.wait(@connectionsMutex)
238
+ end
239
+ }
240
+ else
241
+ @connections.each { |c| c.raise "stop" }
242
+ end
243
+ @tcpServerThread = nil
244
+ @@servicesMutex.synchronize {
245
+ @@services[@host].delete(@port)
246
+ }
247
+ stopping if @audit
248
+ end
249
+ }
250
+ self
251
+ end
252
+
253
+ end
@@ -0,0 +1,5 @@
1
+ module RubySL
2
+ module GServer
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ require './lib/rubysl/gserver/version'
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = "rubysl-gserver"
6
+ spec.version = RubySL::GServer::VERSION
7
+ spec.authors = ["Brian Shirai"]
8
+ spec.email = ["brixen@gmail.com"]
9
+ spec.description = %q{Ruby standard library gserver.}
10
+ spec.summary = %q{Ruby standard library gserver.}
11
+ spec.homepage = "https://github.com/rubysl/rubysl-gserver"
12
+ spec.license = "BSD"
13
+
14
+ spec.files = `git ls-files`.split($/)
15
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_runtime_dependency "rubysl-socket", "~> 1.0"
20
+ spec.add_runtime_dependency "rubysl-thread", "~> 1.0"
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.3"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "mspec", "~> 1.5"
25
+ spec.add_development_dependency "rubysl-prettyprint", "~> 1.0"
26
+ end
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rubysl-gserver
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Brian Shirai
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rubysl-socket
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubysl-thread
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '1.5'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '1.5'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubysl-prettyprint
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '1.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '1.0'
97
+ description: Ruby standard library gserver.
98
+ email:
99
+ - brixen@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - .gitignore
105
+ - .travis.yml
106
+ - Gemfile
107
+ - LICENSE
108
+ - README.md
109
+ - Rakefile
110
+ - lib/gserver.rb
111
+ - lib/rubysl/gserver.rb
112
+ - lib/rubysl/gserver/gserver.rb
113
+ - lib/rubysl/gserver/version.rb
114
+ - rubysl-gserver.gemspec
115
+ homepage: https://github.com/rubysl/rubysl-gserver
116
+ licenses:
117
+ - BSD
118
+ metadata: {}
119
+ post_install_message:
120
+ rdoc_options: []
121
+ require_paths:
122
+ - lib
123
+ required_ruby_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ required_rubygems_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ requirements: []
134
+ rubyforge_project:
135
+ rubygems_version: 2.0.7
136
+ signing_key:
137
+ specification_version: 4
138
+ summary: Ruby standard library gserver.
139
+ test_files: []