Permalink
Browse files

Cleanup: renamed and documented purpose of ConstrainedExecutor

Signed-off-by: Igor Fedorenko <igor@ifedorenko.com>
  • Loading branch information...
1 parent d95e4be commit 949748592c80549e1c9255ba79af9d09abf00338 @ifedorenko ifedorenko committed Apr 1, 2013
Showing with 58 additions and 31 deletions.
  1. +1 −1 ...ore/src/main/java/org/sonatype/nexus/proxy/maven/routing/internal/LocalContentDiscovererImpl.java
  2. +23 −4 nexus-core/src/main/java/org/sonatype/nexus/proxy/maven/routing/internal/ManagerImpl.java
  3. +2 −2 ...-core/src/main/java/org/sonatype/nexus/proxy/maven/routing/internal/UpdateRepositoryRunnable.java
  4. +1 −1 ...ava/org/sonatype/nexus/proxy/maven/routing/internal/scrape/AbstractGeneratedIndexPageScraper.java
  5. +1 −1 ...re/src/main/java/org/sonatype/nexus/proxy/maven/routing/internal/scrape/AmazonS3IndexScraper.java
  6. +1 −1 ...-core/src/main/java/org/sonatype/nexus/{util → proxy/maven/routing/internal}/task/Cancelable.java
  7. +1 −1 ...c/main/java/org/sonatype/nexus/{util → proxy/maven/routing/internal}/task/CancelableRunnable.java
  8. +1 −1 ...java/org/sonatype/nexus/{util → proxy/maven/routing/internal}/task/CancelableRunnableSupport.java
  9. +1 −1 ...rc/main/java/org/sonatype/nexus/{util → proxy/maven/routing/internal}/task/CancelableSupport.java
  10. +1 −1 ...e/src/main/java/org/sonatype/nexus/{util → proxy/maven/routing/internal}/task/CancelableUtil.java
  11. +1 −1 ...n/java/org/sonatype/nexus/{util → proxy/maven/routing/internal}/task/LoggingProgressListener.java
  12. +1 −1 ...src/main/java/org/sonatype/nexus/{util → proxy/maven/routing/internal}/task/ProgressListener.java
  13. +1 −1 ...main/java/org/sonatype/nexus/{util → proxy/maven/routing/internal}/task/ProgressListenerUtil.java
  14. +1 −1 ...n/java/org/sonatype/nexus/{util → proxy/maven/routing/internal}/task/ProgressListenerWrapper.java
  15. +1 −1 ...java/org/sonatype/nexus/{util → proxy/maven/routing/internal}/task/RunnableCanceledException.java
  16. +1 −1 ...a/org/sonatype/nexus/{util → proxy/maven/routing/internal}/task/RunnableInterruptedException.java
  17. +1 −1 .../src/main/java/org/sonatype/nexus/{util → proxy/maven/routing/internal}/task/RunnableSupport.java
  18. +7 −2 ...a/org/sonatype/nexus/{util → proxy/maven/routing/internal}/task/executor/ConstrainedExecutor.java
  19. +4 −3 ...g/sonatype/nexus/{util → proxy/maven/routing/internal}/task/executor/ConstrainedExecutorImpl.java
  20. +2 −2 .../main/java/org/sonatype/nexus/{util → proxy/maven/routing/internal}/task/executor/Statistics.java
  21. +5 −3 ...e/nexus/{util/task/executor → proxy/maven/routing/internal/task}/ConstrainedExecutorImplTest.java
@@ -30,14 +30,14 @@
import org.sonatype.nexus.proxy.maven.routing.Config;
import org.sonatype.nexus.proxy.maven.routing.discovery.DiscoveryResult;
import org.sonatype.nexus.proxy.maven.routing.discovery.LocalContentDiscoverer;
+import org.sonatype.nexus.proxy.maven.routing.internal.task.CancelableUtil;
import org.sonatype.nexus.proxy.walker.AbstractWalkerProcessor;
import org.sonatype.nexus.proxy.walker.DefaultStoreWalkerFilter;
import org.sonatype.nexus.proxy.walker.DefaultWalkerContext;
import org.sonatype.nexus.proxy.walker.ParentOMatic;
import org.sonatype.nexus.proxy.walker.Walker;
import org.sonatype.nexus.proxy.walker.WalkerContext;
import org.sonatype.nexus.proxy.walker.WalkerException;
-import org.sonatype.nexus.util.task.CancelableUtil;
/**
* Default {@link LocalContentDiscoverer} implementation.
@@ -60,6 +60,10 @@
import org.sonatype.nexus.proxy.maven.routing.discovery.RemoteStrategy;
import org.sonatype.nexus.proxy.maven.routing.events.PrefixFilePublishedRepositoryEvent;
import org.sonatype.nexus.proxy.maven.routing.events.PrefixFileUnpublishedRepositoryEvent;
+import org.sonatype.nexus.proxy.maven.routing.internal.task.LoggingProgressListener;
+import org.sonatype.nexus.proxy.maven.routing.internal.task.executor.ConstrainedExecutor;
+import org.sonatype.nexus.proxy.maven.routing.internal.task.executor.ConstrainedExecutorImpl;
+import org.sonatype.nexus.proxy.maven.routing.internal.task.executor.Statistics;
import org.sonatype.nexus.proxy.registry.RepositoryRegistry;
import org.sonatype.nexus.proxy.repository.GroupRepository;
import org.sonatype.nexus.proxy.repository.LocalStatus;
@@ -68,10 +72,6 @@
import org.sonatype.nexus.proxy.repository.ShadowRepository;
import org.sonatype.nexus.proxy.utils.RepositoryStringUtils;
import org.sonatype.nexus.threads.NexusThreadFactory;
-import org.sonatype.nexus.util.task.LoggingProgressListener;
-import org.sonatype.nexus.util.task.executor.ConstrainedExecutor;
-import org.sonatype.nexus.util.task.executor.ConstrainedExecutorImpl;
-import org.sonatype.nexus.util.task.executor.Statistics;
import org.sonatype.sisu.goodies.eventbus.EventBus;
import com.google.common.annotations.VisibleForTesting;
@@ -81,6 +81,25 @@
/**
* Default implementation.
+ * <p>
+ * Notes on synchronization. As of 2.4,
+ * <ul>
+ * <li>periodic autorouting metadata updates are performed without holding any locks on path prefix file (i.e.
+ * .meta/prefixes.txt). Instead, ConstrainedExecutor is used to avoid multiple concurrent execution of periodic
+ * autorouting metadata updates. If new periodic update is requested while the previous one is already running, which is
+ * theoretically possible if update takes longer than update check period (1 hour as of 2.4), ConstrainedExecutor will
+ * prevent second concurrent execution.</li>
+ * <li>during period update existing metadata, if any, is kept available throughout update and is changed as one
+ * relatively short prefix file update performed while holding write, i.e. exclusive, lock on the prefix file.</li>
+ * <li>contents of the prefix file is cached in memory on first request and the cache is refreshed on each change to the
+ * prefix file. reading of the prefix file into the memory cache is performed while holding read, i.e. shared, lock,
+ * which is necessary to prevent reading prefix file partially written by concurrently running prefix file update.</li>
+ * <li>during repository deploy/delete operations, prefix file contents is first read while holding read lock, then, if
+ * the operation results in changes to the prefix file, the prefix file is read-updated-written while holding write
+ * long. This allows concurrent execution of multiple repository deploy/delete operations that do not require changes to
+ * the contents of the prefix file.</li>
+ * </ul>
+ * </p>
*
* @author cstamas
* @since 2.4
@@ -18,8 +18,8 @@
import org.sonatype.nexus.ApplicationStatusSource;
import org.sonatype.nexus.proxy.maven.MavenRepository;
-import org.sonatype.nexus.util.task.CancelableRunnableSupport;
-import org.sonatype.nexus.util.task.ProgressListener;
+import org.sonatype.nexus.proxy.maven.routing.internal.task.CancelableRunnableSupport;
+import org.sonatype.nexus.proxy.maven.routing.internal.task.ProgressListener;
import com.google.common.base.Throwables;
@@ -18,11 +18,11 @@
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.sonatype.nexus.proxy.maven.routing.internal.scrape.Page.UnexpectedPageResponse;
+import org.sonatype.nexus.proxy.maven.routing.internal.task.CancelableUtil;
import org.sonatype.nexus.proxy.walker.ParentOMatic;
import org.sonatype.nexus.proxy.walker.ParentOMatic.Payload;
import org.sonatype.nexus.util.Node;
import org.sonatype.nexus.util.SystemPropertiesHelper;
-import org.sonatype.nexus.util.task.CancelableUtil;
import com.google.common.base.Throwables;
@@ -23,8 +23,8 @@
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
+import org.sonatype.nexus.proxy.maven.routing.internal.task.CancelableUtil;
import org.sonatype.nexus.util.PathUtils;
-import org.sonatype.nexus.util.task.CancelableUtil;
/**
* Scraper for remote AmazonS3 hosted repositories.
@@ -10,7 +10,7 @@
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
-package org.sonatype.nexus.util.task;
+package org.sonatype.nexus.proxy.maven.routing.internal.task;
/**
* Cancelable interface.
@@ -10,7 +10,7 @@
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
-package org.sonatype.nexus.util.task;
+package org.sonatype.nexus.proxy.maven.routing.internal.task;
/**
* A {@link Runnable} that is {@link Cancelable}.
@@ -10,7 +10,7 @@
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
-package org.sonatype.nexus.util.task;
+package org.sonatype.nexus.proxy.maven.routing.internal.task;
/**
* Support class for {@link Cancelable} implementations of {@link Runnable} interfaces. Extends {@link RunnableSupport}
@@ -10,7 +10,7 @@
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
-package org.sonatype.nexus.util.task;
+package org.sonatype.nexus.proxy.maven.routing.internal.task;
/**
* Helper class for {@link Cancelable}.
@@ -10,7 +10,7 @@
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
-package org.sonatype.nexus.util.task;
+package org.sonatype.nexus.proxy.maven.routing.internal.task;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -10,7 +10,7 @@
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
-package org.sonatype.nexus.util.task;
+package org.sonatype.nexus.proxy.maven.routing.internal.task;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -10,7 +10,7 @@
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
-package org.sonatype.nexus.util.task;
+package org.sonatype.nexus.proxy.maven.routing.internal.task;
/**
* Progress listener for tasks. Actual behavior is left to implementors. One possible behavior is to work like a
@@ -10,7 +10,7 @@
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
-package org.sonatype.nexus.util.task;
+package org.sonatype.nexus.proxy.maven.routing.internal.task;
/**
* Collection of static methods allowing to use {@link ProgressListener} and use it in less intrusive way than passing
@@ -10,7 +10,7 @@
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
-package org.sonatype.nexus.util.task;
+package org.sonatype.nexus.proxy.maven.routing.internal.task;
/**
* {@link ProgressListener} implementation that wraps another {@link ProgressListener} within. The wrapped
@@ -10,7 +10,7 @@
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
-package org.sonatype.nexus.util.task;
+package org.sonatype.nexus.proxy.maven.routing.internal.task;
/**
* Runtime exception thrown in cases when runnable task is canceled. Semantical meaning is almost same as Java's
@@ -10,7 +10,7 @@
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
-package org.sonatype.nexus.util.task;
+package org.sonatype.nexus.proxy.maven.routing.internal.task;
/**
* Runtime exception thrown in cases when runnable task's running thread is interrupted. Semantical meaning is almost
@@ -10,7 +10,7 @@
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
-package org.sonatype.nexus.util.task;
+package org.sonatype.nexus.proxy.maven.routing.internal.task;
import static com.google.common.base.Preconditions.checkArgument;
@@ -10,13 +10,18 @@
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
-package org.sonatype.nexus.util.task.executor;
+package org.sonatype.nexus.proxy.maven.routing.internal.task.executor;
-import org.sonatype.nexus.util.task.CancelableRunnable;
+import org.sonatype.nexus.proxy.maven.routing.internal.task.CancelableRunnable;
/**
* Simple {@link java.util.concurrent.Executor} like service, that offers a bit extra functionality in a way it can
* guarantee no two concurrent commands are running under same key.
+ * <p>
+ * The main point of ConstrainedExecutor is to workaround limitation of RepositoryItemUidLock that does not provide a
+ * mechanism to lock-with-timeout and to identify and cancel long-running lock holders. Together with
+ * CancelableRunnable, ConstrainedExecutor provides ability to avoid multiple concurrent executions of autorouting
+ * metadata update for the same repository.
*
* @author cstamas
* @since 2.4
@@ -10,21 +10,22 @@
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
-package org.sonatype.nexus.util.task.executor;
+package org.sonatype.nexus.proxy.maven.routing.internal.task.executor;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.HashMap;
import java.util.HashSet;
import java.util.concurrent.Semaphore;
-import org.sonatype.nexus.util.task.CancelableRunnable;
-import org.sonatype.nexus.util.task.CancelableSupport;
+import org.sonatype.nexus.proxy.maven.routing.internal.task.CancelableRunnable;
+import org.sonatype.nexus.proxy.maven.routing.internal.task.CancelableSupport;
/**
* Default implementation of Executor that adds a thin layer around {@link java.util.concurrent.Executor} that is passed
* in from constructor.
*
+ *
* @author cstamas
* @since 2.4
*/
@@ -10,11 +10,11 @@
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
-package org.sonatype.nexus.util.task.executor;
+package org.sonatype.nexus.proxy.maven.routing.internal.task.executor;
import java.util.Set;
-import org.sonatype.nexus.util.task.CancelableRunnable;
+import org.sonatype.nexus.proxy.maven.routing.internal.task.CancelableRunnable;
/**
* Simple statistics for {@link ConstrainedExecutor}.
@@ -10,7 +10,7 @@
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
-package org.sonatype.nexus.util.task.executor;
+package org.sonatype.nexus.proxy.maven.routing.internal.task;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty;
@@ -20,8 +20,10 @@
import java.util.concurrent.Executors;
import org.junit.Test;
-import org.sonatype.nexus.util.task.CancelableRunnableSupport;
-import org.sonatype.nexus.util.task.CancelableUtil;
+import org.sonatype.nexus.proxy.maven.routing.internal.task.CancelableRunnableSupport;
+import org.sonatype.nexus.proxy.maven.routing.internal.task.CancelableUtil;
+import org.sonatype.nexus.proxy.maven.routing.internal.task.executor.ConstrainedExecutor;
+import org.sonatype.nexus.proxy.maven.routing.internal.task.executor.ConstrainedExecutorImpl;
import org.sonatype.sisu.litmus.testsupport.TestSupport;
public class ConstrainedExecutorImplTest

0 comments on commit 9497485

Please sign in to comment.