extensions/net.sf.basedb.varsearch/trunk/src/net/sf/basedb/varsearch/service/VarSearchService.java

Code
Comments
Other
Rev Date Author Line
6111 29 Jan 21 nicklas 1 package net.sf.basedb.varsearch.service;
6111 29 Jan 21 nicklas 2
6111 29 Jan 21 nicklas 3 import java.io.File;
6111 29 Jan 21 nicklas 4 import java.io.IOException;
6111 29 Jan 21 nicklas 5 import java.util.Collection;
6248 25 May 21 nicklas 6 import java.util.LinkedHashMap;
6112 02 Feb 21 nicklas 7 import java.util.List;
6111 29 Jan 21 nicklas 8 import java.util.Map;
6167 09 Mar 21 nicklas 9 import java.util.Set;
6111 29 Jan 21 nicklas 10 import java.util.TimerTask;
6141 19 Feb 21 nicklas 11 import java.util.concurrent.Executors;
6111 29 Jan 21 nicklas 12
6111 29 Jan 21 nicklas 13 import org.slf4j.LoggerFactory;
6111 29 Jan 21 nicklas 14
6111 29 Jan 21 nicklas 15 import net.sf.basedb.clients.web.extensions.service.ServiceControllerAction;
6111 29 Jan 21 nicklas 16 import net.sf.basedb.clients.web.extensions.service.Services;
6111 29 Jan 21 nicklas 17 import net.sf.basedb.core.Application;
6111 29 Jan 21 nicklas 18 import net.sf.basedb.core.DbControl;
6111 29 Jan 21 nicklas 19 import net.sf.basedb.core.Include;
6111 29 Jan 21 nicklas 20 import net.sf.basedb.core.ItemList;
6111 29 Jan 21 nicklas 21 import net.sf.basedb.core.ItemQuery;
6111 29 Jan 21 nicklas 22 import net.sf.basedb.core.RawBioAssay;
6111 29 Jan 21 nicklas 23 import net.sf.basedb.core.SessionControl;
6111 29 Jan 21 nicklas 24 import net.sf.basedb.core.SystemItems;
6111 29 Jan 21 nicklas 25 import net.sf.basedb.core.User;
6374 07 Sep 21 nicklas 26 import net.sf.basedb.core.query.Expressions;
6374 07 Sep 21 nicklas 27 import net.sf.basedb.core.query.Hql;
6374 07 Sep 21 nicklas 28 import net.sf.basedb.core.query.Restrictions;
6111 29 Jan 21 nicklas 29 import net.sf.basedb.util.extensions.Extension;
7074 24 Mar 23 nicklas 30 import net.sf.basedb.util.extensions.logging.ExtensionsLog;
7074 24 Mar 23 nicklas 31 import net.sf.basedb.util.extensions.logging.ExtensionsLogger;
6145 23 Feb 21 nicklas 32 import net.sf.basedb.varsearch.dao.Annotationtype;
6112 02 Feb 21 nicklas 33 import net.sf.basedb.varsearch.dao.Datafiletype;
6111 29 Jan 21 nicklas 34 import net.sf.basedb.varsearch.dao.Itemlist;
6374 07 Sep 21 nicklas 35 import net.sf.basedb.varsearch.index.AnyToAnyVcfLocator;
6374 07 Sep 21 nicklas 36 import net.sf.basedb.varsearch.index.DatafileVcfLocator;
6132 16 Feb 21 nicklas 37 import net.sf.basedb.varsearch.index.LuceneIndex;
6541 17 Jan 22 nicklas 38 import net.sf.basedb.varsearch.index.VariantCallIndex;
6167 09 Mar 21 nicklas 39 import net.sf.basedb.varsearch.index.LuceneIndex.AutoUpdate;
6168 12 Mar 21 nicklas 40 import net.sf.basedb.varsearch.index.LuceneIndex.FullRebuildRunnable;
6168 12 Mar 21 nicklas 41 import net.sf.basedb.varsearch.index.LuceneIndex.QueryThreadFactory;
6168 12 Mar 21 nicklas 42 import net.sf.basedb.varsearch.index.LuceneIndex.Status;
6541 17 Jan 22 nicklas 43 import net.sf.basedb.varsearch.index.OncoArrayIndex;
6111 29 Jan 21 nicklas 44
6111 29 Jan 21 nicklas 45 public class VarSearchService 
6111 29 Jan 21 nicklas 46 {
7074 24 Mar 23 nicklas 47   /**
7074 24 Mar 23 nicklas 48     The ID of the service extension.
7074 24 Mar 23 nicklas 49     @since 1.8
7074 24 Mar 23 nicklas 50   */
7074 24 Mar 23 nicklas 51   public static final String ID = "net.sf.basedb.varsearch.service";
6111 29 Jan 21 nicklas 52
7074 24 Mar 23 nicklas 53   private static final ExtensionsLogger logger = 
7074 24 Mar 23 nicklas 54       ExtensionsLog.getLogger(ID, true).wrap(LoggerFactory.getLogger(VarSearchService.class));
6111 29 Jan 21 nicklas 55
6111 29 Jan 21 nicklas 56   // At least 15 minutes between index updates (30 seconds when debugging)
7074 24 Mar 23 nicklas 57   private static final long MIN_WAIT_INTERVAL_NORMAL = 900 * 1000;
7074 24 Mar 23 nicklas 58   private static final long MIN_WAIT_INTERVAL_DEBUG = 30 * 1000;
6111 29 Jan 21 nicklas 59
6140 19 Feb 21 nicklas 60   // If the number of raw bioassays is less than this, we wait a bit longer 
6140 19 Feb 21 nicklas 61   // to see if the list is filled with more...
6140 19 Feb 21 nicklas 62   private static final int EXTENDED_WAIT_LIMIT = 24;
6140 19 Feb 21 nicklas 63   // Max time to wait for more until we index (4 hours; 95 seconds when debugging)
7074 24 Mar 23 nicklas 64   private static final long MAX_EXTENDED_WAIT_NORMAL = 4 * 3600 * 1000;
7074 24 Mar 23 nicklas 65   private static final long MAX_EXTENDED_WAIT_DEBUG = 95 * 1000;
6111 29 Jan 21 nicklas 66   
6111 29 Jan 21 nicklas 67   // The singleton instance of the service
6111 29 Jan 21 nicklas 68   private static VarSearchService instance = null;
6111 29 Jan 21 nicklas 69   
6111 29 Jan 21 nicklas 70   /**
6111 29 Jan 21 nicklas 71     Get the singleton instance of the service. If the service has
6111 29 Jan 21 nicklas 72     not been created yet it is created at this time.
6111 29 Jan 21 nicklas 73   */
6111 29 Jan 21 nicklas 74   public static final VarSearchService getInstance()
6111 29 Jan 21 nicklas 75   {
6111 29 Jan 21 nicklas 76     if (instance == null)
6111 29 Jan 21 nicklas 77     {
6111 29 Jan 21 nicklas 78       synchronized (VarSearchService.class)
6111 29 Jan 21 nicklas 79       {
6111 29 Jan 21 nicklas 80         if (instance == null)
6111 29 Jan 21 nicklas 81         {
6111 29 Jan 21 nicklas 82           VarSearchService tmp = new VarSearchService();
6111 29 Jan 21 nicklas 83           instance = tmp;
6111 29 Jan 21 nicklas 84         }
6111 29 Jan 21 nicklas 85       }
6111 29 Jan 21 nicklas 86     }
6111 29 Jan 21 nicklas 87     
6111 29 Jan 21 nicklas 88     // Keep the session control alive
6111 29 Jan 21 nicklas 89     if (instance.rootSc != null) instance.rootSc.updateLastAccess();
6111 29 Jan 21 nicklas 90     
6111 29 Jan 21 nicklas 91     return instance;
6111 29 Jan 21 nicklas 92   }
6111 29 Jan 21 nicklas 93
6111 29 Jan 21 nicklas 94   
6111 29 Jan 21 nicklas 95   private volatile boolean isRunning;
6111 29 Jan 21 nicklas 96   private SessionControl systemSc;
6111 29 Jan 21 nicklas 97   private Extension<ServiceControllerAction> ext;
6111 29 Jan 21 nicklas 98   private SessionControl rootSc;
6111 29 Jan 21 nicklas 99   private TimerTask timer;
6111 29 Jan 21 nicklas 100   
6111 29 Jan 21 nicklas 101   // Time when last check for new data
6111 29 Jan 21 nicklas 102   private volatile long lastAutoUpdateCheck;
6111 29 Jan 21 nicklas 103   // If flag is set, we force check for new date
6111 29 Jan 21 nicklas 104   private volatile long forceUpdateCheck;
6111 29 Jan 21 nicklas 105
6111 29 Jan 21 nicklas 106   // Map Index ID -> LuceneIndex
6111 29 Jan 21 nicklas 107   private final Map<String, LuceneIndex> indexes;
6111 29 Jan 21 nicklas 108
6111 29 Jan 21 nicklas 109   
6111 29 Jan 21 nicklas 110   private VarSearchService()
6111 29 Jan 21 nicklas 111   {
6248 25 May 21 nicklas 112     indexes = new LinkedHashMap<>();
6111 29 Jan 21 nicklas 113   }
6111 29 Jan 21 nicklas 114
6111 29 Jan 21 nicklas 115   
6111 29 Jan 21 nicklas 116   /**
6111 29 Jan 21 nicklas 117     Is the service running or not?
6111 29 Jan 21 nicklas 118   */
6111 29 Jan 21 nicklas 119   public boolean isRunning()
6111 29 Jan 21 nicklas 120   {
6111 29 Jan 21 nicklas 121     return isRunning;
6111 29 Jan 21 nicklas 122   }
6111 29 Jan 21 nicklas 123   
6165 08 Mar 21 nicklas 124   /**
6168 12 Mar 21 nicklas 125     Get the session control used for this service.
6168 12 Mar 21 nicklas 126   */
6168 12 Mar 21 nicklas 127   public SessionControl getRootSessionControl()
6168 12 Mar 21 nicklas 128   {
6168 12 Mar 21 nicklas 129     return rootSc;
6168 12 Mar 21 nicklas 130   }
6168 12 Mar 21 nicklas 131   
6168 12 Mar 21 nicklas 132   /**
6165 08 Mar 21 nicklas 133     Get an index database by id.
6165 08 Mar 21 nicklas 134   */
6165 08 Mar 21 nicklas 135   public LuceneIndex getIndexById(String id)
6165 08 Mar 21 nicklas 136   {
6165 08 Mar 21 nicklas 137     return indexes.get(id);
6165 08 Mar 21 nicklas 138   }
6165 08 Mar 21 nicklas 139   
6165 08 Mar 21 nicklas 140   /**
6165 08 Mar 21 nicklas 141     Get all index databases.
6165 08 Mar 21 nicklas 142   */
6111 29 Jan 21 nicklas 143   public Collection<LuceneIndex> getIndexes()
6111 29 Jan 21 nicklas 144   {
6111 29 Jan 21 nicklas 145     return indexes.values();
6111 29 Jan 21 nicklas 146   }
6111 29 Jan 21 nicklas 147   
6111 29 Jan 21 nicklas 148   /**
6111 29 Jan 21 nicklas 149     Start the service if it is not running.
6111 29 Jan 21 nicklas 150   */
6111 29 Jan 21 nicklas 151   synchronized void start(SessionControl systemSc, Extension<ServiceControllerAction> ext)
6111 29 Jan 21 nicklas 152   {
6111 29 Jan 21 nicklas 153     if (isRunning) return;
6111 29 Jan 21 nicklas 154   
6111 29 Jan 21 nicklas 155     logger.debug("Starting Variant Indexing Service");
6111 29 Jan 21 nicklas 156   
6111 29 Jan 21 nicklas 157     try
6111 29 Jan 21 nicklas 158     {
6111 29 Jan 21 nicklas 159       this.systemSc = systemSc;
6111 29 Jan 21 nicklas 160       this.ext = ext;
6111 29 Jan 21 nicklas 161       this.rootSc = systemSc.impersonateLogin(SystemItems.getId(User.ROOT), "Variant Indexing Service");
6111 29 Jan 21 nicklas 162       
6111 29 Jan 21 nicklas 163       // Initialize LuceneIndexe:s
6111 29 Jan 21 nicklas 164       File dbDir = new File(Application.getUserFilesDirectory(), "lucene.db");
6111 29 Jan 21 nicklas 165       try
6111 29 Jan 21 nicklas 166       {
6541 17 Jan 22 nicklas 167         LuceneIndex filtered = new VariantCallIndex("filtered");
6111 29 Jan 21 nicklas 168         filtered.setName("Variants (filtered)");
6140 19 Feb 21 nicklas 169         filtered.setItemList(Itemlist.VARIANT_INDEX_FILTERED);
6141 19 Feb 21 nicklas 170         filtered.setMaxToIndex(2000);
6374 07 Sep 21 nicklas 171         filtered.setVcfFileLocator(new DatafileVcfLocator(Datafiletype.VCF, false));
6111 29 Jan 21 nicklas 172         filtered.open(new File(dbDir, "filtered"), null);
6111 29 Jan 21 nicklas 173         indexes.put(filtered.getId(), filtered);
6141 19 Feb 21 nicklas 174         
6541 17 Jan 22 nicklas 175         LuceneIndex raw = new VariantCallIndex("raw");
6112 02 Feb 21 nicklas 176         raw.setName("Variants (all)");
6141 19 Feb 21 nicklas 177         raw.setItemList(Itemlist.VARIANT_INDEX_ALL);
6374 07 Sep 21 nicklas 178         raw.setVcfFileLocator(new AnyToAnyVcfLocator("variants-annotated.vcf.gz"));
6525 20 Dec 21 nicklas 179         raw.setViewAllVariantsEnabled(false);
6168 12 Mar 21 nicklas 180         int numQueryThreads = Math.min(8, Runtime.getRuntime().availableProcessors());
6168 12 Mar 21 nicklas 181         raw.open(new File(dbDir, "raw"), numQueryThreads > 1 ? Executors.newFixedThreadPool(numQueryThreads, new QueryThreadFactory(raw.getId())) : null);
6111 29 Jan 21 nicklas 182         indexes.put(raw.getId(), raw);
6372 07 Sep 21 nicklas 183         
6541 17 Jan 22 nicklas 184         LuceneIndex targeted = new VariantCallIndex("targeted");
6407 17 Sep 21 nicklas 185         targeted.setName("Variants (targeted)");
6372 07 Sep 21 nicklas 186         targeted.setItemList(Itemlist.VARIANT_INDEX_TARGETED);
6377 08 Sep 21 nicklas 187         targeted.setIndexAllGenotypes(true);
6372 07 Sep 21 nicklas 188         targeted.setMaxToIndex(2000);
6374 07 Sep 21 nicklas 189         targeted.setVcfFileLocator(new AnyToAnyVcfLocator(
6374 07 Sep 21 nicklas 190             Restrictions.like(Hql.property("name"), Expressions.string("genotype_%.vcf")), 
6374 07 Sep 21 nicklas 191             "genotype_*.vcf"));
6372 07 Sep 21 nicklas 192         targeted.open(new File(dbDir, "targeted"), null);
6372 07 Sep 21 nicklas 193         indexes.put(targeted.getId(), targeted);
6541 17 Jan 22 nicklas 194         
6541 17 Jan 22 nicklas 195         LuceneIndex oncoArray500K = new OncoArrayIndex("oncoarray-500K");
6541 17 Jan 22 nicklas 196         oncoArray500K.setName("Genotyping (OncoArray500K)");
6541 17 Jan 22 nicklas 197         oncoArray500K.setItemList(Itemlist.GENOTYPING_ONCOARRAY_500K);
6541 17 Jan 22 nicklas 198         oncoArray500K.setIndexAllGenotypes(true);
6541 17 Jan 22 nicklas 199         oncoArray500K.setViewAllVariantsEnabled(false);
6541 17 Jan 22 nicklas 200         oncoArray500K.setVcfFileLocator(new DatafileVcfLocator(Datafiletype.VCF, false));
6541 17 Jan 22 nicklas 201         oncoArray500K.open(new File(dbDir, "oncoarray-500k"), null);
6541 17 Jan 22 nicklas 202         indexes.put(oncoArray500K.getId(), oncoArray500K);
6111 29 Jan 21 nicklas 203       }
6111 29 Jan 21 nicklas 204       catch (IOException ex)
6111 29 Jan 21 nicklas 205       {
6111 29 Jan 21 nicklas 206         logger.error("Could not open Lucene index: " + dbDir, ex);
6111 29 Jan 21 nicklas 207       }
6111 29 Jan 21 nicklas 208       
6111 29 Jan 21 nicklas 209       // Start timer for processing async requests
6111 29 Jan 21 nicklas 210       timer = Application.getScheduler().scheduleAtFixedRate(
6111 29 Jan 21 nicklas 211         new IndexUpdateTimerTask(), 5000, 5000, false);
6111 29 Jan 21 nicklas 212     }
6111 29 Jan 21 nicklas 213     catch (RuntimeException ex)
6111 29 Jan 21 nicklas 214     {
6111 29 Jan 21 nicklas 215       logger.debug("Could not start Variant Indexing Service", ex);
6111 29 Jan 21 nicklas 216       stopInternal();
6111 29 Jan 21 nicklas 217       throw ex;
6111 29 Jan 21 nicklas 218     }
6111 29 Jan 21 nicklas 219     
6111 29 Jan 21 nicklas 220     isRunning = true;
6111 29 Jan 21 nicklas 221     logger.debug("Variant Indexing Service is now running");
6111 29 Jan 21 nicklas 222   }
6111 29 Jan 21 nicklas 223   
6111 29 Jan 21 nicklas 224   /**
6111 29 Jan 21 nicklas 225     Stop the service if it is running.
6111 29 Jan 21 nicklas 226   */
6111 29 Jan 21 nicklas 227   synchronized void stop()
6111 29 Jan 21 nicklas 228   {
6111 29 Jan 21 nicklas 229     if (!isRunning) return;
6111 29 Jan 21 nicklas 230     logger.debug("Stopping Variant Indexing Service");
6111 29 Jan 21 nicklas 231     stopInternal();
6111 29 Jan 21 nicklas 232     logger.debug("Variant Indexing Service has stopped");
6111 29 Jan 21 nicklas 233   }
6111 29 Jan 21 nicklas 234   
6111 29 Jan 21 nicklas 235   /**
6111 29 Jan 21 nicklas 236     Restart the service.
6111 29 Jan 21 nicklas 237   */
6111 29 Jan 21 nicklas 238   public synchronized void restart()
6111 29 Jan 21 nicklas 239   {
6111 29 Jan 21 nicklas 240     if (ext != null) Services.restart(ext);
6111 29 Jan 21 nicklas 241   }
6111 29 Jan 21 nicklas 242
6111 29 Jan 21 nicklas 243   
6111 29 Jan 21 nicklas 244   private void stopInternal()
6111 29 Jan 21 nicklas 245   {
6111 29 Jan 21 nicklas 246     if (timer != null)
6111 29 Jan 21 nicklas 247     {
6111 29 Jan 21 nicklas 248       timer.cancel();
6111 29 Jan 21 nicklas 249       timer = null;
6111 29 Jan 21 nicklas 250     }
6241 21 May 21 nicklas 251     for (LuceneIndex idx : indexes.values())
6241 21 May 21 nicklas 252     {
6241 21 May 21 nicklas 253       idx.close();
6241 21 May 21 nicklas 254     }
6241 21 May 21 nicklas 255     indexes.clear();
6111 29 Jan 21 nicklas 256     if (rootSc != null) 
6111 29 Jan 21 nicklas 257     {
6111 29 Jan 21 nicklas 258       rootSc.logout();
6111 29 Jan 21 nicklas 259       rootSc = null;
6111 29 Jan 21 nicklas 260     }
6111 29 Jan 21 nicklas 261     ext = null;
6111 29 Jan 21 nicklas 262     systemSc = null;
6111 29 Jan 21 nicklas 263     isRunning = false;
6111 29 Jan 21 nicklas 264   }
6111 29 Jan 21 nicklas 265
6111 29 Jan 21 nicklas 266   /**
6111 29 Jan 21 nicklas 267     Set a flag forcing the service to perform a check soon after the given number
6111 29 Jan 21 nicklas 268     of seconds. This method is intended to be called by external parties that know
6111 29 Jan 21 nicklas 269     that there is new or modified data to force an index update.
6111 29 Jan 21 nicklas 270   */
6111 29 Jan 21 nicklas 271   public void setForceUpdateCheck(int seconds)
6111 29 Jan 21 nicklas 272   {
6111 29 Jan 21 nicklas 273     this.forceUpdateCheck = System.currentTimeMillis() + seconds * 1000;
6111 29 Jan 21 nicklas 274   }
6111 29 Jan 21 nicklas 275
6111 29 Jan 21 nicklas 276   /**
6111 29 Jan 21 nicklas 277     Perform a check for new or removed data that should be added to or removed
6111 29 Jan 21 nicklas 278     from the index databases.
6111 29 Jan 21 nicklas 279     
6111 29 Jan 21 nicklas 280     Note that this method may return without doing
6111 29 Jan 21 nicklas 281     anything depending on how long time it was since the last check and if
6111 29 Jan 21 nicklas 282     the {@link #setForceCheck()} has been called or not.
6111 29 Jan 21 nicklas 283   */
6111 29 Jan 21 nicklas 284   void autoUpdateIndexes()
6111 29 Jan 21 nicklas 285   {
6111 29 Jan 21 nicklas 286     long now = System.currentTimeMillis();
6111 29 Jan 21 nicklas 287     long timeSinceLastCheck = now - lastAutoUpdateCheck;
7074 24 Mar 23 nicklas 288     long minWaitInterval = logger.isDebugEnabled() ? MIN_WAIT_INTERVAL_DEBUG : MIN_WAIT_INTERVAL_NORMAL;
6111 29 Jan 21 nicklas 289   
6111 29 Jan 21 nicklas 290     // If we have not waited long enough and there there is no recent request we don't have to check
7074 24 Mar 23 nicklas 291     if (timeSinceLastCheck < minWaitInterval && (forceUpdateCheck == 0 || forceUpdateCheck > now))
6111 29 Jan 21 nicklas 292     {
6111 29 Jan 21 nicklas 293       logger.trace("No auto-update check since no recent request and not long enough wait time [" + (timeSinceLastCheck / 1000) + "]");
6111 29 Jan 21 nicklas 294       return;
6111 29 Jan 21 nicklas 295     }
6111 29 Jan 21 nicklas 296   
6111 29 Jan 21 nicklas 297     forceUpdateCheck = 0;
6111 29 Jan 21 nicklas 298     lastAutoUpdateCheck = now;
6111 29 Jan 21 nicklas 299     logger.debug("Time for auto-update check [" + (timeSinceLastCheck / 1000) + "]");
6111 29 Jan 21 nicklas 300     
6111 29 Jan 21 nicklas 301     try
6111 29 Jan 21 nicklas 302     {
6167 09 Mar 21 nicklas 303       int forceAnotherCheck = 0;
6111 29 Jan 21 nicklas 304       
6140 19 Feb 21 nicklas 305       for (LuceneIndex idx : indexes.values())
6111 29 Jan 21 nicklas 306       {
6167 09 Mar 21 nicklas 307         AutoUpdate autoUpdate = idx.getNextAutoUpdateAction();
6168 12 Mar 21 nicklas 308         Status status = idx.getWorkingStatus();
6556 28 Jan 22 nicklas 309         String customAction = idx.getCustomUpdateAction();
6168 12 Mar 21 nicklas 310         logger.debug("Status ("+idx.getName()+"): " + status);
6167 09 Mar 21 nicklas 311         logger.debug("Auto-update action ("+idx.getName()+"): " + autoUpdate);
6556 28 Jan 22 nicklas 312         logger.debug("Custom action ("+idx.getName()+"): " + customAction);
6168 12 Mar 21 nicklas 313         if (autoUpdate == AutoUpdate.DISABLED || status != Status.IDLE) continue;
6167 09 Mar 21 nicklas 314         
6140 19 Feb 21 nicklas 315         DbControl dc = null;
6140 19 Feb 21 nicklas 316         try
6140 19 Feb 21 nicklas 317         {
6556 28 Jan 22 nicklas 318           idx.setError(null);
6604 23 Feb 22 nicklas 319           dc = rootSc.newDbControl("Variant search: auto-update="+(customAction != null ? customAction : autoUpdate.name()));
6140 19 Feb 21 nicklas 320           
6167 09 Mar 21 nicklas 321           if (autoUpdate == AutoUpdate.REMOVE_NON_EXISTING)
6140 19 Feb 21 nicklas 322           {
6167 09 Mar 21 nicklas 323             Set<Integer> nonExisting = idx.getNonExistingRawBioAssays(dc);
6167 09 Mar 21 nicklas 324             idx.removeFromIndex(dc, nonExisting, null);
6544 19 Jan 22 nicklas 325             idx.setNextAutoUpdateAction(AutoUpdate.DEFAULT, null);
6241 21 May 21 nicklas 326             idx.releaseCloseWait();
6140 19 Feb 21 nicklas 327           }
6167 09 Mar 21 nicklas 328           else if (autoUpdate == AutoUpdate.FULL_REBUILD)
6167 09 Mar 21 nicklas 329           {
6168 12 Mar 21 nicklas 330             Thread t = new Thread(new FullRebuildRunnable(idx), "VarSearch-Rebuild-"+idx.getId());
6168 12 Mar 21 nicklas 331             t.start();
6167 09 Mar 21 nicklas 332           }
6169 15 Mar 21 nicklas 333           else if (autoUpdate == AutoUpdate.DELETE)
6169 15 Mar 21 nicklas 334           {
6169 15 Mar 21 nicklas 335             idx.deleteIndex();
6544 19 Jan 22 nicklas 336             idx.setNextAutoUpdateAction(AutoUpdate.DEFAULT, null);
6241 21 May 21 nicklas 337             idx.releaseCloseWait();
6169 15 Mar 21 nicklas 338           }
6544 19 Jan 22 nicklas 339           else if (autoUpdate == AutoUpdate.CUSTOM)
6167 09 Mar 21 nicklas 340           {
6556 28 Jan 22 nicklas 341             idx.doCustomAction(customAction);
6544 19 Jan 22 nicklas 342             idx.setNextAutoUpdateAction(AutoUpdate.DEFAULT, null);
6544 19 Jan 22 nicklas 343             idx.releaseCloseWait();
6544 19 Jan 22 nicklas 344           }
6544 19 Jan 22 nicklas 345           else // AutoUpdate.DEFAULT || AutoUpdate.ADD_TO_INDEX
6544 19 Jan 22 nicklas 346           {
6140 19 Feb 21 nicklas 347           
6167 09 Mar 21 nicklas 348             ItemList rbaToIndex = idx.getItemList().get(dc);
6167 09 Mar 21 nicklas 349             if (rbaToIndex == null)
6140 19 Feb 21 nicklas 350             {
6167 09 Mar 21 nicklas 351               logger.warn("Could not find the '" + idx.getItemList().getName() + "' item list");
6140 19 Feb 21 nicklas 352               continue;
6140 19 Feb 21 nicklas 353             }
6167 09 Mar 21 nicklas 354             
6167 09 Mar 21 nicklas 355             int numItems = rbaToIndex.getSize();
6167 09 Mar 21 nicklas 356             if (autoUpdate == AutoUpdate.DEFAULT)
6167 09 Mar 21 nicklas 357             {
6167 09 Mar 21 nicklas 358               // Check "AutoProcessing" etc,
6167 09 Mar 21 nicklas 359               boolean disabled = "Disable".equals(Annotationtype.AUTO_PROCESSING.getAnnotationValue(dc, rbaToIndex));
6167 09 Mar 21 nicklas 360               logger.debug("Number of items to index ("+idx.getName()+"): " + numItems);
6167 09 Mar 21 nicklas 361               logger.debug("AutoProcessing is "+ (disabled ? "disabled" : "enabled")+" for " + idx.getName());
6167 09 Mar 21 nicklas 362               if (disabled || numItems == 0) continue;
6167 09 Mar 21 nicklas 363               
6167 09 Mar 21 nicklas 364               if (numItems < EXTENDED_WAIT_LIMIT)
6167 09 Mar 21 nicklas 365               {
6167 09 Mar 21 nicklas 366                 // Check if we should wait some more
7074 24 Mar 23 nicklas 367                 long extendedWaitUntil = idx.getExtendedWaitUntil(logger.isDebugEnabled() ? MAX_EXTENDED_WAIT_DEBUG : MAX_EXTENDED_WAIT_NORMAL);
6167 09 Mar 21 nicklas 368                 if (now < extendedWaitUntil)
6167 09 Mar 21 nicklas 369                 {
6167 09 Mar 21 nicklas 370                   logger.debug("Waiting for more more rawbioassays: " + ((extendedWaitUntil-now)/1000) + " seconds");
6167 09 Mar 21 nicklas 371                   continue;
6167 09 Mar 21 nicklas 372                 }
6167 09 Mar 21 nicklas 373               }
6167 09 Mar 21 nicklas 374             }
6167 09 Mar 21 nicklas 375           
6167 09 Mar 21 nicklas 376             int maxToIndex = idx.getMaxToIndex();
6167 09 Mar 21 nicklas 377             if (maxToIndex < numItems)
6167 09 Mar 21 nicklas 378             {
6167 09 Mar 21 nicklas 379               // Do not leave just a few items remaining
6241 21 May 21 nicklas 380               if (numItems-maxToIndex <= 2*EXTENDED_WAIT_LIMIT) maxToIndex = numItems;
6167 09 Mar 21 nicklas 381             }
6167 09 Mar 21 nicklas 382             
6167 09 Mar 21 nicklas 383             ItemQuery<RawBioAssay> rawQuery = rbaToIndex.getMembers();
6167 09 Mar 21 nicklas 384             rawQuery.setIncludes(Include.ALL);
6167 09 Mar 21 nicklas 385             rawQuery.setMaxResults(maxToIndex);
6167 09 Mar 21 nicklas 386             List<RawBioAssay> rba = rawQuery.list(dc);
6167 09 Mar 21 nicklas 387             
6167 09 Mar 21 nicklas 388             logger.debug("Indexing " + idx.getName());
6241 21 May 21 nicklas 389             List<RawBioAssay> indexed = idx.addToIndex(dc, rba, null);
6241 21 May 21 nicklas 390             if (indexed != null)
6241 21 May 21 nicklas 391             {
6241 21 May 21 nicklas 392               rbaToIndex.removeItems(indexed.iterator());
6241 21 May 21 nicklas 393             }
6167 09 Mar 21 nicklas 394             dc.commit();
6241 21 May 21 nicklas 395             idx.releaseCloseWait();
6241 21 May 21 nicklas 396
6167 09 Mar 21 nicklas 397             if (rbaToIndex.getSize() == 0)
6167 09 Mar 21 nicklas 398             {
6167 09 Mar 21 nicklas 399               // The list has been processed, revert to DEFAULT action
6544 19 Jan 22 nicklas 400               idx.setNextAutoUpdateAction(AutoUpdate.DEFAULT, null);
6167 09 Mar 21 nicklas 401             }
6167 09 Mar 21 nicklas 402             
6167 09 Mar 21 nicklas 403             if (rbaToIndex.getSize() > EXTENDED_WAIT_LIMIT)
6167 09 Mar 21 nicklas 404             {
6167 09 Mar 21 nicklas 405               // Force an update if there are more items to index
6167 09 Mar 21 nicklas 406               logger.debug("Scheduling new check in 5 seconds since there are " + rbaToIndex.getSize() + " more items to index");
6167 09 Mar 21 nicklas 407               forceAnotherCheck = 5;
6167 09 Mar 21 nicklas 408             }    
6140 19 Feb 21 nicklas 409           }
6140 19 Feb 21 nicklas 410         }
6140 19 Feb 21 nicklas 411         catch (Exception ex)
6140 19 Feb 21 nicklas 412         {
6556 28 Jan 22 nicklas 413           idx.setError(ex);
6140 19 Feb 21 nicklas 414           logger.error("Indexing failed ("+idx.getName()+")", ex);
6140 19 Feb 21 nicklas 415         }
6140 19 Feb 21 nicklas 416         finally
6140 19 Feb 21 nicklas 417         {
6605 23 Feb 22 nicklas 418           idx.autoSetQueryStatus();
6140 19 Feb 21 nicklas 419           if (dc != null) dc.close();
6140 19 Feb 21 nicklas 420         }
6111 29 Jan 21 nicklas 421       }
6111 29 Jan 21 nicklas 422       
6167 09 Mar 21 nicklas 423       if (forceAnotherCheck > 0) setForceUpdateCheck(forceAnotherCheck);
6111 29 Jan 21 nicklas 424     }
6112 02 Feb 21 nicklas 425     catch (Exception ex)
6112 02 Feb 21 nicklas 426     {
6112 02 Feb 21 nicklas 427       logger.error("Indexing failed", ex);
6112 02 Feb 21 nicklas 428     }
6111 29 Jan 21 nicklas 429     finally
6111 29 Jan 21 nicklas 430     {
6111 29 Jan 21 nicklas 431       lastAutoUpdateCheck = System.currentTimeMillis();
6111 29 Jan 21 nicklas 432     }
6111 29 Jan 21 nicklas 433   }
6111 29 Jan 21 nicklas 434
6111 29 Jan 21 nicklas 435   
6111 29 Jan 21 nicklas 436   /**
6111 29 Jan 21 nicklas 437     Timer for updating indexes.
6111 29 Jan 21 nicklas 438   */
6111 29 Jan 21 nicklas 439   static class IndexUpdateTimerTask
6111 29 Jan 21 nicklas 440     extends TimerTask
6111 29 Jan 21 nicklas 441   {
6111 29 Jan 21 nicklas 442     
6111 29 Jan 21 nicklas 443     public IndexUpdateTimerTask() 
6111 29 Jan 21 nicklas 444     {}
6111 29 Jan 21 nicklas 445     
6111 29 Jan 21 nicklas 446     @Override
6111 29 Jan 21 nicklas 447     public void run()
6111 29 Jan 21 nicklas 448     {
6111 29 Jan 21 nicklas 449       try
6111 29 Jan 21 nicklas 450       {
6111 29 Jan 21 nicklas 451         getInstance().autoUpdateIndexes();
6111 29 Jan 21 nicklas 452       }
6111 29 Jan 21 nicklas 453       catch (Exception ex)
6111 29 Jan 21 nicklas 454       {
6111 29 Jan 21 nicklas 455         logger.error("Exception when performing auto-confirm check", ex);
6111 29 Jan 21 nicklas 456       }
6111 29 Jan 21 nicklas 457     }
6111 29 Jan 21 nicklas 458   
6111 29 Jan 21 nicklas 459   }
6111 29 Jan 21 nicklas 460
6111 29 Jan 21 nicklas 461 }