diff tango/tango/net/cluster/tina/ClusterThread.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/ClusterThread.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,149 @@
+/*******************************************************************************
+
+        copyright:      Copyright (c) 2004 Kris Bell. All rights reserved
+
+        license:        BSD style: $(LICENSE)
+        
+        version:        July 2004: Initial release      
+        
+        author:         Kris
+
+*******************************************************************************/
+
+module tango.net.cluster.tina.ClusterThread;
+
+private import  tango.core.Thread,
+                tango.core.Runtime,
+                tango.core.Exception;
+
+private import  tango.io.Buffer,
+                tango.io.GrowBuffer,
+                tango.net.ServerSocket;
+
+package import  tango.io.model.IBuffer,
+                tango.io.model.IConduit;
+
+private import  tango.text.convert.Sprint;
+
+package import  tango.net.cluster.tina.Cluster,
+                tango.net.cluster.tina.ProtocolReader,
+                tango.net.cluster.tina.ProtocolWriter;
+
+package import  tango.net.cluster.tina.util.AbstractServer;
+
+/******************************************************************************
+
+        Thread for handling client requests. Note that this remains alive
+        until the client kills the socket
+
+******************************************************************************/
+
+class ClusterThread
+{
+        protected IBuffer         buffer;
+        protected ProtocolReader  reader;
+        protected ProtocolWriter  writer;
+        protected Logger          logger;
+        protected char[]          client;
+        protected Thread          thread;
+        protected Sprint!(char)   sprint;
+        protected Cluster         cluster;
+        protected IConduit        conduit;
+
+        /**********************************************************************
+
+                request handler
+
+        **********************************************************************/
+
+        abstract void dispatch ();
+
+        /**********************************************************************
+
+                Note that the conduit stays open until the client kills it.
+                Also note that we use a GrowableBuffer here, which expands
+                as necessary to contain larger payloads.
+
+        **********************************************************************/
+
+        this (AbstractServer server, IConduit conduit, Cluster cluster)
+        {
+                buffer = new GrowBuffer (1024 * 8);
+                buffer.setConduit (conduit);
+
+                // get client infomation
+                client = server.remoteAddress(conduit).toString;
+
+                // setup cluster protocol-transcoders
+                writer = new ProtocolWriter (buffer);
+                reader = new ProtocolReader (buffer);
+
+                // grab a thread to execute within
+                thread = new Thread (&run);
+
+                // make a formatter for this thread
+                sprint = new Sprint!(char);
+                
+                // save state
+                logger = server.getLogger;
+                this.conduit = conduit;
+                this.cluster = cluster;
+        }
+
+        /**********************************************************************
+
+                IRunnable method
+
+        **********************************************************************/
+
+        void execute ()
+        {
+                thread.start;
+        }
+        
+        /**********************************************************************
+
+                process client requests
+                
+        **********************************************************************/
+
+        private void run ()
+        {
+                logger.info (sprint ("{} starting service handler", client));
+                
+                try {
+                    while (true)
+                          {
+                          // start with a clear conscience
+                          buffer.clear;
+
+                          // wait for something to arrive before we try/catch
+                          buffer.slice (1, false);
+
+                          try {
+                              dispatch;
+                              } catch (Object x)
+                                      {
+                                      logger.error (sprint ("{} cluster request error '{}'", client, x));
+                                      writer.exception (sprint ("cluster request error '{}'", x.toString));
+                                      }
+
+                          // send response back to client
+                          buffer.flush;
+                          }
+
+                    } catch (IOException x)
+                             if (! Runtime.isHalting)
+                                   logger.trace (sprint ("{} cluster socket exception '{}'", client, x));
+
+                      catch (Object x)
+                             logger.fatal (sprint ("{} cluster runtime exception '{}'", client, x));
+
+                // log our halt status
+                logger.info (sprint ("{} halting service handler", client));
+
+                // make sure we close the conduit
+                conduit.detach;
+        }
+}
+