diff tango/tango/net/cluster/tina/util/AbstractServer.d @ 132:1700239cab2e trunk

[svn r136] MAJOR UNSTABLE UPDATE!!! Initial commit after moving to Tango instead of Phobos. Lots of bugfixes... This build is not suitable for most things.
author lindquist
date Fri, 11 Jan 2008 17:57:40 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/tango/net/cluster/tina/util/AbstractServer.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,210 @@
+/*******************************************************************************
+
+        copyright:      Copyright (c) 2004 Kris Bell. All rights reserved
+
+        license:        BSD style: $(LICENSE)
+
+        version:        Initial release: April 2004
+
+        author:         Kris
+
+*******************************************************************************/
+
+module tango.net.cluster.tina.util.AbstractServer;
+
+private   import  tango.net.Socket;
+
+protected import  tango.util.log.Log;
+
+protected import  tango.net.ServerSocket,
+                  tango.net.SocketConduit;
+
+protected import  tango.io.model.IConduit;
+
+protected import  tango.text.convert.Sprint;
+
+protected import  tango.net.cluster.tina.util.model.IServer;
+
+/******************************************************************************
+
+        Exposes the foundation of a multi-threaded Socket server. This is
+        subclassed by  mango.net.http.server.HttpServer, which itself would
+        likely be subclassed by a SecureHttpServer.
+
+******************************************************************************/
+
+class AbstractServer : IServer
+{
+        private InternetAddress bind;
+        private ServerSocket    server;
+        private Logger          logger;
+        private Sprint!(char)   sprint;
+        private uint            threads;
+        private uint            backlog;
+
+        /**********************************************************************
+
+                Setup this server with the requisite attributes. The number
+                of threads specified dictate exactly that. You might have
+                anything between 1 thread and several hundred, dependent
+                upon the underlying O/S and hardware.
+
+                Parameter 'backlog' specifies the max number of"simultaneous"
+                connection requests to be handled by an underlying socket
+                implementation.
+
+        **********************************************************************/
+
+        this (InternetAddress bind, int threads, int backlog, Logger logger)
+        in {
+           assert (bind);
+           assert (logger);
+           assert (backlog >= 0);
+           assert (threads > 0 && threads < 256);
+           }
+        body
+        {
+                this.bind = bind;
+                this.logger = logger;
+                this.threads = threads;
+                this.backlog = backlog;
+                this.sprint = new Sprint!(char);
+        }
+
+        /**********************************************************************
+
+                Concrete server must expose a name
+
+        **********************************************************************/
+
+        protected abstract char[] toString();
+
+        /**********************************************************************
+
+                Concrete server must expose a ServerSocket factory
+
+        **********************************************************************/
+
+        protected abstract ServerSocket createSocket (InternetAddress bind, int backlog, bool reuse=false);
+
+        /**********************************************************************
+
+                Concrete server must expose a thread factory
+
+        **********************************************************************/
+
+        protected abstract void createThread (ServerSocket socket);
+
+        /**********************************************************************
+
+                Concrete server must expose a service handler
+
+        **********************************************************************/
+
+        abstract void service (IConduit conduit);
+
+        /**********************************************************************
+
+                Provide support for figuring out the remote address
+
+        **********************************************************************/
+
+        IPv4Address remoteAddress (IConduit conduit)
+        {
+                auto tmp = cast(SocketConduit) conduit;
+                if (tmp)
+                    return cast(IPv4Address) tmp.socket.remoteAddress;
+                return null;
+        }
+
+        /**********************************************************************
+
+                Provide support for figuring out the remote address
+
+        **********************************************************************/
+
+        IPv4Address localAddress ()
+        {
+                return cast(IPv4Address) server.socket.localAddress;
+        }
+
+        /**********************************************************************
+
+                Provide support for figuring out the remote address
+
+        **********************************************************************/
+
+        char[] getRemoteAddress (IConduit conduit)
+        {
+                auto addr = remoteAddress (conduit);
+
+                if (addr)
+                    return addr.toAddrString;
+                return "127.0.0.1";
+        }
+
+        /**********************************************************************
+
+                Provide support for figuring out the remote host. Not
+                currently implemented.
+
+        **********************************************************************/
+
+        char[] getRemoteHost (IConduit conduit)
+        {
+                return null;
+        }
+
+        /**********************************************************************
+
+                Return the local port we're attached to
+
+        **********************************************************************/
+
+        int getPort ()
+        {
+                return localAddress.port;
+        }
+
+        /**********************************************************************
+
+                Return the local address we're attached to
+
+        **********************************************************************/
+
+        char[] getHost ()
+        {
+                return localAddress.toAddrString;
+        }
+
+        /**********************************************************************
+
+                Return the logger associated with this server
+
+        **********************************************************************/
+
+        Logger getLogger ()
+        {
+                return logger;
+        }
+
+        /**********************************************************************
+
+                Start this server
+
+        **********************************************************************/
+
+        void start (bool reuse = false)
+        {
+                // have the subclass create a ServerSocket for us
+                server = createSocket (bind, backlog, reuse);
+
+                // instantiate and start all threads
+                for (auto i=threads; i-- > 0;)
+                     createThread (server);
+
+                // indicate what's going on
+                logger.info (sprint ("Server {} started on {} with {} accept threads and {} backlogs",
+                                      this, localAddress, threads, backlog));
+        }
+}