You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by mi...@apache.org on 2021/05/01 20:15:55 UTC
[maven-resolver] branch master updated: [MRESOLVER-175] Drop
SyncContextFactory delegates in favor of a selector approach
This is an automated email from the ASF dual-hosted git repository.
michaelo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-resolver.git
The following commit(s) were added to refs/heads/master by this push:
new 2c83a69 [MRESOLVER-175] Drop SyncContextFactory delegates in favor of a selector approach
2c83a69 is described below
commit 2c83a6916d586b263b8932ff37637fb4904db8f9
Author: Tamas Cservenak <ta...@cservenak.net>
AuthorDate: Fri Apr 30 10:37:43 2021 +0200
[MRESOLVER-175] Drop SyncContextFactory delegates in favor of a selector approach
Drop all the factory delegates, leave only `named` SyncContextFactory
as only factory, but extend it to be able to functionally replace
the dropped ones.
Replacements:
* Introduce NoopNamedLockFactory
* GlobalSyncContextFactory becomes combo of `static` NameMapper + any NamedLockFactory
* NoLockSyncContextFactory becomes combo of any NameMapper + NoopNamedLockFactory
This closes #102
---
.../eclipse/aether/impl/DefaultServiceLocator.java | 2 +
.../eclipse/aether/impl/guice/AetherModule.java | 33 ++----
.../synccontext/DefaultSyncContextFactory.java | 71 ++++++------
.../impl/synccontext/GlobalSyncContextFactory.java | 94 ----------------
...tFactory.java => NamedLockFactorySelector.java} | 119 +++++++++++----------
.../impl/synccontext/NoLockSyncContextFactory.java | 63 -----------
.../synccontext/SyncContextFactoryDelegate.java | 29 -----
.../src/site/markdown/synccontextfactory.md.vm | 36 +++----
.../named/providers/NoopNamedLockFactory.java | 71 ++++++++++++
9 files changed, 193 insertions(+), 325 deletions(-)
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/DefaultServiceLocator.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/DefaultServiceLocator.java
index fa72590..b706bfa 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/DefaultServiceLocator.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/DefaultServiceLocator.java
@@ -55,6 +55,7 @@ import org.eclipse.aether.internal.impl.Maven2RepositoryLayoutFactory;
import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
import org.eclipse.aether.internal.impl.slf4j.Slf4jLoggerFactory;
import org.eclipse.aether.internal.impl.synccontext.DefaultSyncContextFactory;
+import org.eclipse.aether.internal.impl.synccontext.NamedLockFactorySelector;
import org.eclipse.aether.spi.connector.checksum.ChecksumPolicyProvider;
import org.eclipse.aether.spi.connector.layout.RepositoryLayoutFactory;
import org.eclipse.aether.spi.connector.layout.RepositoryLayoutProvider;
@@ -221,6 +222,7 @@ public final class DefaultServiceLocator
addService( LocalRepositoryManagerFactory.class, EnhancedLocalRepositoryManagerFactory.class );
addService( LoggerFactory.class, Slf4jLoggerFactory.class );
addService( TrackingFileManager.class, DefaultTrackingFileManager.class );
+ addService( NamedLockFactorySelector.class, NamedLockFactorySelector.class );
}
private <T> Entry<T> getEntry( Class<T> type, boolean create )
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/guice/AetherModule.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/guice/AetherModule.java
index 0ac8245..1fe9db2 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/guice/AetherModule.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/guice/AetherModule.java
@@ -43,10 +43,7 @@ import org.eclipse.aether.impl.RepositoryEventDispatcher;
import org.eclipse.aether.internal.impl.DefaultTrackingFileManager;
import org.eclipse.aether.internal.impl.TrackingFileManager;
import org.eclipse.aether.internal.impl.synccontext.DefaultSyncContextFactory;
-import org.eclipse.aether.internal.impl.synccontext.GlobalSyncContextFactory;
-import org.eclipse.aether.internal.impl.synccontext.NamedSyncContextFactory;
-import org.eclipse.aether.internal.impl.synccontext.NoLockSyncContextFactory;
-import org.eclipse.aether.internal.impl.synccontext.SyncContextFactoryDelegate;
+import org.eclipse.aether.internal.impl.synccontext.NamedLockFactorySelector;
import org.eclipse.aether.internal.impl.synccontext.named.GAVNameMapper;
import org.eclipse.aether.internal.impl.synccontext.named.DiscriminatingNameMapper;
import org.eclipse.aether.internal.impl.synccontext.named.NameMapper;
@@ -77,6 +74,7 @@ import org.eclipse.aether.internal.impl.EnhancedLocalRepositoryManagerFactory;
import org.eclipse.aether.internal.impl.Maven2RepositoryLayoutFactory;
import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
import org.eclipse.aether.internal.impl.slf4j.Slf4jLoggerFactory;
+import org.eclipse.aether.named.providers.NoopNamedLockFactory;
import org.eclipse.aether.spi.connector.checksum.ChecksumPolicyProvider;
import org.eclipse.aether.spi.connector.layout.RepositoryLayoutFactory;
import org.eclipse.aether.spi.connector.layout.RepositoryLayoutProvider;
@@ -160,16 +158,11 @@ public class AetherModule
.to( EnhancedLocalRepositoryManagerFactory.class ).in( Singleton.class );
bind( TrackingFileManager.class ).to( DefaultTrackingFileManager.class ).in( Singleton.class );
+ bind( NamedLockFactorySelector.class ).in( Singleton.class );
bind( SyncContextFactory.class ).to( DefaultSyncContextFactory.class ).in( Singleton.class );
bind( org.eclipse.aether.impl.SyncContextFactory.class )
.to( org.eclipse.aether.internal.impl.synccontext.legacy.DefaultSyncContextFactory.class )
.in( Singleton.class );
- bind( SyncContextFactoryDelegate.class ).annotatedWith( Names.named( NoLockSyncContextFactory.NAME ) )
- .to( NoLockSyncContextFactory.class ).in( Singleton.class );
- bind( SyncContextFactoryDelegate.class ).annotatedWith( Names.named( GlobalSyncContextFactory.NAME ) )
- .to( GlobalSyncContextFactory.class ).in( Singleton.class );
- bind( SyncContextFactoryDelegate.class ).annotatedWith( Names.named( NamedSyncContextFactory.NAME ) )
- .to( NamedSyncContextFactory.class ).in( Singleton.class );
bind( NameMapper.class ).annotatedWith( Names.named( StaticNameMapper.NAME ) )
.to( StaticNameMapper.class ).in( Singleton.class );
@@ -178,10 +171,12 @@ public class AetherModule
bind( NameMapper.class ).annotatedWith( Names.named( DiscriminatingNameMapper.NAME ) )
.to( DiscriminatingNameMapper.class ).in( Singleton.class );
+ bind( NamedLockFactory.class ).annotatedWith( Names.named( NoopNamedLockFactory.NAME ) )
+ .to( NoopNamedLockFactory.class ).in( Singleton.class );
bind( NamedLockFactory.class ).annotatedWith( Names.named( LocalReadWriteLockNamedLockFactory.NAME ) )
- .to( LocalReadWriteLockNamedLockFactory.class ).in( Singleton.class );
+ .to( LocalReadWriteLockNamedLockFactory.class ).in( Singleton.class );
bind( NamedLockFactory.class ).annotatedWith( Names.named( LocalSemaphoreNamedLockFactory.NAME ) )
- .to( LocalSemaphoreNamedLockFactory.class ).in( Singleton.class );
+ .to( LocalSemaphoreNamedLockFactory.class ).in( Singleton.class );
install( new Slf4jModule() );
@@ -189,20 +184,6 @@ public class AetherModule
@Provides
@Singleton
- Map<String, SyncContextFactoryDelegate> provideSyncContextFactoryDelegates(
- @Named( NoLockSyncContextFactory.NAME ) SyncContextFactoryDelegate nolock,
- @Named( GlobalSyncContextFactory.NAME ) SyncContextFactoryDelegate global,
- @Named( NamedSyncContextFactory.NAME ) SyncContextFactoryDelegate named )
- {
- Map<String, SyncContextFactoryDelegate> factories = new HashMap<>();
- factories.put( NoLockSyncContextFactory.NAME, nolock );
- factories.put( GlobalSyncContextFactory.NAME, global );
- factories.put( NamedSyncContextFactory.NAME, named );
- return Collections.unmodifiableMap( factories );
- }
-
- @Provides
- @Singleton
Map<String, NameMapper> provideNameMappers(
@Named( StaticNameMapper.NAME ) NameMapper staticNameMapper,
@Named( GAVNameMapper.NAME ) NameMapper gavNameMapper,
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/DefaultSyncContextFactory.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/DefaultSyncContextFactory.java
index 894d9ca..1775c75 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/DefaultSyncContextFactory.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/DefaultSyncContextFactory.java
@@ -19,68 +19,71 @@ package org.eclipse.aether.internal.impl.synccontext;
* under the License.
*/
-import org.eclipse.aether.RepositorySystemSession;
-import org.eclipse.aether.SyncContext;
-import org.eclipse.aether.spi.synccontext.SyncContextFactory;
+import java.util.Objects;
+import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
+
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.SyncContext;
+import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapter;
+import org.eclipse.aether.spi.locator.Service;
+import org.eclipse.aether.spi.locator.ServiceLocator;
+import org.eclipse.aether.spi.synccontext.SyncContextFactory;
/**
- * Default {@link SyncContextFactory} implementation that delegates to some {@link SyncContextFactoryDelegate}
- * implementation.
+ * Default {@link SyncContextFactory} implementation that uses named locks.
*/
@Singleton
@Named
public final class DefaultSyncContextFactory
- implements SyncContextFactory
+ implements SyncContextFactory, Service
{
- private static final String SYNC_CONTEXT_FACTORY_NAME = System.getProperty(
- "aether.syncContext.impl", NamedSyncContextFactory.NAME
- );
-
- private final SyncContextFactoryDelegate delegate;
+ private NamedLockFactoryAdapter namedLockFactoryAdapter;
/**
* Constructor used with DI, where factories are injected and selected based on key.
*/
@Inject
- public DefaultSyncContextFactory( final Map<String, SyncContextFactoryDelegate> delegates )
+ public DefaultSyncContextFactory( final NamedLockFactorySelector selector )
{
- Objects.requireNonNull( delegates );
- this.delegate = selectDelegate( delegates );
+ this.namedLockFactoryAdapter = new NamedLockFactoryAdapter(
+ selector.getSelectedNameMapper(),
+ selector.getSelectedNamedLockFactory(),
+ NamedLockFactorySelector.TIME,
+ NamedLockFactorySelector.TIME_UNIT
+ );
}
- /**
- * Default constructor
- */
public DefaultSyncContextFactory()
{
- Map<String, SyncContextFactoryDelegate> delegates = new HashMap<>( 3 );
- delegates.put( NoLockSyncContextFactory.NAME, new NoLockSyncContextFactory() );
- delegates.put( GlobalSyncContextFactory.NAME, new GlobalSyncContextFactory() );
- delegates.put( NamedSyncContextFactory.NAME, new NamedSyncContextFactory() );
- this.delegate = selectDelegate( delegates );
+ // ctor for ServiceLoader
}
- private SyncContextFactoryDelegate selectDelegate( final Map<String, SyncContextFactoryDelegate> delegates )
+ @Override
+ public void initService( final ServiceLocator locator )
{
- SyncContextFactoryDelegate delegate = delegates.get( SYNC_CONTEXT_FACTORY_NAME );
- if ( delegate == null )
- {
- throw new IllegalArgumentException( "Unknown SyncContextFactory impl: " + SYNC_CONTEXT_FACTORY_NAME
- + ", known ones: " + delegates.keySet() );
- }
- return delegate;
+ NamedLockFactorySelector selector = Objects.requireNonNull(
+ locator.getService( NamedLockFactorySelector.class ) );
+ this.namedLockFactoryAdapter = new NamedLockFactoryAdapter(
+ selector.getSelectedNameMapper(),
+ selector.getSelectedNamedLockFactory(),
+ NamedLockFactorySelector.TIME,
+ NamedLockFactorySelector.TIME_UNIT
+ );
}
@Override
public SyncContext newInstance( final RepositorySystemSession session, final boolean shared )
{
- return delegate.newInstance( session, shared );
+ return namedLockFactoryAdapter.newInstance( session, shared );
+ }
+
+ @PreDestroy
+ public void shutdown()
+ {
+ namedLockFactoryAdapter.shutdown();
}
}
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/GlobalSyncContextFactory.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/GlobalSyncContextFactory.java
deleted file mode 100644
index 047132e..0000000
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/GlobalSyncContextFactory.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package org.eclipse.aether.internal.impl.synccontext;
-
-/*
- * 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.
- */
-
-import java.util.Collection;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import javax.inject.Named;
-import javax.inject.Singleton;
-
-import org.eclipse.aether.RepositorySystemSession;
-import org.eclipse.aether.SyncContext;
-import org.eclipse.aether.artifact.Artifact;
-import org.eclipse.aether.metadata.Metadata;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A singleton factory to create synchronization contexts using a global lock based on
- * {@link ReentrantReadWriteLock}. Explicit artifacts and metadata passed are ignored.
- * <p>
- * <strong>Note: This component is still considered to be experimental, use with caution!</strong>
- */
-@Singleton
-@Named( GlobalSyncContextFactory.NAME )
-public class GlobalSyncContextFactory
- implements SyncContextFactoryDelegate
-{
- public static final String NAME = "global";
-
- private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-
- @Override
- public SyncContext newInstance( final RepositorySystemSession session, final boolean shared )
- {
- return new GlobalSyncContext( shared ? lock.readLock() : lock.writeLock(), shared );
- }
-
- private static class GlobalSyncContext
- implements SyncContext
- {
- private static final Logger LOGGER = LoggerFactory.getLogger( GlobalSyncContext.class );
-
- private final Lock lock;
- private final boolean shared;
- private int lockHoldCount;
-
- private GlobalSyncContext( final Lock lock, final boolean shared )
- {
- this.lock = lock;
- this.shared = shared;
- }
-
- @Override
- public void acquire( final Collection<? extends Artifact> artifact,
- final Collection<? extends Metadata> metadata )
- {
- LOGGER.trace( "Acquiring global {} lock (currently held: {})",
- shared ? "read" : "write", lockHoldCount );
- lock.lock();
- lockHoldCount++;
- }
-
- @Override
- public void close()
- {
- while ( lockHoldCount > 0 )
- {
- LOGGER.trace( "Releasing global {} lock (currently held: {})",
- shared ? "read" : "write", lockHoldCount );
- lock.unlock();
- lockHoldCount--;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/NamedSyncContextFactory.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/NamedLockFactorySelector.java
similarity index 58%
rename from maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/NamedSyncContextFactory.java
rename to maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/NamedLockFactorySelector.java
index ba47c8d..190950f 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/NamedSyncContextFactory.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/NamedLockFactorySelector.java
@@ -19,106 +19,115 @@ package org.eclipse.aether.internal.impl.synccontext;
* under the License.
*/
-import org.eclipse.aether.RepositorySystemSession;
-import org.eclipse.aether.SyncContext;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
import org.eclipse.aether.internal.impl.synccontext.named.DiscriminatingNameMapper;
import org.eclipse.aether.internal.impl.synccontext.named.GAVNameMapper;
import org.eclipse.aether.internal.impl.synccontext.named.NameMapper;
-import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapter;
import org.eclipse.aether.internal.impl.synccontext.named.StaticNameMapper;
import org.eclipse.aether.named.NamedLockFactory;
import org.eclipse.aether.named.providers.LocalReadWriteLockNamedLockFactory;
import org.eclipse.aether.named.providers.LocalSemaphoreNamedLockFactory;
-
-import javax.annotation.PreDestroy;
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Singleton;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
+import org.eclipse.aether.named.providers.NoopNamedLockFactory;
/**
- * Named {@link SyncContextFactoryDelegate} implementation that selects underlying {@link NamedLockFactory}
- * implementation at creation.
+ * Selector for {@link NamedLockFactory} and {@link NameMapper} that selects and exposes selected ones. Essentially
+ * all the named locks configuration is here.
*/
@Singleton
-@Named( NamedSyncContextFactory.NAME )
-public final class NamedSyncContextFactory
- implements SyncContextFactoryDelegate
+@Named
+public final class NamedLockFactorySelector
{
- public static final String NAME = "named";
+ public static final long TIME = Long.getLong(
+ "aether.syncContext.named.time", 30L
+ );
+
+ public static final TimeUnit TIME_UNIT = TimeUnit.valueOf( System.getProperty(
+ "aether.syncContext.named.time.unit", TimeUnit.SECONDS.name()
+ ) );
private static final String FACTORY_NAME = System.getProperty(
- "aether.syncContext.named.factory", LocalReadWriteLockNamedLockFactory.NAME
+ "aether.syncContext.named.factory", LocalReadWriteLockNamedLockFactory.NAME
);
- private static final String NAME_MAPPER = System.getProperty(
+ private static final String NAME_MAPPER_NAME = System.getProperty(
"aether.syncContext.named.nameMapper", GAVNameMapper.NAME
);
- private static final long TIME = Long.getLong(
- "aether.syncContext.named.time", 30L
- );
-
- private static final TimeUnit TIME_UNIT = TimeUnit.valueOf( System.getProperty(
- "aether.syncContext.named.time.unit", TimeUnit.SECONDS.name()
- ) );
+ private final NamedLockFactory namedLockFactory;
- private final NamedLockFactoryAdapter namedLockFactoryAdapter;
+ private final NameMapper nameMapper;
/**
* Constructor used with DI, where factories are injected and selected based on key.
*/
@Inject
- public NamedSyncContextFactory( final Map<String, NameMapper> nameMappers,
- final Map<String, NamedLockFactory> factories )
+ public NamedLockFactorySelector( final Map<String, NamedLockFactory> factories,
+ final Map<String, NameMapper> nameMappers )
{
- this.namedLockFactoryAdapter = selectAndAdapt( nameMappers, factories );
+ this.namedLockFactory = selectNamedLockFactory( factories );
+ this.nameMapper = selectNameMapper( nameMappers );
}
/**
- * Default constructor
+ * Default constructor for ServiceLocator.
*/
- public NamedSyncContextFactory()
+ public NamedLockFactorySelector()
{
+ Map<String, NamedLockFactory> factories = new HashMap<>();
+ factories.put( NoopNamedLockFactory.NAME, new NoopNamedLockFactory() );
+ factories.put( LocalReadWriteLockNamedLockFactory.NAME, new LocalReadWriteLockNamedLockFactory() );
+ factories.put( LocalSemaphoreNamedLockFactory.NAME, new LocalSemaphoreNamedLockFactory() );
+ this.namedLockFactory = selectNamedLockFactory( factories );
+
Map<String, NameMapper> nameMappers = new HashMap<>();
nameMappers.put( StaticNameMapper.NAME, new StaticNameMapper() );
nameMappers.put( GAVNameMapper.NAME, new GAVNameMapper() );
nameMappers.put( DiscriminatingNameMapper.NAME, new DiscriminatingNameMapper( new GAVNameMapper() ) );
- Map<String, NamedLockFactory> factories = new HashMap<>();
- factories.put( LocalReadWriteLockNamedLockFactory.NAME, new LocalReadWriteLockNamedLockFactory() );
- factories.put( LocalSemaphoreNamedLockFactory.NAME, new LocalSemaphoreNamedLockFactory() );
- this.namedLockFactoryAdapter = selectAndAdapt( nameMappers, factories );
+ this.nameMapper = selectNameMapper( nameMappers );
}
- private static NamedLockFactoryAdapter selectAndAdapt( final Map<String, NameMapper> nameMappers,
- final Map<String, NamedLockFactory> factories )
+ /**
+ * Returns the selected {@link NamedLockFactory}, never null.
+ */
+ public NamedLockFactory getSelectedNamedLockFactory()
+ {
+ return namedLockFactory;
+ }
+
+ /**
+ * Returns the selected {@link NameMapper}, never null.
+ */
+ public NameMapper getSelectedNameMapper()
+ {
+ return nameMapper;
+ }
+
+ private static NamedLockFactory selectNamedLockFactory( final Map<String, NamedLockFactory> factories )
{
- NameMapper nameMapper = nameMappers.get( NAME_MAPPER );
- if ( nameMapper == null )
- {
- throw new IllegalArgumentException( "Unknown NameMapper name: " + NAME_MAPPER
- + ", known ones: " + nameMappers.keySet() );
- }
NamedLockFactory factory = factories.get( FACTORY_NAME );
if ( factory == null )
{
throw new IllegalArgumentException( "Unknown NamedLockFactory name: " + FACTORY_NAME
- + ", known ones: " + factories.keySet() );
+ + ", known ones: " + factories.keySet() );
}
- return new NamedLockFactoryAdapter( nameMapper, factory, TIME, TIME_UNIT );
- }
-
- @Override
- public SyncContext newInstance( final RepositorySystemSession session, final boolean shared )
- {
- return namedLockFactoryAdapter.newInstance( session, shared );
+ return factory;
}
- @PreDestroy
- public void shutdown()
+ private static NameMapper selectNameMapper( final Map<String, NameMapper> nameMappers )
{
- namedLockFactoryAdapter.shutdown();
+ NameMapper nameMapper = nameMappers.get( NAME_MAPPER_NAME );
+ if ( nameMapper == null )
+ {
+ throw new IllegalArgumentException( "Unknown NameMapper name: " + NAME_MAPPER_NAME
+ + ", known ones: " + nameMappers.keySet() );
+ }
+ return nameMapper;
}
}
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/NoLockSyncContextFactory.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/NoLockSyncContextFactory.java
deleted file mode 100644
index 10564d7..0000000
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/NoLockSyncContextFactory.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.eclipse.aether.internal.impl.synccontext;
-
-/*
- * 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.
- */
-
-import java.util.Collection;
-
-import javax.inject.Named;
-import javax.inject.Singleton;
-
-import org.eclipse.aether.RepositorySystemSession;
-import org.eclipse.aether.SyncContext;
-import org.eclipse.aether.artifact.Artifact;
-import org.eclipse.aether.metadata.Metadata;
-
-/**
- * A factory to create synchronization contexts. This default implementation does not provide any real
- * synchronization but merely completes the repository system.
- */
-@Singleton
-@Named( NoLockSyncContextFactory.NAME )
-public class NoLockSyncContextFactory
- implements SyncContextFactoryDelegate
-{
- public static final String NAME = "nolock";
-
- @Override
- public SyncContext newInstance( final RepositorySystemSession session, final boolean shared )
- {
- return new DefaultSyncContext();
- }
-
- private static class DefaultSyncContext
- implements SyncContext
- {
- @Override
- public void acquire( final Collection<? extends Artifact> artifact,
- final Collection<? extends Metadata> metadata )
- {
- }
-
- @Override
- public void close()
- {
- }
- }
-}
\ No newline at end of file
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/SyncContextFactoryDelegate.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/SyncContextFactoryDelegate.java
deleted file mode 100644
index 9f768f3..0000000
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/SyncContextFactoryDelegate.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.eclipse.aether.internal.impl.synccontext;
-
-/*
- * 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.
- */
-
-import org.eclipse.aether.spi.synccontext.SyncContextFactory;
-
-/**
- * Internal marker interface to mark internal implementations for {@link SyncContextFactory}.
- */
-public interface SyncContextFactoryDelegate extends SyncContextFactory
-{
-}
diff --git a/maven-resolver-impl/src/site/markdown/synccontextfactory.md.vm b/maven-resolver-impl/src/site/markdown/synccontextfactory.md.vm
index 54697a5..d198291 100644
--- a/maven-resolver-impl/src/site/markdown/synccontextfactory.md.vm
+++ b/maven-resolver-impl/src/site/markdown/synccontextfactory.md.vm
@@ -19,7 +19,7 @@ specific language governing permissions and limitations
under the License.
-->
-In this module there are several implementations of `SyncContextFactory`. The `SyncContextFactory` component is
+This module among others, implements `SyncContextFactory`. The `SyncContextFactory` component is
responsible to synchronize (coordinate) access to shared resources in Maven Resolver internals. Some examples:
- single threaded (ST) build on a single host: given resolution by default happens in multi threaded (MT) way, files
in a local repository must be protected from simultaneous access. In this case, it is enough for coordination to
@@ -38,22 +38,8 @@ a cross process, and in MP multi-host case a cross process and cross host coordi
The defaults in Maven Resolver cover ST and MT cases out of the box (by default).
-${esc.hash}${esc.hash} Provided Implementations
-
-This module provides a default implementation for the interface `org.eclipse.aether.spi.synccontext.SyncContextFactory`
-that is able to delegate to three implementations:
-
-- `named` (the default) is backed by named locks, and provide locks for MT and MP builds.
-- `global` (was experimental in pre 1.7.0 version) is using a single JVM
- `java.util.concurrent.locks.ReentrantReadWriteLock` to protect read and write actions, hence suitable in MT
- builds only. But, even in MT builds it is inferior from `named` due congestion on single lock instance.
-- `nolock` (was default in pre 1.7.0 version) is actually a no-op implementation. It is fundamentally flawed, as
- even single threaded builds may produce concurrency issues (see MRESOLVER-153). Should not be used by end-users,
- is left for "R&D" reasons only.
-
-To choose which `SyncContextFactory` you want to use, the `aether.syncContext.impl` JVM system property should be set
-to some value from those above. In case of wrong value, the factory constructor, hence, Maven itself will fail to
-initialize. The default value used if none is set by user is `named`.
+This module implementation for the interface `org.eclipse.aether.spi.synccontext.SyncContextFactory`
+uses resolver named locks.
${esc.hash}${esc.hash} Configuration Options for "named" `SyncContextFactory`
@@ -65,17 +51,19 @@ You can control and configure several aspects of `NamedSyncContextFactory`:
- `aether.syncContext.named.time.unit` (optional, default is `java.util.concurrent.TimeUnit.SECONDS`): the time unit
of time value.
-For the `aether.syncContext.named.nameMapper` property following values are allowed:
-
-- `discriminating` (default), uses hostname + local repo + GAV to create unique lock names for artifacts.
-- `gav` uses GAV to create unique lock names for artifacts and metadata. Is not unique if multiple local repositories are involved.
-- `static` uses static (same) string as lock name for any input, effectively providing functionality same as "global"
- locking SyncContextFactory.
-
For the `aether.syncContext.named.factory` property following values are allowed:
- `rwlock-local` (default), uses JVM `ReentrantReadWriteLock` per lock name, usable for MT builds.
- `semaphore-local`, uses JVM `Semaphore` per lock name, usable for MT builds.
+- `noop`, implement no-op locking (no locking). For experimenting only. Has same functionality as old "nolock"
+ SyncContextFactory implementation.
+
+For the `aether.syncContext.named.nameMapper` property following values are allowed:
+
+- `discriminating` (default), uses hostname + local repo + GAV to create unique lock names for artifacts.
+- `gav` uses GAV to create unique lock names for artifacts and metadata. Is not unique if multiple local repositories are involved.
+- `static` uses static (same) string as lock name for any input. Effectively providing functionality same as old
+ "global" locking SyncContextFactory.
Extra values for factory (these need extra setup and will work with Sisu DI only):
diff --git a/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/providers/NoopNamedLockFactory.java b/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/providers/NoopNamedLockFactory.java
new file mode 100644
index 0000000..66b45ed
--- /dev/null
+++ b/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/providers/NoopNamedLockFactory.java
@@ -0,0 +1,71 @@
+package org.eclipse.aether.named.providers;
+
+/*
+ * 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.
+ */
+
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.eclipse.aether.named.support.NamedLockFactorySupport;
+import org.eclipse.aether.named.support.NamedLockSupport;
+
+/**
+ * A no-op lock factory, that creates no-op locks.
+ */
+@Singleton
+@Named( NoopNamedLockFactory.NAME )
+public class NoopNamedLockFactory
+ extends NamedLockFactorySupport
+{
+ public static final String NAME = "noop";
+
+ @Override
+ protected NoopNamedLock createLock( final String name )
+ {
+ return new NoopNamedLock( name, this );
+ }
+
+ private static final class NoopNamedLock extends NamedLockSupport
+ {
+ private NoopNamedLock( final String name, final NamedLockFactorySupport factory )
+ {
+ super( name, factory );
+ }
+
+ @Override
+ public boolean lockShared( final long time, final TimeUnit unit )
+ {
+ return true;
+ }
+
+ @Override
+ public boolean lockExclusively( final long time, final TimeUnit unit )
+ {
+ return true;
+ }
+
+ @Override
+ public void unlock()
+ {
+ // no-op
+ }
+ }
+}