michael-o commented on a change in pull request #131: URL: https://github.com/apache/maven-resolver/pull/131#discussion_r755484931
########## File path: maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/named/TakariNameMapper.java ########## @@ -0,0 +1,126 @@ +package org.eclipse.aether.internal.impl.synccontext.named; + +/* + * 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.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.metadata.Metadata; +import org.eclipse.aether.named.support.FileSystemFriendly; + +import javax.inject.Named; +import javax.inject.Singleton; + +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Path; +import java.util.Collection; +import java.util.TreeSet; +import java.util.concurrent.ConcurrentHashMap; + +/** + * A {@link NameMapper} that creates same name mapping as Takari Local Repository does, with baseDir (local repo). + * Part of code blatantly copies parts of the Takari {@code LockingSyncContext}. + * + * @see <a href="https://github.com/takari/takari-local-repository/blob/master/src/main/java/io/takari/aether/concurrency/LockingSyncContext.java">Takari + * LockingSyncContext.java</a> + */ +@Singleton +@Named( TakariNameMapper.NAME ) +public class TakariNameMapper + implements NameMapper, FileSystemFriendly +{ + public static final String NAME = "takari"; + + private static final char SEPARATOR = '~'; + + private final ConcurrentHashMap<String, Path> baseDirs; + + public TakariNameMapper() + { + this.baseDirs = new ConcurrentHashMap<>(); + } + + @Override + public TreeSet<String> nameLocks( final RepositorySystemSession session, + final Collection<? extends Artifact> artifacts, + final Collection<? extends Metadata> metadatas ) + { + File localRepositoryBasedir = session.getLocalRepository().getBasedir(); + Path baseDir = baseDirs.computeIfAbsent( Review comment: where is basedirs used? can this change within a session? ########## File path: maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/named/TakariNameMapper.java ########## @@ -0,0 +1,126 @@ +package org.eclipse.aether.internal.impl.synccontext.named; + +/* + * 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.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.metadata.Metadata; +import org.eclipse.aether.named.support.FileSystemFriendly; + +import javax.inject.Named; +import javax.inject.Singleton; + +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Path; +import java.util.Collection; +import java.util.TreeSet; +import java.util.concurrent.ConcurrentHashMap; + +/** + * A {@link NameMapper} that creates same name mapping as Takari Local Repository does, with baseDir (local repo). + * Part of code blatantly copies parts of the Takari {@code LockingSyncContext}. + * + * @see <a href="https://github.com/takari/takari-local-repository/blob/master/src/main/java/io/takari/aether/concurrency/LockingSyncContext.java">Takari Review comment: this should be a permanent link ########## File path: maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/Retry.java ########## @@ -0,0 +1,98 @@ +package org.eclipse.aether.named.support; + +/* + * 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 java.util.function.Supplier; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Retry helper: retries operation for given time. Assumes {@code null} as "no answer". It retries as long as it + * gets non-null result from operation, or the given time passes. + * + * @since TBD + */ +public final class Retry Review comment: why do we suddenly need this? ########## File path: maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/FileSystemFriendly.java ########## @@ -0,0 +1,30 @@ +package org.eclipse.aether.named.support; + +/* + * 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. + */ + +/** + * A marker interface that mark component "file system friendly". In case of lock factory, it would mean that + * passed in lock names MUST ADHERE to file path naming convention (and not use some special, non FS friendly + * characters in it). Essentially, component marked with this interface expects (or uses) that "name" is an absolute + * and valid file path. + */ +public interface FileSystemFriendly Review comment: this needs more thought whether we can generalize this some how. ########## File path: maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/named/TakariNameMapper.java ########## @@ -0,0 +1,126 @@ +package org.eclipse.aether.internal.impl.synccontext.named; + +/* + * 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.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.metadata.Metadata; +import org.eclipse.aether.named.support.FileSystemFriendly; + +import javax.inject.Named; +import javax.inject.Singleton; + +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Path; +import java.util.Collection; +import java.util.TreeSet; +import java.util.concurrent.ConcurrentHashMap; + +/** + * A {@link NameMapper} that creates same name mapping as Takari Local Repository does, with baseDir (local repo). + * Part of code blatantly copies parts of the Takari {@code LockingSyncContext}. + * + * @see <a href="https://github.com/takari/takari-local-repository/blob/master/src/main/java/io/takari/aether/concurrency/LockingSyncContext.java">Takari + * LockingSyncContext.java</a> + */ +@Singleton +@Named( TakariNameMapper.NAME ) +public class TakariNameMapper + implements NameMapper, FileSystemFriendly +{ + public static final String NAME = "takari"; + + private static final char SEPARATOR = '~'; + + private final ConcurrentHashMap<String, Path> baseDirs; + + public TakariNameMapper() + { + this.baseDirs = new ConcurrentHashMap<>(); + } + + @Override + public TreeSet<String> nameLocks( final RepositorySystemSession session, + final Collection<? extends Artifact> artifacts, + final Collection<? extends Metadata> metadatas ) + { + File localRepositoryBasedir = session.getLocalRepository().getBasedir(); + Path baseDir = baseDirs.computeIfAbsent( + localRepositoryBasedir.getPath(), k -> + { + try + { + return new File( localRepositoryBasedir, ".locks" ).getCanonicalFile().toPath(); + } + catch ( IOException e ) + { + throw new UncheckedIOException( e ); + } + } + ); + + TreeSet<String> paths = new TreeSet<>(); + if ( artifacts != null ) + { + for ( Artifact artifact : artifacts ) + { + paths.add( getPath( baseDir, artifact ) + ".aetherlock" ); + } + } + if ( metadatas != null ) + { + for ( Metadata metadata : metadatas ) + { + paths.add( getPath( baseDir, metadata ) + ".aetherlock" ); Review comment: let's call it resolver-lock ########## File path: maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/FileLockNamedLock.java ########## @@ -0,0 +1,295 @@ +package org.eclipse.aether.named.support; + +/* + * 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.io.IOException; +import java.io.UncheckedIOException; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; +import java.nio.channels.OverlappingFileLockException; +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.Deque; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; + +import static org.eclipse.aether.named.support.Retry.retry; + +/** + * Named lock that uses {@link FileLock}. + * + * @since TBD + */ +public final class FileLockNamedLock + extends NamedLockSupport +{ + private static final long LOCK_POSITION = 0L; + + private static final long LOCK_SIZE = 1L; + + private final HashMap<Thread, Deque<FileLock>> threadSteps; + + private final FileChannel fileChannel; + + private final ReentrantLock fairLock; + + public FileLockNamedLock( final String name, + final FileChannel fileChannel, + final NamedLockFactorySupport factory ) + { + super( name, factory ); + this.threadSteps = new HashMap<>(); + this.fileChannel = fileChannel; + this.fairLock = new ReentrantLock( true ); Review comment: why fair? -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
