You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2011/09/12 17:37:19 UTC

svn commit: r1169801 - in /jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core: JackrabbitThreadPool.java RepositoryContext.java RepositoryImpl.java SearchManager.java query/QueryHandlerContext.java query/lucene/MultiIndex.java

Author: jukka
Date: Mon Sep 12 15:37:19 2011
New Revision: 1169801

URL: http://svn.apache.org/viewvc?rev=1169801&view=rev
Log:
JCR-3066: Use only one scheduler for repository tasks

Added:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/JackrabbitThreadPool.java
Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryContext.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SearchManager.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryHandlerContext.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/JackrabbitThreadPool.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/JackrabbitThreadPool.java?rev=1169801&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/JackrabbitThreadPool.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/JackrabbitThreadPool.java Mon Sep 12 15:37:19 2011
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core;
+
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Thread pool used by the repository.
+ */
+class JackrabbitThreadPool extends ScheduledThreadPoolExecutor {
+
+    /**
+     * Size of the per-repository thread pool.
+     */
+    private static final int size =
+            Runtime.getRuntime().availableProcessors() * 2;
+
+    /**
+     * The classloader used as the context classloader of threads in the pool.
+     */
+    private static final ClassLoader loader =
+            JackrabbitThreadPool.class.getClassLoader();
+
+    /**
+     * Thread counter for generating unique names for the threads in the pool.
+     */
+    private static final AtomicInteger counter = new AtomicInteger(1);
+
+    /**
+     * Thread factory for creating the threads in the pool
+     */
+    private static final ThreadFactory factory = new ThreadFactory() {
+        public Thread newThread(Runnable runnable) {
+            int count = counter.getAndIncrement();
+            String name = "jackrabbit-pool-" + count;
+            Thread thread = new Thread(runnable, name);
+            thread.setDaemon(true);
+            if (thread.getPriority() != Thread.NORM_PRIORITY) {
+                thread.setPriority(Thread.NORM_PRIORITY);
+            }
+            thread.setContextClassLoader(loader);
+            return thread;
+        }
+    };
+
+    /**
+     * Handler for tasks for which no free thread is found within the pool.
+     */
+    private static final RejectedExecutionHandler handler =
+            new ThreadPoolExecutor.CallerRunsPolicy();
+
+    /**
+     * Creates a new thread pool.
+     */
+    public JackrabbitThreadPool() {
+        super(size, factory, handler);
+    }
+
+}

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryContext.java?rev=1169801&r1=1169800&r2=1169801&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryContext.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryContext.java Mon Sep 12 15:37:19 2011
@@ -16,6 +16,8 @@
  */
 package org.apache.jackrabbit.core;
 
+import java.util.concurrent.ScheduledExecutorService;
+
 import org.apache.jackrabbit.core.cluster.ClusterNode;
 import org.apache.jackrabbit.core.data.DataStore;
 import org.apache.jackrabbit.core.fs.FileSystem;
@@ -26,7 +28,6 @@ import org.apache.jackrabbit.core.securi
 import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry;
 import org.apache.jackrabbit.core.state.ItemStateCacheFactory;
 import org.apache.jackrabbit.core.version.InternalVersionManagerImpl;
-import org.apache.jackrabbit.util.Timer;
 
 /**
  * Internal component context of a Jackrabbit content repository.
@@ -100,9 +101,10 @@ public class RepositoryContext {
     private NodeIdFactory nodeIdFactory;
 
     /**
-     * Repository-wide timer instance.
+     * Thread pool of this repository.
      */
-    private final Timer timer = new Timer(false);
+    private final ScheduledExecutorService executor =
+            new JackrabbitThreadPool();
 
     /**
      * Creates a component context for the given repository.
@@ -124,12 +126,12 @@ public class RepositoryContext {
     }
 
     /**
-     * Returns the repository-wide timer instance.
+     * Returns the thread pool of this repository.
      *
-     * @return repository timer
+     * @return repository thread pool
      */
-    public Timer getTimer() {
-        return timer;
+    public ScheduledExecutorService getExecutor() {
+        return executor;
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java?rev=1169801&r1=1169800&r2=1169801&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java Mon Sep 12 15:37:19 2011
@@ -32,11 +32,7 @@ import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
 import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
 
 import javax.jcr.AccessDeniedException;
 import javax.jcr.Credentials;
@@ -237,11 +233,6 @@ public class RepositoryImpl extends Abst
     private WorkspaceEventChannel createWorkspaceEventChannel;
 
     /**
-     * Scheduled executor service.
-     */
-    protected final ScheduledExecutorService executor;
-
-    /**
      * Protected constructor.
      *
      * @param repConfig the repository configuration.
@@ -250,32 +241,6 @@ public class RepositoryImpl extends Abst
      *                             or another error occurs.
      */
     protected RepositoryImpl(RepositoryConfig repConfig) throws RepositoryException {
-        // we should use the jackrabbit classloader for all background threads
-        // from the pool
-        final ClassLoader poolClassLoader = this.getClass().getClassLoader();
-        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(
-                Runtime.getRuntime().availableProcessors() * 2,
-                new ThreadFactory() {
-
-                    final AtomicInteger threadNumber = new AtomicInteger(1);
-
-                    /**
-                     * @see java.util.concurrent.ThreadFactory#newThread(java.lang.Runnable)
-                     */
-                    public Thread newThread(Runnable r) {
-                        final Thread t = new Thread(null, r,
-                                              "jackrabbit-pool-" + threadNumber.getAndIncrement(),
-                                              0);
-                        t.setDaemon(true);
-                        if (t.getPriority() != Thread.NORM_PRIORITY)
-                            t.setPriority(Thread.NORM_PRIORITY);
-                        t.setContextClassLoader(poolClassLoader);
-                        return t;
-                    }
-                },
-                new ThreadPoolExecutor.CallerRunsPolicy());
-        this.executor = executor;
-
         // Acquire a lock on the repository home
         repLock = repConfig.getRepositoryLockMechanism();
         repLock.init(repConfig.getHomeDir());
@@ -644,8 +609,7 @@ public class RepositoryImpl extends Abst
                         repConfig,
                         getWorkspaceInfo(wspName).itemStateMgr,
                         context.getInternalVersionManager().getPersistenceManager(),
-                        SYSTEM_ROOT_NODE_ID,
-                        null, null, executor);
+                        SYSTEM_ROOT_NODE_ID, null, null);
 
                 SystemSession defSysSession = getSystemSession(wspName);
                 ObservationManager obsMgr = defSysSession.getWorkspace().getObservationManager();
@@ -1168,6 +1132,7 @@ public class RepositoryImpl extends Abst
         notifyAll();
 
         // Shut down the executor service
+        ScheduledExecutorService executor = context.getExecutor();
         executor.shutdown();
         try {
             // Wait for all remaining background threads to terminate
@@ -1190,8 +1155,6 @@ public class RepositoryImpl extends Abst
             }
         }
 
-        context.getTimer().cancel();
-
         log.info("Repository has been shutdown");
     }
 
@@ -1892,7 +1855,7 @@ public class RepositoryImpl extends Abst
                             itemStateMgr, persistMgr,
                             context.getRootNodeId(),
                             getSystemSearchManager(getName()),
-                            SYSTEM_ROOT_NODE_ID, executor);
+                            SYSTEM_ROOT_NODE_ID);
                 }
                 return searchMgr;
             }
@@ -1932,7 +1895,8 @@ public class RepositoryImpl extends Abst
          * @return the lock manager
          */
         protected LockManagerImpl createLockManager() throws RepositoryException {
-            return new LockManagerImpl(getSystemSession(), fs, executor);
+            return new LockManagerImpl(
+                    getSystemSession(), fs, context.getExecutor());
         }
 
         /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SearchManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SearchManager.java?rev=1169801&r1=1169800&r2=1169801&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SearchManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SearchManager.java Mon Sep 12 15:37:19 2011
@@ -130,12 +130,11 @@ public class SearchManager implements Sy
     public SearchManager(
             RepositoryContext repositoryContext,
             QueryHandlerFactory qhf,
-                         SharedItemStateManager itemMgr,
-                         PersistenceManager pm,
-                         NodeId rootNodeId,
-                         SearchManager parentMgr,
-                         NodeId excludedNodeId,
-                         Executor executor) throws RepositoryException {
+            SharedItemStateManager itemMgr,
+            PersistenceManager pm,
+            NodeId rootNodeId,
+            SearchManager parentMgr,
+            NodeId excludedNodeId) throws RepositoryException {
         this.nsReg = repositoryContext.getNamespaceRegistry();
         this.itemMgr = itemMgr;
         this.parentHandler = (parentMgr != null) ? parentMgr.handler : null;
@@ -174,7 +173,7 @@ public class SearchManager implements Sy
         this.handler = qhf.getQueryHandler(new QueryHandlerContext(
                 repositoryContext,
                 itemMgr, pm, rootNodeId,
-                parentHandler, excludedNodeId, executor));
+                parentHandler, excludedNodeId));
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryHandlerContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryHandlerContext.java?rev=1169801&r1=1169800&r2=1169801&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryHandlerContext.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryHandlerContext.java Mon Sep 12 15:37:19 2011
@@ -16,7 +16,7 @@
  */
 package org.apache.jackrabbit.core.query;
 
-import java.util.concurrent.Executor;
+import java.util.concurrent.ScheduledExecutorService;
 
 import org.apache.jackrabbit.core.CachingHierarchyManager;
 import org.apache.jackrabbit.core.HierarchyManager;
@@ -27,7 +27,6 @@ import org.apache.jackrabbit.core.nodety
 import org.apache.jackrabbit.core.persistence.PersistenceManager;
 import org.apache.jackrabbit.core.state.ItemStateManager;
 import org.apache.jackrabbit.core.state.SharedItemStateManager;
-import org.apache.jackrabbit.util.Timer;
 
 /**
  * Acts as an argument for the {@link QueryHandler} to keep the interface
@@ -77,11 +76,6 @@ public class QueryHandlerContext {
     private final NodeId excludedNodeId;
 
     /**
-     * Background task executor.
-     */
-    private final Executor executor;
-
-    /**
      * Creates a new context instance.
      *
      * @param stateMgr         provides persistent item states.
@@ -92,7 +86,6 @@ public class QueryHandlerContext {
      * @param excludedNodeId   id of the node that should be excluded from
      *                         indexing. Any descendant of that node is also
      *                         excluded from indexing.
-     * @param executor         background task executor
      */
     public QueryHandlerContext(
             RepositoryContext repositoryContext,
@@ -100,8 +93,7 @@ public class QueryHandlerContext {
             PersistenceManager pm,
             NodeId rootId,
             QueryHandler parentHandler,
-            NodeId excludedNodeId,
-            Executor executor) {
+            NodeId excludedNodeId) {
         this.repositoryContext = repositoryContext;
         this.stateMgr = stateMgr;
         this.hmgr = new CachingHierarchyManager(rootId, stateMgr);
@@ -112,7 +104,6 @@ public class QueryHandlerContext {
         propRegistry = new PropertyTypeRegistry(ntRegistry);
         this.parentHandler = parentHandler;
         this.excludedNodeId = excludedNodeId;
-        this.executor =  executor;
         ntRegistry.addListener(propRegistry);
     }
 
@@ -206,17 +197,8 @@ public class QueryHandlerContext {
      *
      * @return background task executor
      */
-    public Executor getExecutor() {
-        return executor;
-    }
-
-    /**
-     * Returns the repository timer.
-     *
-     * @return repository timer
-     */
-    public Timer getTimer() {
-        return repositoryContext.getTimer();
+    public ScheduledExecutorService getExecutor() {
+        return repositoryContext.getExecutor();
     }
 
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java?rev=1169801&r1=1169800&r2=1169801&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java Mon Sep 12 15:37:19 2011
@@ -29,6 +29,9 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
 
 import javax.jcr.RepositoryException;
 
@@ -44,7 +47,6 @@ import org.apache.jackrabbit.spi.PathFac
 import org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver;
 import org.apache.jackrabbit.spi.commons.conversion.PathResolver;
 import org.apache.jackrabbit.spi.commons.name.PathFactoryImpl;
-import org.apache.jackrabbit.util.Timer;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.Term;
@@ -175,7 +177,7 @@ public class MultiIndex {
     /**
      * The time this index was last flushed or a transaction was committed.
      */
-    private long lastFlushTime;
+    private long lastFlushTime = 0;
 
     /**
      * The <code>IndexMerger</code> for this <code>MultiIndex</code>.
@@ -186,7 +188,7 @@ public class MultiIndex {
      * Task that is periodically called by the repository timer for checking
      * if index should be flushed.
      */
-    private final Timer.Task flushTask;
+    private ScheduledFuture<?> flushTask = null;
 
     /**
      * The RedoLog of this <code>MultiIndex</code>.
@@ -329,15 +331,6 @@ public class MultiIndex {
             flush();
         }
 
-        flushTask = new Timer.Task() {
-            public void run() {
-                // check if there are any indexing jobs finished
-                checkIndexingQueue(false);
-                // check if volatile index should be flushed
-                checkFlush();
-            }
-        };
-
         if (indexNames.size() > 0) {
             scheduleFlushTask();
         }
@@ -798,7 +791,7 @@ public class MultiIndex {
 
         synchronized (this) {
             // stop timer
-            flushTask.cancel();
+            unscheduleFlushTask();
 
             // commit / close indexes
             try {
@@ -1074,9 +1067,29 @@ public class MultiIndex {
         indexHistory.pruneOutdated();
     }
 
+    /**
+     * Schedules a background task for flushing the index once per second.
+     */
     private void scheduleFlushTask() {
-        lastFlushTime = System.currentTimeMillis();
-        handler.getContext().getTimer().schedule(flushTask, 0, 1000);
+        ScheduledExecutorService executor = handler.getContext().getExecutor();
+        flushTask = executor.scheduleWithFixedDelay(new Runnable() {
+            public void run() {
+                // check if there are any indexing jobs finished
+                checkIndexingQueue(false);
+                // check if volatile index should be flushed
+                checkFlush();
+            }
+        }, 1, 1, TimeUnit.SECONDS);
+    }
+
+    /**
+     * Cancels the scheduled background index flush task.
+     */
+    private void unscheduleFlushTask() {
+        if (flushTask != null) {
+            flushTask.cancel(false);
+            flushTask = null;
+        }
     }
 
     /**