Changeset 17630 for gli


Ignore:
Timestamp:
2008-10-29T20:04:25+13:00 (15 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 edited

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        }
Note: See TracChangeset for help on using the changeset viewer.