safety checks and informational Errors generated when IClientDocument is not stored...
authorjprocter <jprocter@compbio.dundee.ac.uk>
Fri, 17 Aug 2007 14:41:01 +0000 (14:41 +0000)
committerjprocter <jprocter@compbio.dundee.ac.uk>
Fri, 17 Aug 2007 14:41:01 +0000 (14:41 +0000)
git-svn-id: https://svn.lifesci.dundee.ac.uk/svn/repository/trunk@434 be28352e-c001-0410-b1a7-c7978e42abec

src/uk/ac/vamsas/client/simpleclient/EventGeneratorThread.java
src/uk/ac/vamsas/client/simpleclient/SimpleClient.java
src/uk/ac/vamsas/client/simpleclient/VamsasSession.java

index 311c825..4a0b1fb 100644 (file)
@@ -83,7 +83,15 @@ public class EventGeneratorThread {
     */
     log.debug("Watchers inited.");
   }
-  void _raise(String handlerEvent, String property, Object oldval, Object newval) {
+  /**
+   * Call registered handlers for a vamsas session event
+   * @param handlerEvent a named event
+   * @param property property name to pass to handler
+   * @param oldval old value of property to pass
+   * @param newval new value of property to pass
+   * @return true if event generation did not raise any exceptions.
+   */
+  boolean _raise(String handlerEvent, String property, Object oldval, Object newval) {
     PropertyChangeSupport h = (PropertyChangeSupport) handlers.get(handlerEvent);
     if (h!=null) {
       log.debug("Triggering:"+handlerEvent);
@@ -91,10 +99,17 @@ public class EventGeneratorThread {
         h.firePropertyChange(property, oldval, newval);
       } catch (Exception e) {
         log.warn("Client Exception during handling of "+handlerEvent, e);
+        return false;
+      }
+      catch (Error e)
+      {
+        log.error("Serious! Client Error during handling of "+handlerEvent, e);
+        return false;
       }
       log.debug("Finished  :"+handlerEvent);
     } else
       log.debug("No handlers for raised "+handlerEvent);
+    return true;
   }
   protected boolean storeDocRequest(Lock lock) {
     if (log.isDebugEnabled())
@@ -115,13 +130,38 @@ public class EventGeneratorThread {
       session.vamArchive.fileLock=doclock;
       if (client.pickmanager!=null)
         client.pickmanager.setPassThru(false);
+      if (log.isDebugEnabled()) {
+        log.debug("Initiating a documentChanged event. Document is "+(client.cdocument==null ? "closed" : "open"));
+      }
       // TODO: decide if individual object update handlers are called as well as overall event handler
-      _raise(Events.DOCUMENT_UPDATE, client.getSessionUrn(), null, client);
+      if (!_raise(Events.DOCUMENT_UPDATE, client.getSessionUrn(), null, client))
+      {
+        log.info("Recovering from errors or exceptions generated by client application");
+        if (client.cdocument!=null)
+        {
+          try {
+            client.tidyAwaySessionDocumentState(); 
+          }
+          catch (Exception e)
+          {
+            log.warn("Exception generated by vamsas library - when tidying away session document:",e);
+          }
+          catch (Error e)
+          {
+            log.error("LIBRARY Implementation error - when tidying away session document:",e);
+          }
+        }
+          
+      }
       if (client.pickmanager!=null)
         client.pickmanager.setPassThru(true);
       if (log.isDebugEnabled()) {
         log.debug("Finished handling a documentChanged event. Document is "+(client.cdocument==null ? "closed" : "open"));
       }
+      if (client.cdocument!=null)
+      {
+        log.warn("Implementation Error ?  ClientDocument instance has not been closed or updated by handler!");
+      }
       /*try {
         client._session.getVamsasDocument().closeArchive();
       } catch (Exception e) {log.warn("Unexpected exception when closing document after update.",e);};
index fccfba7..8e8fba2 100644 (file)
@@ -313,32 +313,23 @@ public class SimpleClient implements IClient {
       throw new Error("Client Error - updateDocument() called before getClientDocument() on this SimpleClient instance.");
     if (newdoc!=cdocument)
       throw new Error("Client Error - SimpleClient.updateDocument() can only take the IClientDocument instance returned from SimpleClient.getClientDocument()");
-
+    
     if (evgen.isDocumentWatchEnabled())
-      throw new Error("Client Error - or Library Bug : Document watcher still enabled whilst ClientDocument instance exists.");
+      throw new Error("Probable Client Error (did you remember to call SimpleClient.updateDocument(clientdoc) at the end of the document update handler?) - or Library Bug : Document watcher still enabled whilst ClientDocument instance exists.");
     
     if (!cdocument.isModified()) {
       // client document is silently got rid of, with no session update events.
       if (log.isDebugEnabled())
         log.debug("updateDocument for "+session.getSessionUrn()+" with unmodified IClientDocument (skipping the write)");
     } else {
-      try {
-        boolean updated=cdocument.updateSessionDocument();
-        if (!updated) {
-          log.warn("Session document did not update properly for session directory "+_session.sessionDir);
-          // cdocument.archive.cancelArchive(); // LATER: could be done - would need to prevent updateSessionDocument closing the iohandler.
-          _session.slog.warn("Session Document updated but may not be valid (false return from org.vamsas.simpleclient.ClientDocument.updateSessionDocument()");
-        } else {
-               log.debug("Document update successful.");
-        }
-        _session.setUnsavedFlag();
-      }
-      catch (IOException e) {
-        log.warn("IO Problems when updating document!",e);
-        _session.slog.error("IO problems when attempting to update document.");
-      }
+      writeSessionDocument();
     }
-    // garbage collect the ClientDocument instance.
+    tidyAwaySessionDocumentState(); 
+  }
+  /**
+   * garbage collect the ClientDocument instance and re-enable watchers.
+   */
+  protected void tidyAwaySessionDocumentState() {
     try {
       log.debug("Finalizing ClientDocument instance.");
       cdocument.finalize();
@@ -355,7 +346,28 @@ public class SimpleClient implements IClient {
       _session.slog.error("IO problems when attempting to release lock on session document.");
     }
   }
-  
+
+  /**
+   * write the cdocument instance to the session for real.
+   */
+  private void writeSessionDocument() {
+    try {
+      boolean updated=cdocument.updateSessionDocument();
+      if (!updated) {
+        log.warn("Session document did not update properly for session directory "+_session.sessionDir);
+        // cdocument.archive.cancelArchive(); // LATER: could be done - would need to prevent updateSessionDocument closing the iohandler.
+        _session.slog.warn("Session Document updated but may not be valid (false return from org.vamsas.simpleclient.ClientDocument.updateSessionDocument()");
+      } else {
+        log.debug("Document update successful.");
+      }
+      _session.setUnsavedFlag();
+    }
+    catch (IOException e) {
+      log.warn("IO Problems when updating document!",e);
+      _session.slog.error("IO problems when attempting to update document.");
+    }
+  }
+
   /*
    * (non-Javadoc)
    * 
@@ -511,23 +523,27 @@ public class SimpleClient implements IClient {
   protected void releaseActiveClientFile() throws IOException
   {
    
-    log.debug("Releasing active client file");
+    log.debug("Releasing active client locks");
     if( activeClientFilelock != null)
     {// Release the lock
+      log.debug("Releasing lock on active client lock file");
       activeClientFilelock.release();
+      log.debug("ReleaseActiveClientFile called when client has no lock on its clientLockFile");
       activeClientFilelock = null;
     } else {
       log.debug("ReleaseActiveClientFile called when client has no lock on its clientLockFile");
     }
     if (this.clientlockFile != null)
     {
+      log.debug("trying to delete active client lock file");
       if (this.clientlockFile.exists())
-      this.clientlockFile.delete();
-      log.debug("deleted active client lock file");
+      {
+        this.clientlockFile.delete();
+        log.debug("deleted active client lock file");
+      }
     } else {
       log.debug("ReleaseActiveClientFile called when client has no clientLockFile");
     }
-
   }
   
   protected void  createActiveClientFile() throws IOException
@@ -566,4 +582,12 @@ public class SimpleClient implements IClient {
   protected File getClientlockFile() {
     return clientlockFile;
   }
+  /**
+   * 
+   * @return the lock for the client in the session
+   */
+  protected Lock getClientLock() {
+    return activeClientFilelock;
+  }
+
 }
index b24ef68..2ae181d 100644 (file)
@@ -486,52 +486,38 @@ public class VamsasSession {
       client.evgen.stopWatching();
       cwe.setHandler(null);
       
-//    ask to the client to copy application data into the document
+      // ask to the client to copy application data into the document
       client.evgen._raise(Events.DOCUMENT_FINALIZEAPPDATA, null, client,null);
-      
-      if ( this.isLastActiveClient(client))
-        {
+      boolean closeSession=isLastActiveClient(client);
+      if (closeSession)
+      {
         log.debug("Raising request-to-save event");
         client.evgen._raise(Events.DOCUMENT_REQUESTTOCLOSE, null, client, null);
-        //client.evgen._raise(Events.SESSION_SHUTDOWN, null, client.getSessionHandle(), null);
-        log.debug("Last active client: closing session");
-        log.info("Closing session");
-          getSessionManager().removeSession(client.getSessionHandle());
-        }
-      
+        client.evgen._raise(Events.SESSION_SHUTDOWN, null, client.getSessionHandle(), null);
+      }
       try 
         {
-          log.debug("Releasing  active client file");
+          log.debug("Attempting to release active client locks");
           client.releaseActiveClientFile();
         }
       catch (IOException e)
         {
           log.error("error during active file client release");
          }
-    }
-   
-  
-   
-    /*clist.removeClient(client.getClientHandle(),null);
-    if (this.clist.retrieveClientList() == null|| this.clist.retrieveClientList().length<1)
-      {//assume it is the last client has been removed shutting down session
-        slog.info("last client removed: removing session");
-        log.debug("last client removed: removing session");
-        this.getSessionManager().removeSession(client.getSessionHandle());
-      }
-    else
+      if (closeSession)
       {
-        int active=clist.retrieveClientList().length;
-        log.debug("Still "+active+" active clients");
-        slog.info("Still "+active+" active clients");
-      }*/
-   
+        log.debug("Last active client: closing session");
+        log.info("Closing session");
+          getSessionManager().removeSession(client.getSessionHandle());
+      }
+    }
   }
   
   
   private boolean isLastActiveClient(SimpleClient client)
     {
     log.debug("Testing if current client is the last one.");
+    log.debug("current client lockfile is '"+client.getClientlockFile()+"'");
       boolean noOtherActiveClient = true;
       //create, if need,  subdirectory to contain client files
       File clientlockFileDir = new File (this.sessionDir, clientFileDirectory);
@@ -554,7 +540,7 @@ public class VamsasSession {
           {
              File clientFile = clientFiles[i];
              log.debug("testing file for lock: "+clientFile.getAbsolutePath());
-             if(client.getClientlockFile().equals(clientFile)) 
+             if(client.getClientLock().isTargetLockFile(clientFile)) 
                {
                log.debug("current client file found");
                  continue;
@@ -693,6 +679,7 @@ public class VamsasSession {
          
             }
               log.debug("Stopping EventGenerator..");
+              // TODO: ensure ClientsFile lock is really released!! clist.unlockFile();
           client.evgen.stopWatching();
         }
           watcher.setHandler(null);//Do not check if the client is the last client. watcher will shutdown anyway
@@ -712,7 +699,7 @@ public class VamsasSession {
 //   close document 
       client.evgen._raise(Events.DOCUMENT_REQUESTTOCLOSE, null, client,null);
       log.debug("close document request done");
-      this.closeSession(client.getSessionHandle());
+      closeSession(client.getSessionHandle());
     }
   
   /**