From 862169c6bb1fc9becf5526e24dfbc446fe6c8e49 Mon Sep 17 00:00:00 2001 From: Alexandre Archambault Date: Sat, 22 Jul 2017 17:29:29 +0200 Subject: [PATCH] Add more guarantees that a same module can't be downloaded concurrently traverse called in ResolutionProcess.fetchAll relies on Applicative, so doesn't guarantee that the module groups will be fetched one after the other. The Applicative instance of scalaz.concurrent.Task doesn't parallelize the tasks by default, so it works fine here. But that extra security ensures that code can be fine with other monads. --- .../scala/coursier/core/ResolutionProcess.scala | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/core/shared/src/main/scala/coursier/core/ResolutionProcess.scala b/core/shared/src/main/scala/coursier/core/ResolutionProcess.scala index 7d4452f98..0f3f5ac75 100644 --- a/core/shared/src/main/scala/coursier/core/ResolutionProcess.scala +++ b/core/shared/src/main/scala/coursier/core/ResolutionProcess.scala @@ -3,9 +3,8 @@ package core import scala.annotation.tailrec import scala.language.higherKinds - -import scalaz.{Monad, -\/, \/-} -import scalaz.Scalaz.{ToFunctorOps, ToTraverseOps, vectorInstance} +import scalaz.{-\/, Monad, \/, \/-} +import scalaz.Scalaz.{ToFunctorOps, ToBindOps, ToTraverseOps, vectorInstance} sealed abstract class ResolutionProcess { @@ -166,7 +165,10 @@ object ResolutionProcess { Missing(resolution0.missingFromCache.toSeq, resolution0, apply) } - private def fetchAll[F[_]](modVers: Seq[(Module, String)], fetch: Fetch.Metadata[F])(implicit F: Monad[F]) = { + private[coursier] def fetchAll[F[_]]( + modVers: Seq[(Module, String)], + fetch: Fetch.Metadata[F] + )(implicit F: Monad[F]): F[Vector[((Module, String), Seq[String] \/ (Artifact.Source, Project))]] = { def uniqueModules(modVers: Seq[(Module, String)]): Stream[Seq[(Module, String)]] = { @@ -191,8 +193,11 @@ object ResolutionProcess { uniqueModules(modVers) .toVector - .traverse(fetch) - .map(_.flatten) + .foldLeft(F.point(Vector.empty[((Module, String), Seq[String] \/ (Artifact.Source, Project))])) { + (acc, l) => + for (v <- acc; e <- fetch(l)) + yield v ++ e + } } }