root/server/WebServer.java

Revision 71, 10.3 kB (checked in by kbarnes3, 2 years ago)

Added Jay's original code for the Overhaul test server.

Line 
1 /* An example of a very simple, multi-threaded HTTP server.
2  * Implementation notes are in WebServer.html, and also
3  * as comments in the source code.
4  */
5 import java.io.BufferedOutputStream;
6 import java.io.BufferedReader;
7 import java.io.File;
8 import java.io.FileOutputStream;
9 import java.io.InputStreamReader;
10 import java.io.PrintStream;
11 import java.net.InetAddress;
12 import java.net.ServerSocket;
13 import java.net.Socket;
14 import java.util.Calendar;
15 import java.util.HashMap;
16 import java.util.Properties;
17 import java.util.Vector;
18 import java.util.concurrent.ExecutorService;
19 import java.util.concurrent.Executors;
20
21 class WebServer implements HttpConstants {
22
23         /* static class data/methods */
24
25         /* print to stdout */
26         protected static void p(String s) {
27                 System.out.println(s);
28         }
29
30         /* print to the log file */
31         protected static void log(String s) {
32                 synchronized (log) {
33                         log.println(s);
34                         log.flush();
35                 }
36         }
37        
38         protected static void log2(String s) {
39                 synchronized (log2) {
40                         log2.println(s);
41                         log2.flush();
42                 }
43         }
44        
45         static Vector<OverhaulClient> overhaulClients = new Vector<OverhaulClient>();
46         static HashMap<String, OverhaulFile> overhaulFiles = new HashMap<String, OverhaulFile>();
47
48         static PrintStream log = null;
49         static PrintStream log2 = null;
50
51         /*
52          * our server's configuration information is stored in these properties
53          */
54         protected static Properties props = new Properties();
55
56         /* Where worker threads stand idle */
57         static Vector threads = new Vector();
58
59         /* the web server's virtual root */
60         static File root;
61        
62         /* top accessed documents */
63         static Vector<String> topFiles = new Vector<String>();
64        
65         /* top k documents -- value of k to be overhauled in p2pizer */
66         static int topK;
67        
68         static boolean topKMode = false;
69        
70         static boolean inTopKMode() {
71
72                 // looks like the following code initializes the value of topKMode
73                 //if (topKMode == false) {
74                 //      topKMode = (topK > 0);
75                 //}
76                 
77                 //return topKMode;
78                 return false;
79         }
80
81         /* timeout on client connections */
82         static int timeout = 0;
83
84         /* max # worker threads */
85         static int workers = 5;
86        
87         static int overhaulMaxChunks = 8;
88         static int overhaulMinChunkSize = 512;
89         static int overhaulMaxClients = 20;
90         static int overhaulSendClients = 10;
91         static long firstHitTS;
92
93         static Detector detector;
94        
95         static void printProps() {
96                 p("root=" + root);
97                 //p("timeout=" + timeout);
98                 //p("workers=" + workers);
99         }
100        
101         static boolean inOverhaulMode() {
102                
103                 //return (Calendar.getInstance().getTimeInMillis() - firstHitTS > 1890*1000);
104
105                 //return false;
106                 return true;
107                 //return detector.isFlashcrowd();
108         }
109        
110         static boolean topKFilesInclude(String name) {
111                
112                 if (topK <= 0) {
113                         return false;
114                 }
115                
116                 //System.out.println("Requested file: " + name);
117                 
118                 //String basename = name.substring(name.lastIndexOf(File.separatorChar));
119                 for(int i = 0; i < topK; i++) {
120                         if (topFiles.get(i).equals(name)) {
121                                 return true;
122                         }
123                 }
124                
125                 return false;
126         }
127        
128         static String getTopKFiles() {
129                
130                 String ret = "";
131                 for(int i = 0; i < topK; i++) {
132                         if (i != 0) {
133                                 ret += " ";
134                         }
135                         ret += topFiles.get(i);
136                 }
137                
138                 return ret;
139         }
140
141         private static Vector<InetAddress> clients = new Vector<InetAddress>();
142
143         public static synchronized boolean addOverhaulClient(InetAddress client) {
144                
145                 WebServer.log("Adding OverhaulClient: " + client + " to File");
146                
147                 if (client == null) {
148                         return false;
149                 }
150
151                 // do not repeat
152                 if (clients.contains(client)) {
153                         return false;
154                 }
155                        
156                 // remove excess clients, should actually only be used once
157                 while (clients.size() >= overhaulMaxClients) {
158                         clients.remove(0);
159                 }
160                        
161                 // actually add the client
162                 return clients.add(client);
163         }
164
165         public static synchronized String getOverhaulClientsStr() {             
166                
167                 if (clients.size() == 0) {
168                         return "FIRST";
169                 }
170                
171                 String ret = "";
172                
173                 int numClients = Math.min(clients.size(), overhaulSendClients);
174                
175                 for(int i = 0; i < numClients ; i++) {
176                         if (i != 0) {
177                                 ret += " ";
178                         }
179                        
180                         // TODO: fix this hack, bad, bad hack.
181                         // currently using a uniform global port for the entire system
182                         ret += clients.get(i).getHostAddress();
183                 }
184                
185                 return ret;
186         }
187
188        
189         static synchronized void insertFileIntoOverhaulProcess(String f, OverhaulFile of) {
190                 if (overhaulFiles.containsKey(f)) {
191                         return; // should actually throw an error
192                 }
193                 overhaulFiles.put(f, of);
194         }
195        
196         static synchronized boolean isFileInOverhaulProcess(String f) {
197                 return overhaulFiles.containsKey(f);
198         }
199        
200         static synchronized OverhaulFile getOverhaulFile(String f) {
201                 return overhaulFiles.get(f);
202         }
203
204         static HashMap<String, OverhaulFile> getOverhaulFiles() {
205                 return overhaulFiles;
206         }
207        
208         static int BW_LIMIT = 150000;
209
210         public static void main(String[] a) throws Exception {
211                
212                 if (a.length != 4 || a[0] == null || a[1] == null || a[2] == null || a[3] == null) {
213                         System.err.println("Usage: java WebServer $WEB_ROOT $LOG_FILE $TOP_DOCS_FILE $TOP_K_DOCS");
214                         return;
215                 }
216                
217                 root = new File(a[0]);
218                 if (!root.isDirectory()) {
219                         System.err.println("Usage: java WebServer $WEB_ROOT $LOG_FILE $TOP_DOCS_FILE $TOP_K_DOCS");
220                         return;
221 //              } else {
222 //                      String[] list = root.list();
223 //              for (int i = 0; list != null && i < list.length; i++) {
224 //                p(list[i]);
225 //              }
226                 }
227                
228                 log = new PrintStream(new BufferedOutputStream(new FileOutputStream(a[1])));
229                 log2 = new PrintStream(new BufferedOutputStream(new FileOutputStream(a[1] + "2")));
230                
231                 topK = new Integer(a[3]).intValue();
232                
233 /*
234                 if (a[2] != null) {
235                 
236                         try {
237
238                                 FileInputStream fis = new FileInputStream(new File(a[2]));
239                                 BufferedReader inStream = new BufferedReader(new InputStreamReader(
240                                         fis));
241
242                                 p("Reading file: " + a[2]);
243
244                                 //The input pattern that we're looking for
245                                 //Pattern fetchPattern = Pattern.compile("(\\d+)\\s+(\\d+.\\d+.\\d+.\\d+)\\s+(\\S+)\\s+(\\d+)");
246                                 Pattern fetchPattern = Pattern
247                                         .compile("(\\d+)\\s+(\\d+)");
248
249                                 Matcher pm = null; // Pattern matcher
250
251                                 // Read the "load" file
252                                 String line = inStream.readLine();
253
254                                 while (line != null) {
255
256                                         if (pm == null) {
257                                                 pm = fetchPattern.matcher(line);
258                                         } else {
259                                                 pm.reset(line);
260                                         }
261
262                                         if (pm.find()) {
263                                                 int URLid = new Integer(pm.group(1)).intValue();
264                                                 int numBytes = new Integer(pm.group(2)).intValue();
265                                                 topFiles.add(URLid + "_" + numBytes);
266                                         }
267
268                                         line = inStream.readLine();
269                                 }
270
271                                 System.out.println("Loaded (in memory): " + topFiles.size()     + " files");
272                         } catch (Exception e) {
273                                 e.printStackTrace();
274                                 System.err.println("Missing top.docs file!");
275                                 return;
276                         }
277                 }
278 */
279                
280                 int port = 8080;
281                 timeout = 300; //in seconds
282                 workers = 150;
283                
284                 printProps();
285
286                 //detector = new Detector(5, 0.001, 0.1, 0, 0.01, 2.5, 0.5);
287                 //detector = new Detector(10, 0.002, 0.6, 0, 0.01, 2.5, 0.5);
288                                 
289                 detector = new Detector(120, 10);
290                
291                 //Thread detectorThread = new Thread(detector);
292                 //detectorThread.start();
293
294                 ServerSocket ss = new ServerSocket(port, 511);
295                
296                 // this listens to the outgoing bandwidth
297                 //ServerSocket bw = new ServerSocket(4123);
298                 //Socket c = bw.accept();
299                 //new Adaptor(c).start();
300
301                 ExecutorService pool = Executors.newFixedThreadPool(workers);
302                
303                 firstHitTS = -1;
304
305                 try {
306                        
307                         //boolean notDoubled = true;
308                         
309                         BW_LIMIT = 300000;
310                        
311                         while (true) {
312                                 // the following call blocks until there is a new incoming connection
313                                 Socket s = ss.accept();
314                                
315                                 if (firstHitTS == -1 ) {
316                                         firstHitTS = Calendar.getInstance().getTimeInMillis();
317                                 }
318                                
319                                
320                                 long currTS = Calendar.getInstance().getTimeInMillis();
321                                
322                                 /*
323                                 
324                                 int timeSinceFirstRequest = (int) (currTS - firstHitTS) / 1000;
325                                 if (timeSinceFirstRequest > 40*60 ) {
326                                         BW_LIMIT = 150000;
327                                 } else  if (timeSinceFirstRequest > 20*60 ) {
328                                         BW_LIMIT = 250000;
329                                 } else {
330                                         BW_LIMIT = 100000000;
331                                 }
332                                 */
333                                
334                                 //detector.addHit();
335                                 pool.execute(new Worker(s, currTS));
336                         }
337                 } catch (Exception e) {
338                         pool.shutdown();
339                         e.printStackTrace();
340                 }
341         }
342
343         public static int getSessionCount() {
344                 // TODO Auto-generated method stub
345                 // fill this in Jay!
346                 return 0;
347         }
348 }
349
350 class Adaptor extends Thread {
351        
352         static int WINDOW_SIZE = 15;
353         static int DOWN_THRESHOLD = 6;
354         static int UP_THRESHOLD = 3;
355         Socket c;
356         Vector<Integer> window = new Vector<Integer>();
357        
358         public Adaptor(Socket c) {
359                 this.c = c;
360         }
361
362         public void run() {
363                                
364                 try {
365                        
366                         BufferedReader is = new BufferedReader(new InputStreamReader(c.getInputStream()));
367                        
368                         String line = is.readLine();
369                        
370                         int timeSinceKChanged = 0;
371                         int avg = 0;
372                        
373                         long firstTS = Calendar.getInstance().getTimeInMillis();
374                        
375                         while (line != null && line.equals("") != true) {
376                                
377                                 int bw = new Integer(line).intValue() * 8;
378                                
379                                 if (window.size() > WINDOW_SIZE ) {
380                                         window.remove(0);
381                                 }
382                                
383                                 window.add(bw);
384                                
385                                 int totalBits = 0;
386                                 for (int i = 0; i < window.size(); i++ ) {
387                                         totalBits += window.get(i);
388                                 }
389                                 avg = totalBits / window.size();
390                                
391                                 long currTS = Calendar.getInstance().getTimeInMillis();
392                                 WebServer.log2(((currTS - firstTS) / 1000) + " " + WebServer.topK + " " + bw + " " + avg);                             
393                                
394                                 //avg = bw;
395                                 
396                                 timeSinceKChanged++;
397                                
398                                 if (avg < WebServer.BW_LIMIT * 0.75 && bw < WebServer.BW_LIMIT * 0.5 && WebServer.topK > 0) {
399                                         if (timeSinceKChanged >= DOWN_THRESHOLD) {
400                                                 WebServer.topK /= 2;
401                                                 timeSinceKChanged = 0;
402                                         }
403                                 } else if (avg < WebServer.BW_LIMIT * 0.90 &&  bw < WebServer.BW_LIMIT * 0.80 && WebServer.topK > 0) {
404                                         if (timeSinceKChanged >= DOWN_THRESHOLD) {
405                                                 WebServer.topK--;
406                                                 timeSinceKChanged = 0;
407                                         }
408                                 } else if (bw > WebServer.BW_LIMIT * 1.5 || avg > WebServer.BW_LIMIT * 0.95) {
409                                         if (timeSinceKChanged >= UP_THRESHOLD) {
410                                                 WebServer.topK += 5;
411                                                 timeSinceKChanged = 0;
412                                         }
413                                 } else if (bw > WebServer.BW_LIMIT || avg > WebServer.BW_LIMIT * 0.80) {
414                                         if (timeSinceKChanged >= UP_THRESHOLD) {
415                                                 WebServer.topK++;
416                                                 timeSinceKChanged = 0;
417                                         }
418                                 }
419                                
420                                
421                                 /*
422                                 if (avg < WebServer.BW_LIMIT * 0.60) {
423                                         if (timeSinceKChanged >= DOWN_THRESHOLD) {
424                                                 WebServer.topK--;
425                                                 timeSinceKChanged = 0;
426                                         }
427                                 } else if (avg > WebServer.BW_LIMIT * 0.75) {
428                                         if (timeSinceKChanged >= UP_THRESHOLD) {
429                                                 WebServer.topK++;
430                                                 timeSinceKChanged = 0;
431                                         }
432                                 }
433                                 */
434                                  
435                                 WebServer.topK = Math.min(WebServer.topK, 50);
436                                 WebServer.topK = Math.max(WebServer.topK, 0);
437                                
438                                 line = is.readLine();
439                         }
440                 } catch (Exception e) {
441                         e.printStackTrace();
442                 }
443                
444         }
445
446        
447 }
Note: See TracBrowser for help on using the browser.