Changeset 17525
- Timestamp:
- 2008-10-13T21:40:31+13:00 (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
gli/trunk/src/org/greenstone/gatherer/download/DownloadJob.java
r13594 r17525 76 76 77 77 private String download_url = ""; 78 78 79 79 // private String current_url; 80 80 // private String destination; … … 96 96 public static int DEFINED_MAX = 1; 97 97 public static int UNDEFINED_MAX = 2; 98 98 99 // To prematurely terminate wget, we will need to use sockets and find a free port. 100 // We will look at a limited range of ports. This range will be reused (circular buffer) 101 private static final int PORT_BASE = 50000; 102 private static final int PORT_BLOCK_SIZE = 100; 103 private static int nextFreePort = PORT_BASE; // Keep track what port numbers we have checked for availability 104 int port; // package access. The socket port number this instance of DownloadJob will use 105 99 106 private String mode = null; 100 107 101 108 private String proxy_url; 102 109 103 110 /** 104 111 */ … … 169 176 // The stop_start_button is used to alternately start or stop the 170 177 // job. If the current state of the job is paused then this 171 // restart is logically equiv elent to a resume.178 // restart is logically equivalent to a resume. 172 179 if(event.getSource() == progress.stop_start_button) { 173 180 previous_state = state; … … 189 196 } 190 197 198 /** Given a portnumber to check, returns true if it is available 199 * (if nothing's listening there already). */ 200 public static boolean isPortAvailable(int portnum) { 201 Socket tmpSocket = null; 202 try { 203 tmpSocket = new Socket("localhost", portnum); 204 tmpSocket.close(); 205 return false; 206 207 } catch(ConnectException ex){ 208 // "Signals that an error occurred while attempting to connect a socket 209 // to a remote address and port. Typically, the connection was refused 210 // remotely (e.g., no process is listening on the remote address/port)." 211 System.err.println("Port " + portnum + " not yet in use."); 212 tmpSocket = null; 213 return true; 214 215 } catch(Exception ex) { 216 // includes BindException "Signals that an error occurred while attempting 217 // to bind a socket to a local address and port. Typically, the port is in 218 // use, or the requested local address could not be assigned." 219 tmpSocket = null; 220 return false; 221 } 222 } 223 224 /** Circular buffer. Modifies the value of nextFreePort (the buffer index). */ 225 private void incrementNextFreePort() { 226 int offset = nextFreePort - PORT_BASE; 227 offset = (offset + 1) % PORT_BLOCK_SIZE; 228 nextFreePort = PORT_BASE + offset; 229 } 191 230 192 231 public void callDownload() { … … 202 241 command_list.add("-cache_dir"); 203 242 command_list.add(Gatherer.getGLIUserCacheDirectoryPath()); 243 // For the purposes of prematurely terminating wget from GLI (which creates a socket 244 // as a communication channel between GLI and Perl), it is important to tell the script 245 // that we're running as GLI. Because when running from the command prompt, it should 246 // not create this socket and do the related processing. 247 command_list.add("-gli"); 204 248 205 249 ArrayList all_arg = download.getArguments(true,false); … … 252 296 } 253 297 } 254 255 298 //System.out.println(newcmd); 256 299 257 InputStreamReader isr = new InputStreamReader(prcs.getErrorStream()); 258 BufferedReader br = new BufferedReader(isr); 259 // Capture the standard error stream and seach for two particular occurances. 300 // Can use the following if debugging WgetDownload.pm - Reads debug stmts from the perl process' STDIN stream 301 //(new PerlReaderThread(prcs)).start(); 302 303 InputStream is = prcs.getInputStream(); 304 BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 305 306 // To be able to stop Wget, we use sockets to communicate with the perl process that launched wget 307 if (!mode.equals("Z3950") && !mode.equals("SRW")) { // wget-based Download modes (OAI, MediaWiki and Web download) 308 309 // Need to find an available (unused) port within the range we're looking for to pass it 310 // the Perl child process, so that it may set up a listening ServerSocket at that port number 311 try { 312 boolean foundFreePort = false; 313 for(int i = 0; i < PORT_BLOCK_SIZE; i++) { 314 315 if(isPortAvailable(nextFreePort)) { 316 foundFreePort = true; 317 break; 318 319 } else { 320 incrementNextFreePort(); 321 } 322 } 323 324 if(foundFreePort) { 325 // Free port number currently found becomes the port number of the socket that this 326 // DownloadJob instance will be connecting to when the user wants to prematurely stop Wget. 327 this.port = nextFreePort; 328 incrementNextFreePort(); 329 330 } else { 331 throw new Exception("Cannot find an available port in the range " 332 + PORT_BASE + "-" + (PORT_BASE+PORT_BLOCK_SIZE) 333 + "\nwhich is necessary for forcibly terminating wget."); 334 } 335 336 // Communicate the chosen port for this DownloadJob instance to the perl process, so 337 // that it can set up a ServerSocket at that port to listen for any signal to terminate wget 338 OutputStream os = prcs.getOutputStream(); 339 String p = ""+this.port+"\n"; 340 System.err.println("Portnumber found: " + p); 341 342 os.write(p.getBytes()); 343 os.close(); 344 345 } catch(Exception ex) { 346 System.err.println("Sent available portnumber " + this.port + " to process' outputstream.\nBut got exception: " + ex); 347 } 348 } 349 350 BufferedReader br = new BufferedReader(new InputStreamReader(prcs.getErrorStream())); 351 // Capture the standard error stream and search for two particular occurrences. 260 352 String line=""; 261 353 boolean ignore_for_robots = false; 262 354 int max_download = DownloadJob.UNKNOWN_MAX; 263 264 355 265 356 while ((line = br.readLine()) != null && !line.trim().equals("<<Finished>>") && state != STOPPED) { 266 267 357 if ( max_download == DownloadJob.UNKNOWN_MAX) { 268 358 if(line.lastIndexOf("<<Defined Maximum>>") != -1) { … … 356 446 } 357 447 if(state == STOPPED) { 358 isr.close(); 359 prcs.destroy(); // This doesn't always work, but it's worth a try 448 // When GLI is working with wget-based download modes (OAI, MediaWiki and Web download) 449 // and the STOP button has been pressed, wget needs to be prematurely terminated. 450 // The presence of the tmpfile will indicate to the perl script that it's time to kill wget. 451 if(prcs != null && !mode.equals("Z3950") && !mode.equals("SRW")) { 452 453 // create a socket to the perl child process and communicate the STOP message 454 Socket clientSocket = null; 455 if(clientSocket == null) { 456 try { 457 clientSocket = new Socket("localhost", this.port); // connect to the port chosen for this DownloadJob instance 458 459 BufferedReader clientReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 460 String response = clientReader.readLine(); // see if we've been connected 461 System.err.println("Communicating with perl download script on port " + this.port 462 + "\nGot response from perl: " + response); 463 464 // Send the STOP signal 465 OutputStream os = clientSocket.getOutputStream(); 466 String message = "<<STOP>>\n"; 467 os.write(message.getBytes()); 468 response = clientReader.readLine(); // see whether the stop signal has been received 469 System.err.println("GLI sent STOP signal to perl to terminate wget." 470 + "\nGot response from perl: " + response); 471 os.close(); 472 473 clientReader.close(); 474 clientSocket.close(); // close the clientSocket (the Perl end will close the server socket that Perl opened) 475 clientReader = null; 476 clientSocket = null; 477 } catch(IOException ex) { 478 System.err.println("Tried to communicate through client socket - port " + this.port + ", but got exception: " + ex); 479 } catch(Exception ex) { 480 System.err.println("Tried to open client socket, but got exception: " + ex); 481 } 482 } 483 } 484 485 //prcs.getInputStream().close(); 486 prcs.getErrorStream().close(); 487 prcs.destroy(); // This doesn't always work, but it's worth a try 488 prcs = null; 489 br.close(); 490 br = null; 491 492 // Notify the DownloadScrollPane which is waiting on this job to complete that we are ready 493 synchronized(this) { 494 this.notify(); 495 } 360 496 } 361 362 497 } 363 498 catch (Exception ioe) { … … 372 507 previous_state = state; 373 508 state = DownloadJob.COMPLETE; 374 375 509 } 376 510 // refresh the workspace tree 377 511 Gatherer.g_man.refreshWorkspaceTree(WorkspaceTree.DOWNLOADED_FILES_CHANGED); 378 379 512 } 380 513 … … 464 597 progress.updateProgress(current, expected); 465 598 } 599 600 601 // Inner thread class that reads from process downloadfrom.pl's errorstream 602 private class PerlReaderThread extends Thread { 603 Process prcs = null; 604 605 public PerlReaderThread(Process proc) { 606 this.prcs = proc; 607 } 608 609 public void run() { 610 try { 611 if(prcs != null) { 612 String message = null; 613 BufferedReader eReader = new BufferedReader(new InputStreamReader(prcs.getInputStream())); 614 while(prcs != null && (message = eReader.readLine()) != null) { 615 System.err.println("**** Perl STDOUT: " + message); 616 } 617 618 if(prcs != null && eReader != null) { 619 eReader.close(); 620 eReader = null; 621 System.err.println("**** Perl ENDed."); 622 } 623 } 624 } catch(Exception e) { 625 System.err.println("Thread - caught exception: " + e); 626 } 627 } 628 } 466 629 }
Note:
See TracChangeset
for help on using the changeset viewer.