ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/server/uk/org/iscream/cms/server/filter/TCPReader.java
Revision: 1.6
Committed: Fri Jan 12 00:45:25 2001 UTC (23 years, 4 months ago) by tdb
Branch: MAIN
Changes since 1.5: +6 -6 lines
Log Message:
A structural change to the Filter.

The old setup looked like this;

UDPReader ------> FilterThread (thread) --> (parent)
TCPReader ------> FilterThread (thread) --> (parent)
FilterServant --> FilterThread (thread) --> (parent)

Seeing this from a threaded point of view, each time a packet came in (through
whatever means - UDP, TCP or CORBA), a FilterThread instance was created to
deal with it. If the link to the parent was slow this resulting in a build-up
of FilterThreads all waiting to talk to the parent - and there is only one
actual parent object, with a synchronised thread, so they have to queue up
anyway.

As a result of this, the following change has been made.

UDPReader -------\
TCPReader ----------> Queue (single) >-- FilterThread --> (parent)
FilterServant ---/

In this setup, each of the three objects that generate packets only see the
single instance of a Queue. They all add their data to this Queue, and then
carry on with the task of listening. The FilterThread (having it's role changed
slightly) now acts as a consumer of the Queue, in that it grabs data from the
Queue and deals with passing it on to the parent.

This setup should be more efficient in the long run, especially under a high
load situation. The only problem could be the Queue growing to an unlimited
size, but this is a Queue design issue.

File Contents

# User Rev Content
1 tdb 1.1 //---PACKAGE DECLARATION---
2 tdb 1.2 package uk.ac.ukc.iscream.filter;
3 tdb 1.1
4     //---IMPORTS---
5     import uk.ac.ukc.iscream.core.*;
6     import uk.ac.ukc.iscream.filter.*;
7     import java.net.Socket;
8     import java.net.ServerSocket;
9     import java.io.OutputStream;
10     import java.io.IOException;
11     import java.net.InetAddress;
12     import java.net.UnknownHostException;
13 ajm 1.4 import uk.ac.ukc.iscream.util.*;
14 tdb 1.1
15     /**
16     * A socket listener to listen for new hosts registering with the system.
17     * When a host makes a connection, the connecton is past to an instance
18     * of the HostInit class, which handles further communication.
19     *
20 ajm 1.5 * @author $Author: ajm4 $
21 tdb 1.6 * @version $Id: TCPReader.java,v 1.5 2000/12/13 13:36:46 ajm4 Exp $
22 tdb 1.1 */
23     class TCPReader extends Thread {
24    
25     //---FINAL ATTRIBUTES---
26    
27     /**
28     * The current CVS revision of this class
29     */
30 tdb 1.6 public final String REVISION = "$Revision: 1.5 $";
31 tdb 1.1
32     //---STATIC METHODS---
33    
34     //---CONSTRUCTORS---
35    
36     /**
37     * Constructs a new listener
38     *
39     * @param logger a reference to the logger we are using
40     * @param configManager a reference to the ConfigurationManager we are using
41     * @param port The port that the server will listen on.
42     */
43 tdb 1.6 public TCPReader(int port, Queue queue) {
44 tdb 1.1 _port = port;
45 tdb 1.6 _queue = queue;
46 tdb 1.1 _logger.write(toString(), Logger.SYSINIT, "started");
47     }
48    
49    
50    
51     //---PUBLIC METHODS---
52    
53     /**
54     * The run() method is the main loop for this thread, and we
55     * will remain in here until such a point as something goes
56     * wrong with the listening. After initially setting up the
57     * ServerSocket we go round a while loop receiving connections
58     * and then passing them off to other processes to deal with.
59     */
60     public void run(){
61     ServerSocket listenPort=null;
62     // We use this boolean so we can break out of the while loop if we want
63     boolean run = true;
64     try{
65     // Setup the ServerSocket so that clients can connect
66     listenPort = new ServerSocket(_port);
67     }
68     catch(IOException e){
69     }
70     // Log what machine/port we're listening on
71     try{
72     _logger.write(toString(), Logger.SYSMSG, "TCPReader listening on "
73     +InetAddress.getLocalHost().getHostName()
74     +"/"+InetAddress.getLocalHost().getHostAddress()
75     +" port "+listenPort.getLocalPort());
76     }
77     catch(UnknownHostException e){
78     _logger.write(toString(), Logger.SYSMSG, "TCPReader listening on UnknownHost "
79     +"port "+listenPort.getLocalPort());
80     }
81     // Loop round constantly until we decide to stop
82     while(run){
83     Socket hostSocket=null;
84     try{
85     _logger.write(toString(), Logger.SYSMSG, "Waiting for Connection");
86     // This will block until a host connects - at which point we get a Socket
87     hostSocket = listenPort.accept();
88     _logger.write(toString(), Logger.SYSMSG, "Connection accepted from: " + hostSocket.toString());
89     }
90     catch(IOException e){
91     // Something went wrong with the ServerSocket, so we'll stop listening
92     run=false;
93     }
94     // If we've stopped on the line above we won't want to try this !
95     if(run){
96     try {
97     // Setup the HostInit so it can carry on communications with the host
98 tdb 1.6 TCPReaderInit init = new TCPReaderInit(hostSocket, _queue);
99 tdb 1.1 // and start it
100     init.start();
101     } catch (IOException e) {
102     _logger.write(toString(), Logger.ERROR, e.toString());
103     }
104     }
105     }
106     // Best log the fact that we're stopping
107     _logger.write(toString(), Logger.FATAL, "Fatal error, shutdown pending");
108     }
109    
110     /**
111     * Overrides the {@link java.lang.Object#toString() Object.toString()}
112     * method to provide clean logging (every class should have this).
113     *
114 ajm 1.5 * This uses the uk.ac.ukc.iscream.util.NameFormat class
115     * to format the toString()
116     *
117 tdb 1.1 * @return the name of this class and its CVS revision
118     */
119     public String toString() {
120 ajm 1.5 return FormatName.getName(
121     _name,
122     getClass().getName(),
123     REVISION);
124 tdb 1.1 }
125    
126     //---PRIVATE METHODS---
127    
128     //---ACCESSOR/MUTATOR METHODS---
129    
130     //---ATTRIBUTES---
131    
132     /**
133 ajm 1.5 * This is the friendly identifier of the
134     * component this class is running in.
135     * eg, a Filter may be called "filter1",
136     * If this class does not have an owning
137     * component, a name from the configuration
138     * can be placed here. This name could also
139     * be changed to null for utility classes.
140     */
141     private String _name = FilterMain.NAME;
142    
143     /**
144     * This holds a reference to the
145     * system logger that is being used.
146 tdb 1.1 */
147 ajm 1.5 private Logger _logger = ReferenceManager.getInstance().getLogger();
148 tdb 1.1
149     /**
150     * The port on which the server should listen.
151     */
152     private int _port;
153    
154 tdb 1.6 private Queue _queue;
155 tdb 1.1
156     //---STATIC ATTRIBUTES---
157    
158     }