You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by be...@apache.org on 2010/01/19 23:25:13 UTC

svn commit: r900982 - in /maven/maven-3/trunk: maven-compat/src/main/java/org/apache/maven/artifact/resolver/ maven-compat/src/main/java/org/apache/maven/repository/legacy/ maven-embedder/src/main/java/org/apache/maven/cli/

Author: bentmann
Date: Tue Jan 19 22:25:12 2010
New Revision: 900982

URL: http://svn.apache.org/viewvc?rev=900982&view=rev
Log:
[MNG-4432] reimplement parallel artifacts download

Modified:
    maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java
    maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/repository/legacy/TransferListenerAdapter.java
    maven/maven-3/trunk/maven-embedder/src/main/java/org/apache/maven/cli/ConsoleMavenTransferListener.java

Modified: maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java?rev=900982&r1=900981&r2=900982&view=diff
==============================================================================
--- maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java (original)
+++ maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java Tue Jan 19 22:25:12 2010
@@ -24,6 +24,12 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.factory.ArtifactFactory;
@@ -97,6 +103,38 @@
     @Requirement
     private LegacySupport legacySupport;
 
+    private final Executor executor;
+
+    public DefaultArtifactResolver()
+    {
+        int threads = Integer.getInteger( "maven.artifact.threads", 5 ).intValue();
+        if ( threads <= 1 )
+        {
+            executor = new Executor()
+            {
+                public void execute( Runnable command )
+                {
+                    command.run();
+                }
+            };
+        }
+        else
+        {
+            executor =
+                new ThreadPoolExecutor( threads, threads, 3, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>() );
+        }
+    }
+
+    @Override
+    protected void finalize()
+        throws Throwable
+    {
+        if ( executor instanceof ExecutorService )
+        {
+            ( (ExecutorService) executor ).shutdown();
+        }
+    }
+
     private void injectSession( RepositoryRequest request )
     {
         MavenSession session = legacySupport.getSession();
@@ -558,41 +596,41 @@
         {
             return result;
         }
-                
+
         if ( result.getArtifactResolutionNodes() != null )
         {
-            ArtifactResolutionRequest childRequest = new ArtifactResolutionRequest( request );
+            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+
+            CountDownLatch latch = new CountDownLatch( result.getArtifactResolutionNodes().size() );
 
             for ( ResolutionNode node : result.getArtifactResolutionNodes() )
             {
                 Artifact artifact = node.getArtifact();
 
-                try
+                if ( resolutionFilter == null || resolutionFilter.include( artifact ) )
                 {
-                    if ( resolutionFilter == null || resolutionFilter.include( artifact ) )
-                    {
-                        childRequest.setRemoteRepositories( node.getRemoteRepositories() );
+                    ArtifactResolutionRequest childRequest = new ArtifactResolutionRequest( request );
+                    childRequest.setRemoteRepositories( node.getRemoteRepositories() );
 
-                        resolve( artifact, childRequest, transferListener, false );
-                    }
+                    executor.execute( new ResolveTask( classLoader, latch, artifact, transferListener, childRequest,
+                                                       result ) );
                 }
-                catch ( ArtifactNotFoundException anfe )
-                {
-                    // These are cases where the artifact just isn't present in any of the remote repositories
-                    // because it wasn't deployed, or it was deployed in the wrong place.
-
-                    result.addMissingArtifact( artifact );
-                }
-                catch ( ArtifactResolutionException e )
+                else
                 {
-                    // This is really a wagon TransferFailedException so something went wrong after we successfully
-                    // retrieved the metadata.
-
-                    result.addErrorArtifactException( e );
+                    latch.countDown();
                 }
             }
+            try
+            {
+                latch.await();
+            }
+            catch ( InterruptedException e )
+            {
+                result.addErrorArtifactException( new ArtifactResolutionException( "Resolution interrupted",
+                                                                                   rootArtifact, e ) );
+            }
         }
-                
+
         // We want to send the root artifact back in the result but we need to do this after the other dependencies
         // have been resolved.
         if ( request.isResolveRoot() )
@@ -612,4 +650,67 @@
     {
         resolve( artifact, remoteRepositories, localRepository, null );
     }
+
+    private class ResolveTask
+        implements Runnable
+    {
+
+        private final ClassLoader classLoader;
+
+        private final CountDownLatch latch;
+
+        private final Artifact artifact;
+
+        private final TransferListener transferListener;
+
+        private final ArtifactResolutionRequest request;
+
+        private final ArtifactResolutionResult result;
+
+        public ResolveTask( ClassLoader classLoader, CountDownLatch latch, Artifact artifact, TransferListener transferListener,
+                            ArtifactResolutionRequest request, ArtifactResolutionResult result )
+        {
+            this.classLoader = classLoader;
+            this.latch = latch;
+            this.artifact = artifact;
+            this.transferListener = transferListener;
+            this.request = request;
+            this.result = result;
+        }
+
+        public void run()
+        {
+            try
+            {
+                Thread.currentThread().setContextClassLoader( classLoader );
+                resolve( artifact, request, transferListener, false );
+            }
+            catch ( ArtifactNotFoundException anfe )
+            {
+                // These are cases where the artifact just isn't present in any of the remote repositories
+                // because it wasn't deployed, or it was deployed in the wrong place.
+
+                synchronized ( result )
+                {
+                    result.addMissingArtifact( artifact );
+                }
+            }
+            catch ( ArtifactResolutionException e )
+            {
+                // This is really a wagon TransferFailedException so something went wrong after we successfully
+                // retrieved the metadata.
+
+                synchronized ( result )
+                {
+                    result.addErrorArtifactException( e );
+                }
+            }
+            finally
+            {
+                latch.countDown();
+            }
+        }
+
+    }
+
 }

Modified: maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/repository/legacy/TransferListenerAdapter.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/repository/legacy/TransferListenerAdapter.java?rev=900982&r1=900981&r2=900982&view=diff
==============================================================================
--- maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/repository/legacy/TransferListenerAdapter.java (original)
+++ maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/repository/legacy/TransferListenerAdapter.java Tue Jan 19 22:25:12 2010
@@ -34,11 +34,11 @@
     implements TransferListener
 {
 
-    private ArtifactTransferListener listener;
+    private final ArtifactTransferListener listener;
 
-    private Map<Resource, ArtifactTransferResource> artifacts;
+    private final Map<Resource, ArtifactTransferResource> artifacts;
 
-    private Map<Resource, Long> transfers;
+    private final Map<Resource, Long> transfers;
 
     public static TransferListener newAdapter( ArtifactTransferListener listener )
     {
@@ -67,22 +67,34 @@
     {
         ArtifactTransferEvent event = wrap( transferEvent );
 
-        Long transferred = transfers.get( transferEvent.getResource() );
+        Long transferred = null;
+        synchronized ( transfers )
+        {
+            transferred = transfers.remove( transferEvent.getResource() );
+        }
         if ( transferred != null )
         {
             event.setTransferredBytes( transferred.longValue() );
         }
 
-        listener.transferCompleted( event );
+        synchronized ( artifacts )
+        {
+            artifacts.remove( transferEvent.getResource() );
+        }
 
-        artifacts.remove( transferEvent.getResource() );
-        transfers.remove( transferEvent.getResource() );
+        listener.transferCompleted( event );
     }
 
     public void transferError( TransferEvent transferEvent )
     {
-        artifacts.remove( transferEvent.getResource() );
-        transfers.remove( transferEvent.getResource() );
+        synchronized ( transfers )
+        {
+            transfers.remove( transferEvent.getResource() );
+        }
+        synchronized ( artifacts )
+        {
+            artifacts.remove( transferEvent.getResource() );
+        }
     }
 
     public void transferInitiated( TransferEvent transferEvent )
@@ -92,16 +104,20 @@
 
     public void transferProgress( TransferEvent transferEvent, byte[] buffer, int length )
     {
-        Long transferred = transfers.get( transferEvent.getResource() );
-        if ( transferred == null )
-        {
-            transferred = Long.valueOf( length );
-        }
-        else
+        Long transferred;
+        synchronized ( transfers )
         {
-            transferred = Long.valueOf( transferred.longValue() + length );
+            transferred = transfers.get( transferEvent.getResource() );
+            if ( transferred == null )
+            {
+                transferred = Long.valueOf( length );
+            }
+            else
+            {
+                transferred = Long.valueOf( transferred.longValue() + length );
+            }
+            transfers.put( transferEvent.getResource(), transferred );
         }
-        transfers.put( transferEvent.getResource(), transferred );
 
         ArtifactTransferEvent event = wrap( transferEvent );
         event.setDataBuffer( buffer );
@@ -153,15 +169,18 @@
         }
         else
         {
-            ArtifactTransferResource artifact = artifacts.get( resource );
-
-            if ( artifact == null )
+            synchronized ( artifacts )
             {
-                artifact = new MavenArtifact( repository.getUrl(), resource );
-                artifacts.put( resource, artifact );
-            }
+                ArtifactTransferResource artifact = artifacts.get( resource );
 
-            return artifact;
+                if ( artifact == null )
+                {
+                    artifact = new MavenArtifact( repository.getUrl(), resource );
+                    artifacts.put( resource, artifact );
+                }
+
+                return artifact;
+            }
         }
     }
 

Modified: maven/maven-3/trunk/maven-embedder/src/main/java/org/apache/maven/cli/ConsoleMavenTransferListener.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-embedder/src/main/java/org/apache/maven/cli/ConsoleMavenTransferListener.java?rev=900982&r1=900981&r2=900982&view=diff
==============================================================================
--- maven/maven-3/trunk/maven-embedder/src/main/java/org/apache/maven/cli/ConsoleMavenTransferListener.java (original)
+++ maven/maven-3/trunk/maven-embedder/src/main/java/org/apache/maven/cli/ConsoleMavenTransferListener.java Tue Jan 19 22:25:12 2010
@@ -20,18 +20,27 @@
  */
 
 import java.io.PrintStream;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
 
 import org.apache.maven.repository.ArtifactTransferEvent;
+import org.apache.maven.repository.ArtifactTransferResource;
 
 /**
  * Console download progress meter.
- *
+ * 
  * @author <a href="mailto:brett@apache.org">Brett Porter</a>
  */
 class ConsoleMavenTransferListener
     extends AbstractMavenTransferListener
 {
 
+    private Map<ArtifactTransferResource, Long> downloads =
+        Collections.synchronizedMap( new LinkedHashMap<ArtifactTransferResource, Long>() );
+
+    private int lastLength;
+
     public ConsoleMavenTransferListener( PrintStream out )
     {
         super( out );
@@ -40,26 +49,69 @@
     @Override
     protected void doProgress( ArtifactTransferEvent transferEvent )
     {
-        long total = transferEvent.getResource().getContentLength();
-        long complete = transferEvent.getTransferredBytes();
+        ArtifactTransferResource resource = transferEvent.getResource();
+        downloads.put( resource, Long.valueOf( transferEvent.getTransferredBytes() ) );
+
+        StringBuilder buffer = new StringBuilder( 64 );
 
-        // TODO [BP]: Sys.out may no longer be appropriate, but will \r work with getLogger()?
+        for ( Map.Entry<ArtifactTransferResource, Long> entry : downloads.entrySet() )
+        {
+            long total = entry.getKey().getContentLength();
+            long complete = entry.getValue().longValue();
+
+            buffer.append( getStatus( complete, total ) ).append( "  " );
+        }
+
+        int pad = lastLength - buffer.length();
+        lastLength = buffer.length();
+        pad( buffer, pad );
+        buffer.append( '\r' );
+
+        out.print( buffer );
+    }
+
+    private String getStatus( long complete, long total )
+    {
         if ( total >= 1024 )
         {
-            out.print( toKB( complete ) + "/" + toKB( total ) + " KB " + "\r" );
+            return toKB( complete ) + "/" + toKB( total ) + " KB ";
         }
         else if ( total >= 0 )
         {
-            out.print( complete + "/" + total + " B " + "\r" );
+            return complete + "/" + total + " B ";
         }
         else if ( complete >= 1024 )
         {
-            out.print( toKB( complete ) + " KB " + "\r" );
+            return toKB( complete ) + " KB ";
         }
         else
         {
-            out.print( complete + " B " + "\r" );
+            return complete + " B ";
         }
     }
 
+    private void pad( StringBuilder buffer, int spaces )
+    {
+        String block = "                                        ";
+        while ( spaces > 0 )
+        {
+            int n = Math.min( spaces, block.length() );
+            buffer.append( block, 0, n );
+            spaces -= n;
+        }
+    }
+
+    @Override
+    public void transferCompleted( ArtifactTransferEvent transferEvent )
+    {
+        downloads.remove( transferEvent.getResource() );
+
+        StringBuilder buffer = new StringBuilder( 64 );
+        pad( buffer, lastLength );
+        buffer.append( '\r' );
+        out.print( buffer );
+
+        super.transferCompleted( transferEvent );
+    }
+
 }



Re: svn commit: r900982 - in /maven/maven-3/trunk: maven-compat/src/main/java/org/apache/maven/artifact/resolver/ maven-compat/src/main/java/org/apache/maven/repository/legacy/ maven-embedder/src/main/java/org/apache/maven/cli/

Posted by Olivier Lamy <ol...@apache.org>.
Just tested with -Dmaven.artifact.threads=20 and no issue with the small fix

:-)

2010/1/20 Benjamin Bentmann <be...@udo.edu>:
> Olivier Lamy wrote:
>
>> I just have a concurrency issue :
>> [...]
>> But it's on a build server with a huge number of cpu ( solaris : 8
>> cores * 8 cpu per core).
>> I'm testing a small change which looks to fix the issue.
>
> Thanks, keep stressing Maven 3 ;-) !
>
>
> Benjamin
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
> For additional commands, e-mail: dev-help@maven.apache.org
>
>



-- 
Olivier

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org


Re: svn commit: r900982 - in /maven/maven-3/trunk: maven-compat/src/main/java/org/apache/maven/artifact/resolver/ maven-compat/src/main/java/org/apache/maven/repository/legacy/ maven-embedder/src/main/java/org/apache/maven/cli/

Posted by Benjamin Bentmann <be...@udo.edu>.
Olivier Lamy wrote:

> I just have a concurrency issue :
> [...]
> But it's on a build server with a huge number of cpu ( solaris : 8
> cores * 8 cpu per core).
> I'm testing a small change which looks to fix the issue.

Thanks, keep stressing Maven 3 ;-) !


Benjamin

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org


Re: svn commit: r900982 - in /maven/maven-3/trunk: maven-compat/src/main/java/org/apache/maven/artifact/resolver/ maven-compat/src/main/java/org/apache/maven/repository/legacy/ maven-embedder/src/main/java/org/apache/maven/cli/

Posted by Olivier Lamy <ol...@apache.org>.
I just have a concurrency issue :

Exception in thread "pool-1-thread-3" java.util.ConcurrentModificationException
        at java.util.LinkedHashMap$LinkedHashIterator.nextEntry(LinkedHashMap.java:373)
        at java.util.LinkedHashMap$EntryIterator.next(LinkedHashMap.java:392)
        at java.util.LinkedHashMap$EntryIterator.next(LinkedHashMap.java:391)
        at org.apache.maven.cli.ConsoleMavenTransferListener.doProgress(ConsoleMavenTransferListener.java:57)
        at org.apache.maven.cli.AbstractMavenTransferListener.transferProgress(AbstractMavenTransferListener.java:106)
        at org.apache.maven.repository.legacy.TransferListenerAdapter.transferProgress(TransferListenerAdapter.java:128)
        at org.apache.maven.wagon.events.TransferEventSupport.fireTransferProgress(TransferEventSupport.java:124)
        at org.apache.maven.wagon.AbstractWagon.fireTransferProgress(AbstractWagon.java:505)
        at org.apache.maven.wagon.AbstractWagon.transfer(AbstractWagon.java:490)
        at org.apache.maven.wagon.AbstractWagon.getTransfer(AbstractWagon.java:328)
        at org.apache.maven.wagon.AbstractWagon.getTransfer(AbstractWagon.java:299)
        at org.apache.maven.wagon.AbstractWagon.getTransfer(AbstractWagon.java:276)
        at org.apache.maven.wagon.StreamWagon.getIfNewer(StreamWagon.java:97)
        at org.apache.maven.wagon.StreamWagon.get(StreamWagon.java:61)
        at org.apache.maven.repository.legacy.DefaultWagonManager.getRemoteFile(DefaultWagonManager.java:309)
        at org.apache.maven.repository.legacy.DefaultWagonManager.getArtifact(DefaultWagonManager.java:98)
        at org.apache.maven.repository.legacy.DefaultWagonManager.getArtifact(DefaultWagonManager.java:129)
        at org.apache.maven.artifact.resolver.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:251)
        at org.apache.maven.artifact.resolver.DefaultArtifactResolver.access$000(DefaultArtifactResolver.java:73)
        at org.apache.maven.artifact.resolver.DefaultArtifactResolver$ResolveTask.run(DefaultArtifactResolver.java:686)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:619)

But it's on a build server with a huge number of cpu ( solaris : 8
cores * 8 cpu per core).
I'm testing a small change which looks to fix the issue.



2010/1/20 Olivier Lamy <ol...@apache.org>:
> Nice and thanks !!
>
> --
> Olivier
>
> 2010/1/19  <be...@apache.org>:
>> Author: bentmann
>> Date: Tue Jan 19 22:25:12 2010
>> New Revision: 900982
>>
>> URL: http://svn.apache.org/viewvc?rev=900982&view=rev
>> Log:
>> [MNG-4432] reimplement parallel artifacts download
>>
>> Modified:
>>    maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java
>>    maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/repository/legacy/TransferListenerAdapter.java
>>    maven/maven-3/trunk/maven-embedder/src/main/java/org/apache/maven/cli/ConsoleMavenTransferListener.java
>>
>> Modified: maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java
>> URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java?rev=900982&r1=900981&r2=900982&view=diff
>> ==============================================================================
>> --- maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java (original)
>> +++ maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java Tue Jan 19 22:25:12 2010
>> @@ -24,6 +24,12 @@
>>  import java.util.List;
>>  import java.util.Map;
>>  import java.util.Set;
>> +import java.util.concurrent.CountDownLatch;
>> +import java.util.concurrent.Executor;
>> +import java.util.concurrent.ExecutorService;
>> +import java.util.concurrent.LinkedBlockingQueue;
>> +import java.util.concurrent.ThreadPoolExecutor;
>> +import java.util.concurrent.TimeUnit;
>>
>>  import org.apache.maven.artifact.Artifact;
>>  import org.apache.maven.artifact.factory.ArtifactFactory;
>> @@ -97,6 +103,38 @@
>>     @Requirement
>>     private LegacySupport legacySupport;
>>
>> +    private final Executor executor;
>> +
>> +    public DefaultArtifactResolver()
>> +    {
>> +        int threads = Integer.getInteger( "maven.artifact.threads", 5 ).intValue();
>> +        if ( threads <= 1 )
>> +        {
>> +            executor = new Executor()
>> +            {
>> +                public void execute( Runnable command )
>> +                {
>> +                    command.run();
>> +                }
>> +            };
>> +        }
>> +        else
>> +        {
>> +            executor =
>> +                new ThreadPoolExecutor( threads, threads, 3, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>() );
>> +        }
>> +    }
>> +
>> +    @Override
>> +    protected void finalize()
>> +        throws Throwable
>> +    {
>> +        if ( executor instanceof ExecutorService )
>> +        {
>> +            ( (ExecutorService) executor ).shutdown();
>> +        }
>> +    }
>> +
>>     private void injectSession( RepositoryRequest request )
>>     {
>>         MavenSession session = legacySupport.getSession();
>> @@ -558,41 +596,41 @@
>>         {
>>             return result;
>>         }
>> -
>> +
>>         if ( result.getArtifactResolutionNodes() != null )
>>         {
>> -            ArtifactResolutionRequest childRequest = new ArtifactResolutionRequest( request );
>> +            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
>> +
>> +            CountDownLatch latch = new CountDownLatch( result.getArtifactResolutionNodes().size() );
>>
>>             for ( ResolutionNode node : result.getArtifactResolutionNodes() )
>>             {
>>                 Artifact artifact = node.getArtifact();
>>
>> -                try
>> +                if ( resolutionFilter == null || resolutionFilter.include( artifact ) )
>>                 {
>> -                    if ( resolutionFilter == null || resolutionFilter.include( artifact ) )
>> -                    {
>> -                        childRequest.setRemoteRepositories( node.getRemoteRepositories() );
>> +                    ArtifactResolutionRequest childRequest = new ArtifactResolutionRequest( request );
>> +                    childRequest.setRemoteRepositories( node.getRemoteRepositories() );
>>
>> -                        resolve( artifact, childRequest, transferListener, false );
>> -                    }
>> +                    executor.execute( new ResolveTask( classLoader, latch, artifact, transferListener, childRequest,
>> +                                                       result ) );
>>                 }
>> -                catch ( ArtifactNotFoundException anfe )
>> -                {
>> -                    // These are cases where the artifact just isn't present in any of the remote repositories
>> -                    // because it wasn't deployed, or it was deployed in the wrong place.
>> -
>> -                    result.addMissingArtifact( artifact );
>> -                }
>> -                catch ( ArtifactResolutionException e )
>> +                else
>>                 {
>> -                    // This is really a wagon TransferFailedException so something went wrong after we successfully
>> -                    // retrieved the metadata.
>> -
>> -                    result.addErrorArtifactException( e );
>> +                    latch.countDown();
>>                 }
>>             }
>> +            try
>> +            {
>> +                latch.await();
>> +            }
>> +            catch ( InterruptedException e )
>> +            {
>> +                result.addErrorArtifactException( new ArtifactResolutionException( "Resolution interrupted",
>> +                                                                                   rootArtifact, e ) );
>> +            }
>>         }
>> -
>> +
>>         // We want to send the root artifact back in the result but we need to do this after the other dependencies
>>         // have been resolved.
>>         if ( request.isResolveRoot() )
>> @@ -612,4 +650,67 @@
>>     {
>>         resolve( artifact, remoteRepositories, localRepository, null );
>>     }
>> +
>> +    private class ResolveTask
>> +        implements Runnable
>> +    {
>> +
>> +        private final ClassLoader classLoader;
>> +
>> +        private final CountDownLatch latch;
>> +
>> +        private final Artifact artifact;
>> +
>> +        private final TransferListener transferListener;
>> +
>> +        private final ArtifactResolutionRequest request;
>> +
>> +        private final ArtifactResolutionResult result;
>> +
>> +        public ResolveTask( ClassLoader classLoader, CountDownLatch latch, Artifact artifact, TransferListener transferListener,
>> +                            ArtifactResolutionRequest request, ArtifactResolutionResult result )
>> +        {
>> +            this.classLoader = classLoader;
>> +            this.latch = latch;
>> +            this.artifact = artifact;
>> +            this.transferListener = transferListener;
>> +            this.request = request;
>> +            this.result = result;
>> +        }
>> +
>> +        public void run()
>> +        {
>> +            try
>> +            {
>> +                Thread.currentThread().setContextClassLoader( classLoader );
>> +                resolve( artifact, request, transferListener, false );
>> +            }
>> +            catch ( ArtifactNotFoundException anfe )
>> +            {
>> +                // These are cases where the artifact just isn't present in any of the remote repositories
>> +                // because it wasn't deployed, or it was deployed in the wrong place.
>> +
>> +                synchronized ( result )
>> +                {
>> +                    result.addMissingArtifact( artifact );
>> +                }
>> +            }
>> +            catch ( ArtifactResolutionException e )
>> +            {
>> +                // This is really a wagon TransferFailedException so something went wrong after we successfully
>> +                // retrieved the metadata.
>> +
>> +                synchronized ( result )
>> +                {
>> +                    result.addErrorArtifactException( e );
>> +                }
>> +            }
>> +            finally
>> +            {
>> +                latch.countDown();
>> +            }
>> +        }
>> +
>> +    }
>> +
>>  }
>>
>> Modified: maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/repository/legacy/TransferListenerAdapter.java
>> URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/repository/legacy/TransferListenerAdapter.java?rev=900982&r1=900981&r2=900982&view=diff
>> ==============================================================================
>> --- maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/repository/legacy/TransferListenerAdapter.java (original)
>> +++ maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/repository/legacy/TransferListenerAdapter.java Tue Jan 19 22:25:12 2010
>> @@ -34,11 +34,11 @@
>>     implements TransferListener
>>  {
>>
>> -    private ArtifactTransferListener listener;
>> +    private final ArtifactTransferListener listener;
>>
>> -    private Map<Resource, ArtifactTransferResource> artifacts;
>> +    private final Map<Resource, ArtifactTransferResource> artifacts;
>>
>> -    private Map<Resource, Long> transfers;
>> +    private final Map<Resource, Long> transfers;
>>
>>     public static TransferListener newAdapter( ArtifactTransferListener listener )
>>     {
>> @@ -67,22 +67,34 @@
>>     {
>>         ArtifactTransferEvent event = wrap( transferEvent );
>>
>> -        Long transferred = transfers.get( transferEvent.getResource() );
>> +        Long transferred = null;
>> +        synchronized ( transfers )
>> +        {
>> +            transferred = transfers.remove( transferEvent.getResource() );
>> +        }
>>         if ( transferred != null )
>>         {
>>             event.setTransferredBytes( transferred.longValue() );
>>         }
>>
>> -        listener.transferCompleted( event );
>> +        synchronized ( artifacts )
>> +        {
>> +            artifacts.remove( transferEvent.getResource() );
>> +        }
>>
>> -        artifacts.remove( transferEvent.getResource() );
>> -        transfers.remove( transferEvent.getResource() );
>> +        listener.transferCompleted( event );
>>     }
>>
>>     public void transferError( TransferEvent transferEvent )
>>     {
>> -        artifacts.remove( transferEvent.getResource() );
>> -        transfers.remove( transferEvent.getResource() );
>> +        synchronized ( transfers )
>> +        {
>> +            transfers.remove( transferEvent.getResource() );
>> +        }
>> +        synchronized ( artifacts )
>> +        {
>> +            artifacts.remove( transferEvent.getResource() );
>> +        }
>>     }
>>
>>     public void transferInitiated( TransferEvent transferEvent )
>> @@ -92,16 +104,20 @@
>>
>>     public void transferProgress( TransferEvent transferEvent, byte[] buffer, int length )
>>     {
>> -        Long transferred = transfers.get( transferEvent.getResource() );
>> -        if ( transferred == null )
>> -        {
>> -            transferred = Long.valueOf( length );
>> -        }
>> -        else
>> +        Long transferred;
>> +        synchronized ( transfers )
>>         {
>> -            transferred = Long.valueOf( transferred.longValue() + length );
>> +            transferred = transfers.get( transferEvent.getResource() );
>> +            if ( transferred == null )
>> +            {
>> +                transferred = Long.valueOf( length );
>> +            }
>> +            else
>> +            {
>> +                transferred = Long.valueOf( transferred.longValue() + length );
>> +            }
>> +            transfers.put( transferEvent.getResource(), transferred );
>>         }
>> -        transfers.put( transferEvent.getResource(), transferred );
>>
>>         ArtifactTransferEvent event = wrap( transferEvent );
>>         event.setDataBuffer( buffer );
>> @@ -153,15 +169,18 @@
>>         }
>>         else
>>         {
>> -            ArtifactTransferResource artifact = artifacts.get( resource );
>> -
>> -            if ( artifact == null )
>> +            synchronized ( artifacts )
>>             {
>> -                artifact = new MavenArtifact( repository.getUrl(), resource );
>> -                artifacts.put( resource, artifact );
>> -            }
>> +                ArtifactTransferResource artifact = artifacts.get( resource );
>>
>> -            return artifact;
>> +                if ( artifact == null )
>> +                {
>> +                    artifact = new MavenArtifact( repository.getUrl(), resource );
>> +                    artifacts.put( resource, artifact );
>> +                }
>> +
>> +                return artifact;
>> +            }
>>         }
>>     }
>>
>>
>> Modified: maven/maven-3/trunk/maven-embedder/src/main/java/org/apache/maven/cli/ConsoleMavenTransferListener.java
>> URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-embedder/src/main/java/org/apache/maven/cli/ConsoleMavenTransferListener.java?rev=900982&r1=900981&r2=900982&view=diff
>> ==============================================================================
>> --- maven/maven-3/trunk/maven-embedder/src/main/java/org/apache/maven/cli/ConsoleMavenTransferListener.java (original)
>> +++ maven/maven-3/trunk/maven-embedder/src/main/java/org/apache/maven/cli/ConsoleMavenTransferListener.java Tue Jan 19 22:25:12 2010
>> @@ -20,18 +20,27 @@
>>  */
>>
>>  import java.io.PrintStream;
>> +import java.util.Collections;
>> +import java.util.LinkedHashMap;
>> +import java.util.Map;
>>
>>  import org.apache.maven.repository.ArtifactTransferEvent;
>> +import org.apache.maven.repository.ArtifactTransferResource;
>>
>>  /**
>>  * Console download progress meter.
>> - *
>> + *
>>  * @author <a href="mailto:brett@apache.org">Brett Porter</a>
>>  */
>>  class ConsoleMavenTransferListener
>>     extends AbstractMavenTransferListener
>>  {
>>
>> +    private Map<ArtifactTransferResource, Long> downloads =
>> +        Collections.synchronizedMap( new LinkedHashMap<ArtifactTransferResource, Long>() );
>> +
>> +    private int lastLength;
>> +
>>     public ConsoleMavenTransferListener( PrintStream out )
>>     {
>>         super( out );
>> @@ -40,26 +49,69 @@
>>     @Override
>>     protected void doProgress( ArtifactTransferEvent transferEvent )
>>     {
>> -        long total = transferEvent.getResource().getContentLength();
>> -        long complete = transferEvent.getTransferredBytes();
>> +        ArtifactTransferResource resource = transferEvent.getResource();
>> +        downloads.put( resource, Long.valueOf( transferEvent.getTransferredBytes() ) );
>> +
>> +        StringBuilder buffer = new StringBuilder( 64 );
>>
>> -        // TODO [BP]: Sys.out may no longer be appropriate, but will \r work with getLogger()?
>> +        for ( Map.Entry<ArtifactTransferResource, Long> entry : downloads.entrySet() )
>> +        {
>> +            long total = entry.getKey().getContentLength();
>> +            long complete = entry.getValue().longValue();
>> +
>> +            buffer.append( getStatus( complete, total ) ).append( "  " );
>> +        }
>> +
>> +        int pad = lastLength - buffer.length();
>> +        lastLength = buffer.length();
>> +        pad( buffer, pad );
>> +        buffer.append( '\r' );
>> +
>> +        out.print( buffer );
>> +    }
>> +
>> +    private String getStatus( long complete, long total )
>> +    {
>>         if ( total >= 1024 )
>>         {
>> -            out.print( toKB( complete ) + "/" + toKB( total ) + " KB " + "\r" );
>> +            return toKB( complete ) + "/" + toKB( total ) + " KB ";
>>         }
>>         else if ( total >= 0 )
>>         {
>> -            out.print( complete + "/" + total + " B " + "\r" );
>> +            return complete + "/" + total + " B ";
>>         }
>>         else if ( complete >= 1024 )
>>         {
>> -            out.print( toKB( complete ) + " KB " + "\r" );
>> +            return toKB( complete ) + " KB ";
>>         }
>>         else
>>         {
>> -            out.print( complete + " B " + "\r" );
>> +            return complete + " B ";
>>         }
>>     }
>>
>> +    private void pad( StringBuilder buffer, int spaces )
>> +    {
>> +        String block = "                                        ";
>> +        while ( spaces > 0 )
>> +        {
>> +            int n = Math.min( spaces, block.length() );
>> +            buffer.append( block, 0, n );
>> +            spaces -= n;
>> +        }
>> +    }
>> +
>> +    @Override
>> +    public void transferCompleted( ArtifactTransferEvent transferEvent )
>> +    {
>> +        downloads.remove( transferEvent.getResource() );
>> +
>> +        StringBuilder buffer = new StringBuilder( 64 );
>> +        pad( buffer, lastLength );
>> +        buffer.append( '\r' );
>> +        out.print( buffer );
>> +
>> +        super.transferCompleted( transferEvent );
>> +    }
>> +
>>  }
>>
>>
>>
>
>
>
> --
> Olivier
>



-- 
Olivier

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org


Re: svn commit: r900982 - in /maven/maven-3/trunk: maven-compat/src/main/java/org/apache/maven/artifact/resolver/ maven-compat/src/main/java/org/apache/maven/repository/legacy/ maven-embedder/src/main/java/org/apache/maven/cli/

Posted by Olivier Lamy <ol...@apache.org>.
Nice and thanks !!

--
Olivier

2010/1/19  <be...@apache.org>:
> Author: bentmann
> Date: Tue Jan 19 22:25:12 2010
> New Revision: 900982
>
> URL: http://svn.apache.org/viewvc?rev=900982&view=rev
> Log:
> [MNG-4432] reimplement parallel artifacts download
>
> Modified:
>    maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java
>    maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/repository/legacy/TransferListenerAdapter.java
>    maven/maven-3/trunk/maven-embedder/src/main/java/org/apache/maven/cli/ConsoleMavenTransferListener.java
>
> Modified: maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java
> URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java?rev=900982&r1=900981&r2=900982&view=diff
> ==============================================================================
> --- maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java (original)
> +++ maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java Tue Jan 19 22:25:12 2010
> @@ -24,6 +24,12 @@
>  import java.util.List;
>  import java.util.Map;
>  import java.util.Set;
> +import java.util.concurrent.CountDownLatch;
> +import java.util.concurrent.Executor;
> +import java.util.concurrent.ExecutorService;
> +import java.util.concurrent.LinkedBlockingQueue;
> +import java.util.concurrent.ThreadPoolExecutor;
> +import java.util.concurrent.TimeUnit;
>
>  import org.apache.maven.artifact.Artifact;
>  import org.apache.maven.artifact.factory.ArtifactFactory;
> @@ -97,6 +103,38 @@
>     @Requirement
>     private LegacySupport legacySupport;
>
> +    private final Executor executor;
> +
> +    public DefaultArtifactResolver()
> +    {
> +        int threads = Integer.getInteger( "maven.artifact.threads", 5 ).intValue();
> +        if ( threads <= 1 )
> +        {
> +            executor = new Executor()
> +            {
> +                public void execute( Runnable command )
> +                {
> +                    command.run();
> +                }
> +            };
> +        }
> +        else
> +        {
> +            executor =
> +                new ThreadPoolExecutor( threads, threads, 3, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>() );
> +        }
> +    }
> +
> +    @Override
> +    protected void finalize()
> +        throws Throwable
> +    {
> +        if ( executor instanceof ExecutorService )
> +        {
> +            ( (ExecutorService) executor ).shutdown();
> +        }
> +    }
> +
>     private void injectSession( RepositoryRequest request )
>     {
>         MavenSession session = legacySupport.getSession();
> @@ -558,41 +596,41 @@
>         {
>             return result;
>         }
> -
> +
>         if ( result.getArtifactResolutionNodes() != null )
>         {
> -            ArtifactResolutionRequest childRequest = new ArtifactResolutionRequest( request );
> +            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
> +
> +            CountDownLatch latch = new CountDownLatch( result.getArtifactResolutionNodes().size() );
>
>             for ( ResolutionNode node : result.getArtifactResolutionNodes() )
>             {
>                 Artifact artifact = node.getArtifact();
>
> -                try
> +                if ( resolutionFilter == null || resolutionFilter.include( artifact ) )
>                 {
> -                    if ( resolutionFilter == null || resolutionFilter.include( artifact ) )
> -                    {
> -                        childRequest.setRemoteRepositories( node.getRemoteRepositories() );
> +                    ArtifactResolutionRequest childRequest = new ArtifactResolutionRequest( request );
> +                    childRequest.setRemoteRepositories( node.getRemoteRepositories() );
>
> -                        resolve( artifact, childRequest, transferListener, false );
> -                    }
> +                    executor.execute( new ResolveTask( classLoader, latch, artifact, transferListener, childRequest,
> +                                                       result ) );
>                 }
> -                catch ( ArtifactNotFoundException anfe )
> -                {
> -                    // These are cases where the artifact just isn't present in any of the remote repositories
> -                    // because it wasn't deployed, or it was deployed in the wrong place.
> -
> -                    result.addMissingArtifact( artifact );
> -                }
> -                catch ( ArtifactResolutionException e )
> +                else
>                 {
> -                    // This is really a wagon TransferFailedException so something went wrong after we successfully
> -                    // retrieved the metadata.
> -
> -                    result.addErrorArtifactException( e );
> +                    latch.countDown();
>                 }
>             }
> +            try
> +            {
> +                latch.await();
> +            }
> +            catch ( InterruptedException e )
> +            {
> +                result.addErrorArtifactException( new ArtifactResolutionException( "Resolution interrupted",
> +                                                                                   rootArtifact, e ) );
> +            }
>         }
> -
> +
>         // We want to send the root artifact back in the result but we need to do this after the other dependencies
>         // have been resolved.
>         if ( request.isResolveRoot() )
> @@ -612,4 +650,67 @@
>     {
>         resolve( artifact, remoteRepositories, localRepository, null );
>     }
> +
> +    private class ResolveTask
> +        implements Runnable
> +    {
> +
> +        private final ClassLoader classLoader;
> +
> +        private final CountDownLatch latch;
> +
> +        private final Artifact artifact;
> +
> +        private final TransferListener transferListener;
> +
> +        private final ArtifactResolutionRequest request;
> +
> +        private final ArtifactResolutionResult result;
> +
> +        public ResolveTask( ClassLoader classLoader, CountDownLatch latch, Artifact artifact, TransferListener transferListener,
> +                            ArtifactResolutionRequest request, ArtifactResolutionResult result )
> +        {
> +            this.classLoader = classLoader;
> +            this.latch = latch;
> +            this.artifact = artifact;
> +            this.transferListener = transferListener;
> +            this.request = request;
> +            this.result = result;
> +        }
> +
> +        public void run()
> +        {
> +            try
> +            {
> +                Thread.currentThread().setContextClassLoader( classLoader );
> +                resolve( artifact, request, transferListener, false );
> +            }
> +            catch ( ArtifactNotFoundException anfe )
> +            {
> +                // These are cases where the artifact just isn't present in any of the remote repositories
> +                // because it wasn't deployed, or it was deployed in the wrong place.
> +
> +                synchronized ( result )
> +                {
> +                    result.addMissingArtifact( artifact );
> +                }
> +            }
> +            catch ( ArtifactResolutionException e )
> +            {
> +                // This is really a wagon TransferFailedException so something went wrong after we successfully
> +                // retrieved the metadata.
> +
> +                synchronized ( result )
> +                {
> +                    result.addErrorArtifactException( e );
> +                }
> +            }
> +            finally
> +            {
> +                latch.countDown();
> +            }
> +        }
> +
> +    }
> +
>  }
>
> Modified: maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/repository/legacy/TransferListenerAdapter.java
> URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/repository/legacy/TransferListenerAdapter.java?rev=900982&r1=900981&r2=900982&view=diff
> ==============================================================================
> --- maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/repository/legacy/TransferListenerAdapter.java (original)
> +++ maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/repository/legacy/TransferListenerAdapter.java Tue Jan 19 22:25:12 2010
> @@ -34,11 +34,11 @@
>     implements TransferListener
>  {
>
> -    private ArtifactTransferListener listener;
> +    private final ArtifactTransferListener listener;
>
> -    private Map<Resource, ArtifactTransferResource> artifacts;
> +    private final Map<Resource, ArtifactTransferResource> artifacts;
>
> -    private Map<Resource, Long> transfers;
> +    private final Map<Resource, Long> transfers;
>
>     public static TransferListener newAdapter( ArtifactTransferListener listener )
>     {
> @@ -67,22 +67,34 @@
>     {
>         ArtifactTransferEvent event = wrap( transferEvent );
>
> -        Long transferred = transfers.get( transferEvent.getResource() );
> +        Long transferred = null;
> +        synchronized ( transfers )
> +        {
> +            transferred = transfers.remove( transferEvent.getResource() );
> +        }
>         if ( transferred != null )
>         {
>             event.setTransferredBytes( transferred.longValue() );
>         }
>
> -        listener.transferCompleted( event );
> +        synchronized ( artifacts )
> +        {
> +            artifacts.remove( transferEvent.getResource() );
> +        }
>
> -        artifacts.remove( transferEvent.getResource() );
> -        transfers.remove( transferEvent.getResource() );
> +        listener.transferCompleted( event );
>     }
>
>     public void transferError( TransferEvent transferEvent )
>     {
> -        artifacts.remove( transferEvent.getResource() );
> -        transfers.remove( transferEvent.getResource() );
> +        synchronized ( transfers )
> +        {
> +            transfers.remove( transferEvent.getResource() );
> +        }
> +        synchronized ( artifacts )
> +        {
> +            artifacts.remove( transferEvent.getResource() );
> +        }
>     }
>
>     public void transferInitiated( TransferEvent transferEvent )
> @@ -92,16 +104,20 @@
>
>     public void transferProgress( TransferEvent transferEvent, byte[] buffer, int length )
>     {
> -        Long transferred = transfers.get( transferEvent.getResource() );
> -        if ( transferred == null )
> -        {
> -            transferred = Long.valueOf( length );
> -        }
> -        else
> +        Long transferred;
> +        synchronized ( transfers )
>         {
> -            transferred = Long.valueOf( transferred.longValue() + length );
> +            transferred = transfers.get( transferEvent.getResource() );
> +            if ( transferred == null )
> +            {
> +                transferred = Long.valueOf( length );
> +            }
> +            else
> +            {
> +                transferred = Long.valueOf( transferred.longValue() + length );
> +            }
> +            transfers.put( transferEvent.getResource(), transferred );
>         }
> -        transfers.put( transferEvent.getResource(), transferred );
>
>         ArtifactTransferEvent event = wrap( transferEvent );
>         event.setDataBuffer( buffer );
> @@ -153,15 +169,18 @@
>         }
>         else
>         {
> -            ArtifactTransferResource artifact = artifacts.get( resource );
> -
> -            if ( artifact == null )
> +            synchronized ( artifacts )
>             {
> -                artifact = new MavenArtifact( repository.getUrl(), resource );
> -                artifacts.put( resource, artifact );
> -            }
> +                ArtifactTransferResource artifact = artifacts.get( resource );
>
> -            return artifact;
> +                if ( artifact == null )
> +                {
> +                    artifact = new MavenArtifact( repository.getUrl(), resource );
> +                    artifacts.put( resource, artifact );
> +                }
> +
> +                return artifact;
> +            }
>         }
>     }
>
>
> Modified: maven/maven-3/trunk/maven-embedder/src/main/java/org/apache/maven/cli/ConsoleMavenTransferListener.java
> URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-embedder/src/main/java/org/apache/maven/cli/ConsoleMavenTransferListener.java?rev=900982&r1=900981&r2=900982&view=diff
> ==============================================================================
> --- maven/maven-3/trunk/maven-embedder/src/main/java/org/apache/maven/cli/ConsoleMavenTransferListener.java (original)
> +++ maven/maven-3/trunk/maven-embedder/src/main/java/org/apache/maven/cli/ConsoleMavenTransferListener.java Tue Jan 19 22:25:12 2010
> @@ -20,18 +20,27 @@
>  */
>
>  import java.io.PrintStream;
> +import java.util.Collections;
> +import java.util.LinkedHashMap;
> +import java.util.Map;
>
>  import org.apache.maven.repository.ArtifactTransferEvent;
> +import org.apache.maven.repository.ArtifactTransferResource;
>
>  /**
>  * Console download progress meter.
> - *
> + *
>  * @author <a href="mailto:brett@apache.org">Brett Porter</a>
>  */
>  class ConsoleMavenTransferListener
>     extends AbstractMavenTransferListener
>  {
>
> +    private Map<ArtifactTransferResource, Long> downloads =
> +        Collections.synchronizedMap( new LinkedHashMap<ArtifactTransferResource, Long>() );
> +
> +    private int lastLength;
> +
>     public ConsoleMavenTransferListener( PrintStream out )
>     {
>         super( out );
> @@ -40,26 +49,69 @@
>     @Override
>     protected void doProgress( ArtifactTransferEvent transferEvent )
>     {
> -        long total = transferEvent.getResource().getContentLength();
> -        long complete = transferEvent.getTransferredBytes();
> +        ArtifactTransferResource resource = transferEvent.getResource();
> +        downloads.put( resource, Long.valueOf( transferEvent.getTransferredBytes() ) );
> +
> +        StringBuilder buffer = new StringBuilder( 64 );
>
> -        // TODO [BP]: Sys.out may no longer be appropriate, but will \r work with getLogger()?
> +        for ( Map.Entry<ArtifactTransferResource, Long> entry : downloads.entrySet() )
> +        {
> +            long total = entry.getKey().getContentLength();
> +            long complete = entry.getValue().longValue();
> +
> +            buffer.append( getStatus( complete, total ) ).append( "  " );
> +        }
> +
> +        int pad = lastLength - buffer.length();
> +        lastLength = buffer.length();
> +        pad( buffer, pad );
> +        buffer.append( '\r' );
> +
> +        out.print( buffer );
> +    }
> +
> +    private String getStatus( long complete, long total )
> +    {
>         if ( total >= 1024 )
>         {
> -            out.print( toKB( complete ) + "/" + toKB( total ) + " KB " + "\r" );
> +            return toKB( complete ) + "/" + toKB( total ) + " KB ";
>         }
>         else if ( total >= 0 )
>         {
> -            out.print( complete + "/" + total + " B " + "\r" );
> +            return complete + "/" + total + " B ";
>         }
>         else if ( complete >= 1024 )
>         {
> -            out.print( toKB( complete ) + " KB " + "\r" );
> +            return toKB( complete ) + " KB ";
>         }
>         else
>         {
> -            out.print( complete + " B " + "\r" );
> +            return complete + " B ";
>         }
>     }
>
> +    private void pad( StringBuilder buffer, int spaces )
> +    {
> +        String block = "                                        ";
> +        while ( spaces > 0 )
> +        {
> +            int n = Math.min( spaces, block.length() );
> +            buffer.append( block, 0, n );
> +            spaces -= n;
> +        }
> +    }
> +
> +    @Override
> +    public void transferCompleted( ArtifactTransferEvent transferEvent )
> +    {
> +        downloads.remove( transferEvent.getResource() );
> +
> +        StringBuilder buffer = new StringBuilder( 64 );
> +        pad( buffer, lastLength );
> +        buffer.append( '\r' );
> +        out.print( buffer );
> +
> +        super.transferCompleted( transferEvent );
> +    }
> +
>  }
>
>
>



-- 
Olivier

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org