summaryrefslogtreecommitdiff
path: root/lib/gserver.rb
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-05-16 21:31:06 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-05-16 21:31:06 +0000
commit28c2fa2fdb56abb6960ee40b9364706059f0ea65 (patch)
treedda82a6e9299e03b67db4a9986df92c5104404c1 /lib/gserver.rb
parente60f744e9a574630ebe1c14d023dc3d75ac6ae2b (diff)
* 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
Diffstat (limited to 'lib/gserver.rb')
-rw-r--r--lib/gserver.rb82
1 files changed, 69 insertions, 13 deletions
diff --git a/lib/gserver.rb b/lib/gserver.rb
index 2ab6e42bce..f6f37d3a89 100644
--- a/lib/gserver.rb
+++ b/lib/gserver.rb
@@ -4,9 +4,6 @@
# Author:: John W. Small
# Documentation:: Gavin Sinclair
# Licence:: Freeware.
-#
-# See the class GServer for documentation.
-#
require "socket"
require "thread"
@@ -25,7 +22,7 @@ require "thread"
# you the effort. All events are optionally logged, but you can provide your
# own event handlers if you wish.
#
-# === Example
+# == Example
#
# Using GServer is simple. Below we implement a simple time server, run it,
# 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
# more detailed logging.
#
-# connecting
-# disconnecting
-# starting
-# stopping
+# * #connecting
+# * #disconnecting
+# * #starting
+# * #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.
#
class GServer
@@ -93,17 +90,28 @@ class GServer
@@services = {} # Hash of opened ports, i.e. services
@@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)
@@servicesMutex.synchronize {
@@services[host][port].stop
}
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)
@@services.has_key?(host) and
@@services[host].has_key?(port)
end
+ # Stop the server
def stop
@connectionsMutex.synchronize {
if @tcpServerThread
@@ -112,25 +120,45 @@ class GServer
}
end
+ # Returns true if the server has stopped.
def stopped?
@tcpServerThread == nil
end
+ # Schedule a shutdown for the server
def shutdown
@shutdown = true
end
+ # Return the current number of connected clients
def connections
@connections.size
end
+ # Join with the server thread
def join
@tcpServerThread.join if @tcpServerThread
end
- attr_reader :port, :host, :maxConnections
- attr_accessor :stdlog, :audit, :debug
+ # Port on which to listen, as a FixNum
+ 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)
addr = client.peeraddr
log("#{self.class.to_s} #{@host}:#{@port} client:#{addr[1]} " +
@@ -138,6 +166,10 @@ class GServer
true
end
+
+ # Called when a client disconnects, if audition is enabled.
+ #
+ # +clientPort+:: the port of the client that is connecting
def disconnecting(clientPort)
log("#{self.class.to_s} #{@host}:#{@port} " +
"client:#{clientPort} disconnect")
@@ -145,20 +177,30 @@ class GServer
protected :connecting, :disconnecting
+ # Called when the server is starting up, if auditing is enabled.
def starting()
log("#{self.class.to_s} #{@host}:#{@port} start")
end
+ # Called when the server is shutting down, if auditing is enabled.
def stopping()
log("#{self.class.to_s} #{@host}:#{@port} stop")
end
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)
log(detail.backtrace.join("\n"))
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)
if @stdlog
@stdlog.puts("[#{Time.new.ctime}] %s" % msg)
@@ -168,6 +210,15 @@ class GServer
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,
stdlog = $stderr, audit = false, debug = false)
@tcpServerThread = nil
@@ -182,8 +233,13 @@ class GServer
@debug = debug
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)
- raise "running" if !stopped?
+ raise "server is already running" if !stopped?
@shutdown = false
@maxConnections = maxConnections if maxConnections > 0
@@servicesMutex.synchronize {