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/FilterThread.java
Revision: 1.15
Committed: Fri Jan 12 00:45:25 2001 UTC (23 years, 4 months ago) by tdb
Branch: MAIN
Changes since 1.14: +48 -44 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.8 //---PACKAGE DECLARATION---
2     package uk.ac.ukc.iscream.filter;
3    
4     //---IMPORTS---
5 pjm2 1.1 import java.io.*;
6     import java.net.*;
7     import java.util.*;
8 pjm2 1.6 import uk.ac.ukc.iscream.core.*;
9 tdb 1.2 import uk.ac.ukc.iscream.filter.*;
10 ajm 1.11 import uk.ac.ukc.iscream.util.*;
11 pjm2 1.1
12 tdb 1.8 /**
13 ajm 1.14 * Handle an incoming packet as a separate thread.
14     * Passes the data through various plugins, then
15     * passes it on to the parent filter.
16 tdb 1.8 *
17 tdb 1.15 * Now grabs data from a single queue, rather than
18     * waiting to be contacted.
19     *
20     * @author $Author: ajm4 $
21     * @version $Id: FilterThread.java,v 1.14 2000/12/13 13:36:46 ajm4 Exp $
22 tdb 1.8 */
23 tdb 1.2 public class FilterThread extends Thread{
24 pjm2 1.1
25 tdb 1.8 //---FINAL ATTRIBUTES---
26    
27     /**
28     * The current CVS revision of this class
29     */
30 tdb 1.15 public final String REVISION = "$Revision: 1.14 $";
31 tdb 1.8
32     //---STATIC METHODS---
33    
34     //---CONSTRUCTORS---
35 tdb 1.15
36 ajm 1.14 /**
37 tdb 1.15 * Class constructor.
38 ajm 1.14 */
39 tdb 1.15 public FilterThread(Queue queue, Filter parent){
40 tdb 1.10 _parent = parent;
41 tdb 1.15 _queue = queue;
42 ajm 1.14 _logger.write(toString(), Logger.DEBUG, "created");
43 pjm2 1.1 }
44 tdb 1.8
45     //---PUBLIC METHODS---
46    
47 ajm 1.14 /**
48     * Runs the thread
49     */
50 pjm2 1.1 public void run(){
51 tdb 1.15 // get a queue for ourselves
52     int n = _queue.getQueue();
53     // keep this out here, saves recreating the object
54     String xml = null;
55     while(true) {
56     // get a String of xml
57     try {
58     xml = (String) _queue.get(n);
59     }
60     catch (InvalidQueueException e) {
61     _logger.write(toString(), Logger.ERROR, "Queue error: "+e);
62     }
63    
64     // Get a string without any null characters in it.
65     // -- maybe String.trim() would be better here ?
66     if (xml.indexOf(0) != -1) {
67     xml = xml.substring(0, xml.indexOf(0));
68     }
69     else {
70     xml = xml.substring(0, xml.length());
71     }
72    
73     // Use XMLPacketMaker to make an XMLPacket object.
74     XMLPacketMaker xmlPacketMaker = new XMLPacketMaker(xml);
75     XMLPacket packet = xmlPacketMaker.createXMLPacket();
76    
77     if(packet != null && PluginFilterManager.getInstance().runFilters(packet)) {
78     // packet is not null
79     // packet was not dropped by a plugin
80     // ... best pass it on !
81     _parent.receiveXML(xml);
82     }
83     else {
84     // either we had a null, or a plugin dropped it
85     _logger.write(toString(), Logger.DEBUG, "An XML packet was sucessfully filtered from the system.");
86     }
87 pjm2 1.1 }
88     }
89 tdb 1.8
90     /**
91     * Overrides the {@link java.lang.Object#toString() Object.toString()}
92     * method to provide clean logging (every class should have this).
93     *
94 ajm 1.14 * This uses the uk.ac.ukc.iscream.util.NameFormat class
95     * to format the toString()
96     *
97 tdb 1.8 * @return the name of this class and its CVS revision
98     */
99     public String toString() {
100 ajm 1.14 return FormatName.getName(
101     _name,
102     getClass().getName(),
103     REVISION);
104 tdb 1.8 }
105    
106     //---PRIVATE METHODS---
107    
108     //---ACCESSOR/MUTATOR METHODS---
109    
110     //---ATTRIBUTES---
111    
112 ajm 1.14 /**
113     * Our parent filter
114     */
115 tdb 1.10 Filter _parent;
116 ajm 1.14
117     /**
118 tdb 1.15 * The Queue object
119 ajm 1.14 */
120 tdb 1.15 Queue _queue;
121 ajm 1.14
122     /**
123     * This is the friendly identifier of the
124     * component this class is running in.
125     * eg, a Filter may be called "filter1",
126     * If this class does not have an owning
127     * component, a name from the configuration
128     * can be placed here. This name could also
129     * be changed to null for utility classes.
130     */
131     private String _name = FilterMain.NAME;
132    
133     /**
134     * This holds a reference to the
135     * system logger that is being used.
136     */
137     private Logger _logger = ReferenceManager.getInstance().getLogger();
138 tdb 1.8
139     //---STATIC ATTRIBUTES---
140    
141 pjm2 1.1 }