Changeset 17630 for gli/trunk

Show
Ignore:
Timestamp:
29.10.2008 20:04:25 (11 years ago)
Author:
ak19
Message:

1. Previously the GLI client and GLI applet used to have a problem that manifested very rarely and randomly: every so often, one of the gliserver Action commands would get stuck in an infinite wait loop. The current code, after running it about 50 times and not showing this problem anymore, seems to have fixed this. The changes made were to RemoteGreenstoneServer?.performAction() where a wait() is now used instead of a timed wait() and the ActionQueue?.java class where more methods are now synchronised and the infinite while loop in the Thread's run() method has been reorganised to check for any increase in the size of the action queue at the start. 2. An exit condition is now used instead of an infinite while loop in ActionQueue?'s run(), so that the loop is terminated when the user cancels or a connect exception occurs. This ends the thread (which is particularly necessary in Applets, else they keep consuming processor time). RemoteGreenstoneServer?.performAction() checks for whether the ActionQueue? thread has exited and if so GLI's Gatherer exits, otherwise performAction proceeds to add the next action to the queue as before.

Location:
gli/trunk/src/org/greenstone/gatherer/remote
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • gli/trunk/src/org/greenstone/gatherer/remote/ActionQueue.java

    r17612 r17630  
    3333import java.util.zip.*; 
    3434import javax.swing.*; 
    35 import java.io.ByteArrayOutputStream; 
    3635import org.greenstone.gatherer.Configuration; 
    3736import org.greenstone.gatherer.DebugStream; 
     
    6867    /** The queue of waiting jobs. */ 
    6968    private ArrayList queue = null; 
    70      
    71      
     69    private boolean exited; 
     70 
    7271    public ActionQueue() 
    7372    { 
     73    super("RemoteGreenstoneServerActionQueue"); 
     74    exited = false; 
    7475    if (Gatherer.isGsdlRemote) { 
    7576        queue = new ArrayList(); 
     
    8687     
    8788     
    88     public int size() 
     89    synchronized public int size() 
    8990    { 
    9091    return queue.size(); 
    9192    } 
    9293     
     94    synchronized public RemoteGreenstoneServerAction getAction(int i) 
     95    { 
     96    return (RemoteGreenstoneServerAction)queue.get(i); 
     97    } 
     98 
     99    synchronized public boolean hasExited() {  
     100    return exited;  
     101    } 
    93102     
     103    synchronized public void clear() {  
     104    queue.clear();  
     105    } 
     106 
    94107    public void run() 
    95108    { 
    96109    boolean exit = false; 
     110 
    97111    while (!exit) { 
    98         // If there are jobs on the queue, get the next in line and process it 
    99         if (queue.size() > 0) { 
    100         RemoteGreenstoneServerAction remote_greenstone_server_action = (RemoteGreenstoneServerAction) queue.get(0); 
     112        RemoteGreenstoneServerAction remote_greenstone_server_action = null; 
     113         
     114        // Wait until we are notify()ed by addAction that there is a new job on the queue 
     115        try { 
     116        Gatherer.remoteGreenstoneServer.getProgressBar().setAction(null); 
     117        synchronized (this) { 
     118            while(queue.size() <= 0) { 
     119            wait(); // wait for queue size to become > 0, which is done by external thread (performAction()) 
     120            } 
     121            // Now there is at least one job on the queue, get the next in line and process it 
     122            remote_greenstone_server_action = (RemoteGreenstoneServerAction) queue.get(0); //getAction(0) is already synchronized  
     123        } 
     124        } catch (InterruptedException exception) { 
     125        // It may be that GLI is exiting if we get here  
     126        exit = true; 
     127        } 
     128         
     129        if(exit) { 
     130        break; 
     131        } 
     132         
     133        try { 
     134        remote_greenstone_server_action.perform(); 
    101135         
    102         try { 
    103             remote_greenstone_server_action.perform(); 
    104              
    105             // No exceptions were thrown, so the action was successful 
    106             remote_greenstone_server_action.processed_successfully = true; 
     136        // No exceptions were thrown, so the action was successful 
     137        remote_greenstone_server_action.processed_successfully = true; 
     138        } 
     139        catch (RemoteGreenstoneServerAction.ActionCancelledException exception) { 
     140        remote_greenstone_server_action.processed_successfully = false; 
     141        }  
     142        catch(java.net.ConnectException exception) { 
     143        if(exception.getMessage().trim().startsWith("Connection refused")) { 
     144            exit = true; 
     145        } else { 
     146            DebugStream.printStackTrace(exception); 
    107147        } 
    108         catch (RemoteGreenstoneServerAction.ActionCancelledException exception) { 
    109             remote_greenstone_server_action.processed_successfully = false; 
    110             exit = true; 
    111         }  
    112         catch(java.net.ConnectException exception) { 
    113             if(exception.getMessage().trim().startsWith("Connection refused")) { 
    114             exit = true; 
    115             } else { 
    116             DebugStream.printStackTrace(exception); 
    117             } 
    118             JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("RemoteGreenstoneServer.Error", exception.getMessage()), Dictionary.get("RemoteGreenstoneServer.Error_Title"), JOptionPane.ERROR_MESSAGE); 
    119             remote_greenstone_server_action.processed_successfully = false;          
     148        JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("RemoteGreenstoneServer.Error", exception.getMessage()), Dictionary.get("RemoteGreenstoneServer.Error_Title"), JOptionPane.ERROR_MESSAGE); 
     149        remote_greenstone_server_action.processed_successfully = false;          
     150        } 
     151        catch (FileNotFoundException exception) { 
     152        // FileNotFoundException happens when there's no GS server at the user-provided 
     153        // url (the address of gliserver.pl is wrong). 
     154        exit = true; 
     155        DebugStream.printStackTrace(exception); 
     156        JOptionPane.showMessageDialog(Gatherer.g_man,  
     157                          Dictionary.get("RemoteGreenstoneServer.Error",  
     158                                 "No gliserver.pl found. " + exception.getMessage()),  
     159                          Dictionary.get("RemoteGreenstoneServer.Error_Title"),  
     160                          JOptionPane.ERROR_MESSAGE); 
     161        remote_greenstone_server_action.processed_successfully = false; 
     162        } 
     163        catch (Exception exception) { 
     164        DebugStream.printStackTrace(exception); 
     165        JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("RemoteGreenstoneServer.Error", exception.getMessage()), Dictionary.get("RemoteGreenstoneServer.Error_Title"), JOptionPane.ERROR_MESSAGE); 
     166        remote_greenstone_server_action.processed_successfully = false; 
     167        } 
     168         
     169        // We're done with this action, for better or worse 
     170        try { 
     171        remote_greenstone_server_action.processed = true; 
     172        synchronized(remote_greenstone_server_action) { 
     173            remote_greenstone_server_action.notifyAll(); // notifies RemoteGreenstoneServer.performAction() 
    120174        } 
    121         catch (FileNotFoundException exception) { 
    122             // FileNotFoundException happens when there's no GS server at the user-provided 
    123             // url (the address of gliserver.pl is wrong). 
    124             exit = true; 
    125             DebugStream.printStackTrace(exception); 
    126             JOptionPane.showMessageDialog(Gatherer.g_man,  
    127                           Dictionary.get("RemoteGreenstoneServer.Error",  
    128                                  "No gliserver.pl found. " + exception.getMessage()),  
    129                           Dictionary.get("RemoteGreenstoneServer.Error_Title"),  
    130                           JOptionPane.ERROR_MESSAGE); 
    131             remote_greenstone_server_action.processed_successfully = false; 
    132         } 
    133         catch (Exception exception) { 
    134             DebugStream.printStackTrace(exception); 
    135             JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("RemoteGreenstoneServer.Error", exception.getMessage()), Dictionary.get("RemoteGreenstoneServer.Error_Title"), JOptionPane.ERROR_MESSAGE); 
    136             remote_greenstone_server_action.processed_successfully = false; 
    137         } 
    138          
    139         // We're done with this action, for better or worse 
    140         remote_greenstone_server_action.processed = true; 
     175        } catch (Exception exception) { 
     176        System.err.println("RemoteGreenstoneServerActionQueue.run() - exception: " + exception); 
     177        } 
     178        synchronized (this) { // remove the action just processed from the queue, since it's done. 
    141179        queue.remove(0); 
    142180        } 
    143          
    144         // Otherwise the queue is empty 
    145         else { 
    146         Gatherer.remoteGreenstoneServer.getProgressBar().setAction(null); 
    147          
    148         // Wait until we are notify()ed by addAction that there is a new job on the queue 
    149         synchronized (this) { 
    150             try { 
    151             wait(); 
    152             } 
    153             catch (InterruptedException exception) { } 
    154         } 
    155         } 
    156          
    157181    } 
    158     // stop the gazillion annoying error messages when the connection was simply 
    159     // refused or when the user pressed Cancel in the opening dialog, by exitting 
    160     // cleanly in one go. 
    161     //if(exit == true) { 
    162         //Gatherer.exit(); 
    163     //} 
     182 
     183    // Out of while, means exit = true 
     184    // Stop the gazillion annoying error messages when the connection was simply 
     185    // refused or when the user pressed Cancel in the opening dialog, by clearing 
     186    // the action queue of subsequent actions and setting exited to true. 
     187    synchronized(this) { 
     188        queue.clear(); 
     189        exited = true; 
     190    } 
    164191    } 
    165192} 
  • gli/trunk/src/org/greenstone/gatherer/remote/RemoteGreenstoneServer.java

    r17612 r17630  
    6666 
    6767    public RemoteGreenstoneServer() { 
     68    // Create the progress_bar first since ActionQueue uses it in its thread  
     69    // (the thread will start immediately). 
     70    progress_bar = new RemoteGreenstoneServer.ProgressBar(); 
    6871    remote_greenstone_server_action_queue = new ActionQueue(); 
    69     progress_bar = new RemoteGreenstoneServer.ProgressBar(); 
    7072    } 
    7173 
     
    230232    } 
    231233    } 
    232  
     234     
    233235 
    234236    // ---------------------------------------------------------------------------------------------------- 
     
    240242    private String performAction(RemoteGreenstoneServerAction remote_greenstone_server_action) 
    241243    { 
     244    // Check for whether the queue thread stopped running because  
     245    // the user cancelled out. If so, exit GLI. 
     246    if(remote_greenstone_server_action_queue.hasExited()) { 
     247        remote_greenstone_server_action_queue.clear(); 
     248        //remote_greenstone_server_action_queue = null; 
     249        Gatherer.exit(); 
     250        return ""; 
     251    } 
     252 
    242253    // Add the action to the queue 
    243254    remote_greenstone_server_action_queue.addAction(remote_greenstone_server_action); 
     255    String threadName = Thread.currentThread().getName(); 
    244256 
    245257    // If we're running in the GUI thread we must return immediately 
    246258    // We cannot wait for the action to complete because this will block any GUI updates 
    247259    if (SwingUtilities.isEventDispatchThread()) { 
    248         System.err.println("WARNING: In event dispatch thread, returning immediately..."); 
     260        System.err.println(threadName  
     261                   + "\tACTION QUEUED: In event dispatch thread, returning immediately...\n\t"  
     262                   + remote_greenstone_server_action); 
    249263        return null; 
    250264    } 
    251265 
    252266    // Otherwise wait until the action is processed 
    253     while (!remote_greenstone_server_action.processed) { 
     267    try { 
    254268        synchronized (remote_greenstone_server_action) { 
    255         try { 
     269        while(!remote_greenstone_server_action.processed) { 
     270            //System.err.println("Waiting for action to complete...: " + remote_greenstone_server_action); 
    256271            DebugStream.println("Waiting for action to complete..."); 
    257             remote_greenstone_server_action.wait(500); 
     272            remote_greenstone_server_action.wait(); // wait to be notified when the action has been processed  
    258273        } 
    259         catch (InterruptedException exception) {} 
    260         } 
     274        } 
     275    } catch (Exception e) { 
     276        System.err.println("RemoteGreenstoneServer.performAction() - exception: " + e); 
     277        e.printStackTrace(); 
    261278    } 
    262279 
     
    285302    } 
    286303 
    287  
    288     public void setAction(String action) 
     304    /** synchronized to avoid conflicts since several threads access this */ 
     305    synchronized public void setAction(String action) 
    289306    { 
    290307        if (action != null) { 
     
    310327    } 
    311328     
    312     public RemoteGreenstoneServer.ProgressBar getProgressBar() 
     329    /** synchronized to avoid conflicts since several threads access this */ 
     330    synchronized public RemoteGreenstoneServer.ProgressBar getProgressBar() 
    313331    { 
    314332    return progress_bar; 
     
    327345        remote_greenstone_server_authentication = new RemoteGreenstoneServerAuthenticator().getAuthentication(); 
    328346    } 
    329  
     347     
    330348 
    331349    static private class RemoteGreenstoneServerAuthenticator 
     
    366384        } 
    367385        catch (Exception exception) { 
     386        System.err.println("Exception occurred when authenticating the user: " + exception); 
    368387        DebugStream.printStackTrace(exception); 
    369388        }