1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* lib/gserver.rb: Improve documentation. Patch by David Copeland.

[Ruby 1.9 - Bug #4705]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31596 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
drbrain 2011-05-16 21:31:06 +00:00
parent e60f744e9a
commit 28c2fa2fdb
2 changed files with 74 additions and 13 deletions

View file

@ -1,3 +1,8 @@
Tue May 17 06:28:14 2011 Eric Hodel <drbrain@segment7.net>
* lib/gserver.rb: Improve documentation. Patch by David Copeland.
[Ruby 1.9 - Bug #4705]
Tue May 17 06:21:15 2011 Eric Hodel <drbrain@segment7.net> Tue May 17 06:21:15 2011 Eric Hodel <drbrain@segment7.net>
* lib/cgi.rb: Add toplevel documentation to class CGI * lib/cgi.rb: Add toplevel documentation to class CGI

View file

@ -4,9 +4,6 @@
# Author:: John W. Small # Author:: John W. Small
# Documentation:: Gavin Sinclair # Documentation:: Gavin Sinclair
# Licence:: Freeware. # Licence:: Freeware.
#
# See the class GServer for documentation.
#
require "socket" require "socket"
require "thread" require "thread"
@ -25,7 +22,7 @@ require "thread"
# you the effort. All events are optionally logged, but you can provide your # you the effort. All events are optionally logged, but you can provide your
# own event handlers if you wish. # own event handlers if you wish.
# #
# === Example # == Example
# #
# Using GServer is simple. Below we implement a simple time server, run it, # Using GServer is simple. Below we implement a simple time server, run it,
# query it, and shut it down. Try this code in +irb+: # query it, and shut it down. Try this code in +irb+:
@ -73,14 +70,14 @@ require "thread"
# other methods as well if you wish, perhaps to collect statistics, or emit # other methods as well if you wish, perhaps to collect statistics, or emit
# more detailed logging. # more detailed logging.
# #
# connecting # * #connecting
# disconnecting # * #disconnecting
# starting # * #starting
# stopping # * #stopping
# #
# The above methods are only called if auditing is enabled. # The above methods are only called if auditing is enabled, via #audit=.
# #
# You can also override +log+ and +error+ if, for example, you wish to use a # You can also override #log and #error if, for example, you wish to use a
# more sophisticated logging system. # more sophisticated logging system.
# #
class GServer class GServer
@ -93,17 +90,28 @@ class GServer
@@services = {} # Hash of opened ports, i.e. services @@services = {} # Hash of opened ports, i.e. services
@@servicesMutex = Mutex.new @@servicesMutex = Mutex.new
# Stop the server running on the given port, bound to the given host
#
# +port+:: port, as a FixNum, of the server to stop
# +host+:: host on which to find the server to stop
def GServer.stop(port, host = DEFAULT_HOST) def GServer.stop(port, host = DEFAULT_HOST)
@@servicesMutex.synchronize { @@servicesMutex.synchronize {
@@services[host][port].stop @@services[host][port].stop
} }
end end
# Check if a server is running on the given port and host
#
# +port+:: port, as a FixNum, of the server to check
# +host+:: host on which to find the server to check
#
# Returns true if a server is running on that port and host.
def GServer.in_service?(port, host = DEFAULT_HOST) def GServer.in_service?(port, host = DEFAULT_HOST)
@@services.has_key?(host) and @@services.has_key?(host) and
@@services[host].has_key?(port) @@services[host].has_key?(port)
end end
# Stop the server
def stop def stop
@connectionsMutex.synchronize { @connectionsMutex.synchronize {
if @tcpServerThread if @tcpServerThread
@ -112,25 +120,45 @@ class GServer
} }
end end
# Returns true if the server has stopped.
def stopped? def stopped?
@tcpServerThread == nil @tcpServerThread == nil
end end
# Schedule a shutdown for the server
def shutdown def shutdown
@shutdown = true @shutdown = true
end end
# Return the current number of connected clients
def connections def connections
@connections.size @connections.size
end end
# Join with the server thread
def join def join
@tcpServerThread.join if @tcpServerThread @tcpServerThread.join if @tcpServerThread
end end
attr_reader :port, :host, :maxConnections # Port on which to listen, as a FixNum
attr_accessor :stdlog, :audit, :debug attr_reader :port
# Host on which to bind, as a String
attr_reader :host
# Maximum number of connections to accept at at ime, as a FixNum
attr_reader :maxConnections
# IO Device on which log messages should be written
attr_accessor :stdlog
# Set to true to cause the callbacks #connecting, #disconnecting, #starting,
# and #stopping to be called during the server's lifecycle
attr_accessor :audit
# Set to true to show more detailed logging
attr_accessor :debug
# Called when a client connects, if auditing is enabled.
#
# +client+:: a TCPSocket instances representing the client that connected
#
# Return true to allow this client to connect, false to prevent it.
def connecting(client) def connecting(client)
addr = client.peeraddr addr = client.peeraddr
log("#{self.class.to_s} #{@host}:#{@port} client:#{addr[1]} " + log("#{self.class.to_s} #{@host}:#{@port} client:#{addr[1]} " +
@ -138,6 +166,10 @@ class GServer
true true
end end
# Called when a client disconnects, if audition is enabled.
#
# +clientPort+:: the port of the client that is connecting
def disconnecting(clientPort) def disconnecting(clientPort)
log("#{self.class.to_s} #{@host}:#{@port} " + log("#{self.class.to_s} #{@host}:#{@port} " +
"client:#{clientPort} disconnect") "client:#{clientPort} disconnect")
@ -145,20 +177,30 @@ class GServer
protected :connecting, :disconnecting protected :connecting, :disconnecting
# Called when the server is starting up, if auditing is enabled.
def starting() def starting()
log("#{self.class.to_s} #{@host}:#{@port} start") log("#{self.class.to_s} #{@host}:#{@port} start")
end end
# Called when the server is shutting down, if auditing is enabled.
def stopping() def stopping()
log("#{self.class.to_s} #{@host}:#{@port} stop") log("#{self.class.to_s} #{@host}:#{@port} stop")
end end
protected :starting, :stopping protected :starting, :stopping
# Called if #debug is true whenever an unhandled exception is raised.
# This implementation simply logs the backtrace.
#
# +detail+:: The Exception that was caught
def error(detail) def error(detail)
log(detail.backtrace.join("\n")) log(detail.backtrace.join("\n"))
end end
# Log a message to #stdlog, if it's defined. This implementation
# outputs the timestamp and message to the log.
#
# +msg+:: the message to log
def log(msg) def log(msg)
if @stdlog if @stdlog
@stdlog.puts("[#{Time.new.ctime}] %s" % msg) @stdlog.puts("[#{Time.new.ctime}] %s" % msg)
@ -168,6 +210,15 @@ class GServer
protected :error, :log protected :error, :log
# Create a new server
#
# +port+:: the port, as a FixNum, on which to listen.
# +host+:: the host to bind to
# +maxConnections+:: The maximum number of simultaneous connections to
# accept
# +stdlog+:: IO device on which to log messages
# +audit+:: if true, lifecycle callbacks will be called. See #audit
# +debug+:: if true, error messages are logged. See #debug
def initialize(port, host = DEFAULT_HOST, maxConnections = 4, def initialize(port, host = DEFAULT_HOST, maxConnections = 4,
stdlog = $stderr, audit = false, debug = false) stdlog = $stderr, audit = false, debug = false)
@tcpServerThread = nil @tcpServerThread = nil
@ -182,8 +233,13 @@ class GServer
@debug = debug @debug = debug
end end
# Start the server if it isn't already running
#
# +maxConnections+::
# override +maxConnections+ given to the constructor. A negative
# value indicates that the value from the constructor should be used.
def start(maxConnections = -1) def start(maxConnections = -1)
raise "running" if !stopped? raise "server is already running" if !stopped?
@shutdown = false @shutdown = false
@maxConnections = maxConnections if maxConnections > 0 @maxConnections = maxConnections if maxConnections > 0
@@servicesMutex.synchronize { @@servicesMutex.synchronize {