132
|
1 /*******************************************************************************
|
|
2
|
|
3 copyright: Copyright (c) 2004 Kris Bell. All rights reserved
|
|
4
|
|
5 license: BSD style: $(LICENSE)
|
|
6
|
|
7 version: July 2004: Initial release
|
|
8
|
|
9 author: Kris
|
|
10
|
|
11 *******************************************************************************/
|
|
12
|
|
13 module tango.net.cluster.tina.ClusterThread;
|
|
14
|
|
15 private import tango.core.Thread,
|
|
16 tango.core.Runtime,
|
|
17 tango.core.Exception;
|
|
18
|
|
19 private import tango.io.Buffer,
|
|
20 tango.io.GrowBuffer,
|
|
21 tango.net.ServerSocket;
|
|
22
|
|
23 package import tango.io.model.IBuffer,
|
|
24 tango.io.model.IConduit;
|
|
25
|
|
26 private import tango.text.convert.Sprint;
|
|
27
|
|
28 package import tango.net.cluster.tina.Cluster,
|
|
29 tango.net.cluster.tina.ProtocolReader,
|
|
30 tango.net.cluster.tina.ProtocolWriter;
|
|
31
|
|
32 package import tango.net.cluster.tina.util.AbstractServer;
|
|
33
|
|
34 /******************************************************************************
|
|
35
|
|
36 Thread for handling client requests. Note that this remains alive
|
|
37 until the client kills the socket
|
|
38
|
|
39 ******************************************************************************/
|
|
40
|
|
41 class ClusterThread
|
|
42 {
|
|
43 protected IBuffer buffer;
|
|
44 protected ProtocolReader reader;
|
|
45 protected ProtocolWriter writer;
|
|
46 protected Logger logger;
|
|
47 protected char[] client;
|
|
48 protected Thread thread;
|
|
49 protected Sprint!(char) sprint;
|
|
50 protected Cluster cluster;
|
|
51 protected IConduit conduit;
|
|
52
|
|
53 /**********************************************************************
|
|
54
|
|
55 request handler
|
|
56
|
|
57 **********************************************************************/
|
|
58
|
|
59 abstract void dispatch ();
|
|
60
|
|
61 /**********************************************************************
|
|
62
|
|
63 Note that the conduit stays open until the client kills it.
|
|
64 Also note that we use a GrowableBuffer here, which expands
|
|
65 as necessary to contain larger payloads.
|
|
66
|
|
67 **********************************************************************/
|
|
68
|
|
69 this (AbstractServer server, IConduit conduit, Cluster cluster)
|
|
70 {
|
|
71 buffer = new GrowBuffer (1024 * 8);
|
|
72 buffer.setConduit (conduit);
|
|
73
|
|
74 // get client infomation
|
|
75 client = server.remoteAddress(conduit).toString;
|
|
76
|
|
77 // setup cluster protocol-transcoders
|
|
78 writer = new ProtocolWriter (buffer);
|
|
79 reader = new ProtocolReader (buffer);
|
|
80
|
|
81 // grab a thread to execute within
|
|
82 thread = new Thread (&run);
|
|
83
|
|
84 // make a formatter for this thread
|
|
85 sprint = new Sprint!(char);
|
|
86
|
|
87 // save state
|
|
88 logger = server.getLogger;
|
|
89 this.conduit = conduit;
|
|
90 this.cluster = cluster;
|
|
91 }
|
|
92
|
|
93 /**********************************************************************
|
|
94
|
|
95 IRunnable method
|
|
96
|
|
97 **********************************************************************/
|
|
98
|
|
99 void execute ()
|
|
100 {
|
|
101 thread.start;
|
|
102 }
|
|
103
|
|
104 /**********************************************************************
|
|
105
|
|
106 process client requests
|
|
107
|
|
108 **********************************************************************/
|
|
109
|
|
110 private void run ()
|
|
111 {
|
|
112 logger.info (sprint ("{} starting service handler", client));
|
|
113
|
|
114 try {
|
|
115 while (true)
|
|
116 {
|
|
117 // start with a clear conscience
|
|
118 buffer.clear;
|
|
119
|
|
120 // wait for something to arrive before we try/catch
|
|
121 buffer.slice (1, false);
|
|
122
|
|
123 try {
|
|
124 dispatch;
|
|
125 } catch (Object x)
|
|
126 {
|
|
127 logger.error (sprint ("{} cluster request error '{}'", client, x));
|
|
128 writer.exception (sprint ("cluster request error '{}'", x.toString));
|
|
129 }
|
|
130
|
|
131 // send response back to client
|
|
132 buffer.flush;
|
|
133 }
|
|
134
|
|
135 } catch (IOException x)
|
|
136 if (! Runtime.isHalting)
|
|
137 logger.trace (sprint ("{} cluster socket exception '{}'", client, x));
|
|
138
|
|
139 catch (Object x)
|
|
140 logger.fatal (sprint ("{} cluster runtime exception '{}'", client, x));
|
|
141
|
|
142 // log our halt status
|
|
143 logger.info (sprint ("{} halting service handler", client));
|
|
144
|
|
145 // make sure we close the conduit
|
|
146 conduit.detach;
|
|
147 }
|
|
148 }
|
|
149
|