serious memory leak in the producer subsystem fixed
authorzapata <zapata>
Sun, 30 Oct 2005 00:46:57 +0000 (00:46 +0000)
committerzapata <zapata>
Sun, 30 Oct 2005 00:46:57 +0000 (00:46 +0000)
12 files changed:
source/mir/entity/AbstractEntity.java
source/mir/storage/store/StoreIdentifier.java
source/mir/util/HTMLRoutines.java
source/mircoders/entity/EntityComment.java
source/mircoders/entity/EntityContent.java
source/mircoders/entity/EntityImages.java
source/mircoders/entity/EntityUploadedMedia.java
source/mircoders/entity/EntityVideo.java
source/mircoders/global/JobQueue.java
source/mircoders/global/ProducerEngine.java
source/mircoders/localizer/basic/MirBasicOpenPostingLocalizer.java
source/mircoders/servlet/ServletModuleComment.java

index a56572e..108f424 100755 (executable)
@@ -44,7 +44,7 @@ import mir.storage.Database;
  * Base class the entities are derived from. Provides base functionality of
  * an entity.
  *
- * @version $Id: AbstractEntity.java,v 1.8.2.7 2005/03/26 11:26:23 zapata Exp $
+ * @version $Id: AbstractEntity.java,v 1.8.2.8 2005/10/30 00:46:57 zapata Exp $
  */
 
 public class AbstractEntity implements Entity {
@@ -52,11 +52,8 @@ public class AbstractEntity implements Entity {
 
   protected Map values;
   protected Database database;
-  protected LoggerWrapper logger;
 
   public AbstractEntity() {
-    logger = new LoggerWrapper("Entity");
-
     values = new HashMap();
   }
 
@@ -90,7 +87,7 @@ public class AbstractEntity implements Entity {
 
   /** {@inheritDoc} */
   public String insert() throws DatabaseExc {
-    logger.debug("Entity: trying to insert ...");
+    getLogger().debug("Entity: trying to insert ...");
 
     if (database != null) {
       return database.insert(this);
@@ -130,7 +127,7 @@ public class AbstractEntity implements Entity {
     if (hasField(theProp))
       values.put(theProp, theValue);
     else {
-      logger.warn("Entity.setFieldValue: Property not found: " + theProp + " (" + theValue + ")");
+      getLogger().warn("Entity.setFieldValue: Property not found: " + theProp + " (" + theValue + ")");
     }
   }
 
@@ -149,5 +146,9 @@ public class AbstractEntity implements Entity {
   public boolean hasField(String fieldName) throws DatabaseFailure {
     return getFieldNames().contains(fieldName);
   }
+
+  protected LoggerWrapper getLogger() {
+    return new LoggerWrapper("Entity");
+  }
 }
 
index de65c7a..bb98698 100755 (executable)
@@ -58,7 +58,7 @@ public class StoreIdentifier {
   private long timesUsed;
   private boolean invalidating = false;
 
-  protected LoggerWrapper logger = new LoggerWrapper("Database.ObjectStore");
+  protected static LoggerWrapper logger = new LoggerWrapper("Database.ObjectStore");
 
   public StoreIdentifier(StorableObject reference, int storeType,
                          String uniqueIdentifier) {
index c4a2e84..dd4882f 100755 (executable)
@@ -30,6 +30,8 @@
 
 package mir.util;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.net.URLEncoder;
 import java.util.HashMap;
 import java.util.Map;
@@ -37,17 +39,35 @@ import java.util.Map;
 public class HTMLRoutines {
   private HTMLRoutines() {
   }
-  
+
+  private static Method encodeURLMethod;
+  static {
+    try {
+      encodeURLMethod = URLEncoder.class.getMethod("encode", new Class[] {String.class});
+    }
+    catch (NoSuchMethodException e) {
+      throw new RuntimeException(e.getMessage());
+    }
+  }
+
   /**
    * Encodes a URL: escapes reserved URL characters like &, = into % escape
    *    constructions.
    */
   public static String encodeURL(String aString) {
-    return URLEncoder.encode(aString);
+    try {
+      return (String) encodeURLMethod.invoke(URLEncoder.class, new Object[] {aString});
+    }
+    catch (IllegalAccessException e) {
+      throw new RuntimeException(e.getMessage());
+    }
+    catch (InvocationTargetException e) {
+      throw new RuntimeException(e.getMessage());
+    }
   }
 
   public static String encodeURL(String aString, String anEncoding) {
-    return URLEncoder.encode(aString);
+    return encodeURL(aString);
   }
 
   private static final char[] CHARACTERS_TO_ESCAPE = { '&', '<', '>', '"' };
index 022ccfe..2e9e8db 100755 (executable)
@@ -41,7 +41,7 @@ import mircoders.storage.DatabaseContent;
  * This class maps one line of the comment-table to a java-object.
  *
  * @author $Author: zapata $
- * @version $Revision: 1.16.2.6 $ $Date: 2005/03/26 11:26:26 $
+ * @version $Revision: 1.16.2.7 $ $Date: 2005/10/30 00:46:58 $
  */
 
 
@@ -75,8 +75,7 @@ public class EntityComment extends AbstractEntity {
   /**
    * Deattaches media from a comment
    */
-  public void dettach(String aCommentId,String aMediaId) throws DatabaseFailure
-  {
+  public void dettach(String aCommentId,String aMediaId) throws DatabaseFailure {
     if (aMediaId!=null){
       DatabaseCommentToMedia.getInstance().delete(aCommentId, aMediaId);
       DatabaseContent.getInstance().setUnproduced("id="+getFieldValue("to_media"));
@@ -94,7 +93,7 @@ public class EntityComment extends AbstractEntity {
       DatabaseContent.getInstance().setUnproduced("id="+getFieldValue("to_media"));
     }
     else {
-      logger.error("EntityContent: attach without mid");
+      getLogger().error("EntityContent: attach without mid");
     }
   }
 }
index d35ad7c..96ab2dc 100755 (executable)
@@ -44,22 +44,13 @@ import mircoders.storage.DatabaseContentToMedia;
  * this class implements mapping of one line of the database table content
  * to a java object
  *
- * @version $Id: EntityContent.java,v 1.19.2.11 2005/03/26 11:26:26 zapata Exp $
+ * @version $Id: EntityContent.java,v 1.19.2.12 2005/10/30 00:46:58 zapata Exp $
  * @author mir-coders group
  *
  */
 
 
 public class EntityContent extends AbstractEntity {
-  // constructors
-
-  public EntityContent()
-  {
-    super();
-
-    logger = new LoggerWrapper("Entity.Content");
-  }
-
   /**
    * set is_produced flag for the article
    */
@@ -114,7 +105,7 @@ public class EntityContent extends AbstractEntity {
       setProduced(false);
     }
     else {
-      logger.error("EntityContent: attach without mid");
+      getLogger().error("EntityContent: attach without mid");
     }
   }
 
index 21404d6..019ee22 100755 (executable)
@@ -50,8 +50,6 @@ public class EntityImages extends EntityUploadedMedia
   public EntityImages()
   {
     super();
-
-    logger = new LoggerWrapper("Entity.UploadedMedia.Images");
   }
 
   /**
index 74cb05c..578ad4b 100755 (executable)
@@ -41,16 +41,10 @@ import mircoders.storage.DatabaseUploadedMedia;
 /**
  *
  * @author mh, mir-coders group
- * @version $Id: EntityUploadedMedia.java,v 1.26.2.12 2005/03/26 11:26:26 zapata Exp $
+ * @version $Id: EntityUploadedMedia.java,v 1.26.2.13 2005/10/30 00:46:58 zapata Exp $
  */
 
 public class EntityUploadedMedia extends AbstractEntity {
-  public EntityUploadedMedia() {
-    super();
-
-    logger = new LoggerWrapper("Entity.UploadedMedia");
-  }
-
   public void update() throws DatabaseFailure {
     super.update();
 
index 00e3639..ed5b918 100755 (executable)
@@ -31,21 +31,14 @@ package mircoders.entity;
 
 import java.util.Map;
 
-import mir.log.LoggerWrapper;
-
 public class EntityVideo extends EntityUploadedMedia {
-  public EntityVideo() {
-    super();
-
-    logger = new LoggerWrapper("Entity.UploadedMedia.Video");
-  }
-
-  public void setFieldValues(Map theStringValues) {
-    if (theStringValues != null) {
-      if (!theStringValues.containsKey("is_published"))
-        theStringValues.put("is_published", "0");
+  public void setFieldValues(Map someFieldValues) {
+    if (someFieldValues != null) {
+      if (!someFieldValues.containsKey("is_published")) {
+        someFieldValues.put("is_published", "0");
+      }
     }
-    super.setFieldValues(theStringValues);
+    super.setFieldValues(someFieldValues);
   }
 
 }
\ No newline at end of file
index 5cc3a92..99ffed7 100755 (executable)
@@ -82,8 +82,9 @@ public class JobQueue {
 
   public String appendJob(Job aJob, String aDescription) {
     try {
-      if (System.currentTimeMillis() - lastCleanup > 60000)
+      if (System.currentTimeMillis() - lastCleanup > 60000) {
         cleanupJobList();
+      }
     }
     catch (Throwable t) {
       logger.error("error while cleaning up joblist: " + t.toString());
@@ -92,8 +93,10 @@ public class JobQueue {
     synchronized (jobHandlers) {
       JobHandler jobHandler = new JobHandler(aJob, Integer.toString(nrJobs), aDescription);
       nrJobs++;
+
       jobHandlers.add(jobHandler);
       identifierToJobHandler.put(jobHandler.getIdentifier(), jobHandler);
+
       jobHandler.setPending();
 
       jobHandlers.notify();
@@ -103,6 +106,10 @@ public class JobQueue {
   }
 
   public List getJobsInfo() {
+    if (System.currentTimeMillis() - lastCleanup > 60000) {
+      cleanupJobList();
+    }
+
     List result = new ArrayList();
 
     synchronized (jobHandlers) {
@@ -132,6 +139,7 @@ public class JobQueue {
         synchronized (jobHandler) {
           if (jobHandler.isFinished() && jobHandler.getLastChange().before(treshold)) {
             toRemove.add(jobHandler);
+            identifierToJobHandler.remove(jobHandler.getIdentifier());
           }
         }
       }
index d60345b..de40217 100755 (executable)
  */
 package mircoders.global;
 
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
 import mir.config.MirPropertiesConfiguration;
-import mir.log.LoggerToWriterAdapter;
 import mir.log.LoggerWrapper;
 import mir.producer.Producer;
 import mir.producer.ProducerFactory;
@@ -45,32 +37,30 @@ import mir.producer.ProductionContext;
 import mir.util.GeneratorFormatAdapters;
 import mir.util.StringRoutines;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Collections;
+
 public class ProducerEngine {
-  private JobQueue producerJobQueue;
-  private LoggerWrapper logger;
-  private Map nameToFactory;
-  private List factories;
+  private final JobQueue producerJobQueue;
+  private final LoggerWrapper logger = new LoggerWrapper("Producer");
+  private final Map nameToFactory = new HashMap();;
+  private List factories = new ArrayList();
 
   protected ProducerEngine() {
-    logger = new LoggerWrapper("Producer");
     producerJobQueue = new JobQueue(new LoggerWrapper("Producer.Queue"));
-
-    factories = new ArrayList();
-    nameToFactory = new HashMap();
-
-    try {
-      reloadConfiguration();
-    }
-    catch (Throwable t) {
-    }
+    reloadConfiguration();
   }
 
   /**
    * Reloads the producer configuration
    */
-  public void reloadConfiguration()  throws MirGlobalExc, MirGlobalFailure {
+  public void reloadConfiguration() {
     try {
-      factories = MirGlobal.localizer().producers().loadFactories();
+      factories = new ArrayList(MirGlobal.localizer().producers().loadFactories());
 
       synchronized (nameToFactory) {
         nameToFactory.clear();
@@ -100,21 +90,21 @@ public class ProducerEngine {
    * Returns all factories
    */
   public List getFactories() {
-    return factories;
+    return Collections.unmodifiableList(factories);
   }
   /**
    * Adds a producer job to the queue
    */
   public void addJob(String aProducerFactory, String aVerb) throws MirGlobalExc, MirGlobalFailure {
-    ProducerFactory factory;
+    ProducerFactory factory = getFactoryForName( aProducerFactory );
 
-    factory = getFactoryForName( aProducerFactory );
-
-    if (factory==null)
+    if (factory==null) {
       throw new MirGlobalExc("Unknown producer: " + aProducerFactory);
+    }
 
-    if (!factory.allowVerb(aVerb))
+    if (!factory.allowVerb(aVerb)) {
       throw new MirGlobalExc("illegal producer/verb combination: " + aProducerFactory+"::"+aVerb);
+    }
 
     producerJobQueue.appendJob(
         new ProducerJob(aProducerFactory, aVerb), aProducerFactory+"."+aVerb);
@@ -139,26 +129,34 @@ public class ProducerEngine {
   }
 
   private String convertStatus(JobQueue.JobInfo aJob) {
+
     switch (aJob.getStatus()) {
       case JobQueue.STATUS_ABORTED:
         return "aborted";
+
       case JobQueue.STATUS_CANCELLED:
         return "cancelled";
+
       case JobQueue.STATUS_CREATED:
         return "created";
+
       case JobQueue.STATUS_PENDING:
         return "pending";
+
       case JobQueue.STATUS_PROCESSED:
         return "processed";
+
       case JobQueue.STATUS_PROCESSING:
         return "processing";
     }
+
     return "unknown";
   }
 
   private Map convertJob(JobQueue.JobInfo aJob) {
     try {
       Map result = new HashMap();
+
       result.put("identifier", aJob.getIdentifier());
       result.put("description", aJob.getDescription());
       result.put("priority", new Integer(aJob.getPriority()));
@@ -198,7 +196,7 @@ public class ProducerEngine {
     private Producer producer;
     private ProductionContext productionContext;
 
-    public ProducerJob(String aFactory, String aVerb) {
+    ProducerJob(String aFactory, String aVerb) {
       factoryName = aFactory;
       verb = aVerb;
       producer=null;
@@ -219,22 +217,14 @@ public class ProducerEngine {
     }
 
     public boolean run() {
-      final ProducerFactory factory;
-      long startTime;
-      long endTime;
-      boolean result = false;
       final Map startingMap = new HashMap();
-      Map mirMap = new HashMap();
-      mirMap.put("producer", factoryName);
-      mirMap.put("verb", verb);
 
-      startingMap.put("Mir", mirMap);
-
-      startTime = System.currentTimeMillis();
+      long startTime = System.currentTimeMillis();
       logger.info("Producing job: "+factoryName+"."+verb);
+      boolean result = false;
 
       try {
-        factory = getFactoryForName(factoryName);
+        final ProducerFactory factory = getFactoryForName(factoryName);
 
         if (factory!=null) {
           MirGlobal.localizer().producerAssistant().initializeGenerationValueSet(startingMap);
@@ -272,9 +262,11 @@ public class ProducerEngine {
                 return startingMap;
               }
             };
+
             result = producer.execute(productionContext);
             productionContext = null;
             producer = null;
+
             try {
               MirGlobal.localizer().producers().afterProducerTask(factoryName, verb);
             }
@@ -285,10 +277,10 @@ public class ProducerEngine {
         }
       }
       catch (Throwable t) {
-        logger.error("Exception occurred while producing " + factoryName + "." + verb + t.getMessage());
-        t.printStackTrace(new PrintWriter(new LoggerToWriterAdapter(logger, LoggerWrapper.ERROR_MESSAGE)));
+        logger.error("Exception occurred while producing " + factoryName + "." + verb, t);
       }
-      endTime = System.currentTimeMillis();
+      long endTime = System.currentTimeMillis();
+
       logger.info("Done producing job: " + factoryName + "." + verb + ", time elapsed:" + (endTime-startTime) + " ms");
 
       return result;
@@ -317,18 +309,18 @@ public class ProducerEngine {
     }
 
     public static List parseProducerTaskList(String aList) throws MirGlobalExc {
-      Iterator i;
       List result = new ArrayList();
 
-      i = StringRoutines.splitString(aList, ";").iterator();
+      Iterator i = StringRoutines.splitString(aList, ";").iterator();
       while (i.hasNext()) {
         String taskExpression = ((String) i.next()).trim();
 
         if (taskExpression.length()>0) {
           List parts = StringRoutines.splitString(taskExpression, ".");
 
-          if (parts.size() != 2)
+          if (parts.size() != 2) {
             throw new MirGlobalExc("Invalid producer expression: '" + taskExpression + "'");
+          }
           result.add(new ProducerEngine.ProducerTask( (String) parts.get(0), (String) parts.get(1)));
         }
       }
index b6833ed..0133316 100755 (executable)
@@ -35,6 +35,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Random;
+import java.util.Collections;
 
 import mir.config.MirPropertiesConfiguration;
 import mir.log.LoggerWrapper;
@@ -171,8 +172,9 @@ public class MirBasicOpenPostingLocalizer implements MirOpenPostingLocalizer {
     long l = System.currentTimeMillis();
 
     l = (l*l*l*l)/random;
-    if (l<0)
+    if (l<0) {
       l = l * -1;
+    }
 
     String returnString = ""+l;
 
@@ -180,11 +182,11 @@ public class MirBasicOpenPostingLocalizer implements MirOpenPostingLocalizer {
   }
 
   public List getAntiAbuseFilterTypes() {
-    return filterTypes;
+    return Collections.unmodifiableList(filterTypes);
   }
 
   public boolean allowArticlePublication(EntityContent anArticle){
-    return (anArticle!=null) && "t".equals(anArticle.getFieldValue("is_published"));
+    return anArticle != null && "1".equals(anArticle.getFieldValue("is_published"));
   }
 
   public void removeSimpleAntiAbuseFilterType(String aName) {
index 8f6bbeb..b712314 100755 (executable)
@@ -124,8 +124,7 @@ public class ServletModuleComment extends AdminServletModule {
     }
   }
 
-  public void attach(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
-  {
+  public void attach(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
     String  mediaIdParam = aRequest.getParameter("mid");
     String  commentId = aRequest.getParameter("commentid");
 
@@ -146,8 +145,7 @@ public class ServletModuleComment extends AdminServletModule {
     editObject(aRequest, aResponse, commentId);
   }
 
-  public void dettach(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
-  {
+  public void dettach(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
     String  commentId = aRequest.getParameter("commentid");
     String  midParam = aRequest.getParameter("mid");
     if (commentId == null) {