Skip to content

Commit

Permalink
Merge pull request #229 from VirtusLab/fetch-with-retry
Browse files Browse the repository at this point in the history
Fetch dependencies with retry
  • Loading branch information
tpasternak authored Jul 11, 2022
2 parents 732bd5f + 3195b72 commit 9b56dc2
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ object DependenciesConfig {
case class Resolvers(
intellij: IntelliJ = IntelliJ(Seq.empty),
plugins: Plugins = Plugins(None),
jbr: Jbr = Jbr(Seq.empty)
jbr: Jbr = Jbr(Seq.empty),
retries: Int = 0
)

case class IntelliJ(repositories: Seq[String])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,31 @@ import java.net.URI
import java.nio.file.Files
import java.nio.file.Path

import scala.annotation.tailrec

import org.virtuslab.ideprobe.Extensions._
import org.virtuslab.ideprobe.IdeProbePaths

trait ResourceProvider {
def get(uri: URI, provider: => InputStream): Path
def get(uri: URI, provider: () => InputStream): Path

def get(uri: URI): Path = get(uri, uri.toURL.openStream())
def get(uri: URI): Path = get(uri, () => uri.toURL.openStream())
}

object ResourceProvider {
def fromConfig(paths: IdeProbePaths): ResourceProvider = {
new Cached(paths.cache)
def fromConfig(paths: IdeProbePaths, retries: Int): ResourceProvider = {
new Cached(paths.cache, retries)
}

val Default = new Cached(IdeProbePaths.Default.cache)
val Default = new Cached(IdeProbePaths.Default.cache, 0)

final class Cached(directory: Path) extends ResourceProvider {
override def get(uri: URI, provider: => InputStream): Path = {
final class Cached(directory: Path, retries: Int) extends ResourceProvider {
override def get(uri: URI, provider: () => InputStream): Path = {
Resource.from(uri) match {
case Resource.Http(uri) =>
cacheUri(uri, provider, cached => s"Fetching $uri into $cached")
cacheUri(uri, provider, cached => s"Fetching $uri into $cached", retries)
case Resource.Jar(uri) =>
cacheUri(uri, provider, cached => s"Extracting $uri from jar into $cached")
cacheUri(uri, provider, cached => s"Extracting $uri from jar into $cached", retries)
case file: Resource.File if file.path.toFile.exists() =>
file.path
case file: Resource.File =>
Expand All @@ -37,19 +39,35 @@ object ResourceProvider {
}
}

@tailrec
def retry[T](times: Int)(body: () => T): T = {
try {
body()
} catch {
case e: Throwable =>
if (times > 0) {
Thread.sleep(10000)
retry(times - 1)(body)
} else throw e
}
}

private def cacheUri(
uri: URI,
createStream: => InputStream,
message: Path => String
createStream: () => InputStream,
message: Path => String,
retries: Int
): Path = {
val cachedResource = cached(uri)
if (!cachedResource.isFile) {
val stream = createStream
println(message(cachedResource))
Files
.createTempFile("cached-resource", "-tmp")
.append(stream)
.moveTo(cachedResource)
retry(retries) { () =>
val stream = createStream()
println(message(cachedResource))
Files
.createTempFile("cached-resource", "-tmp")
.append(stream)
.moveTo(cachedResource)
}
}
cachedResource
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ object IntelliJProvider {
val intelliJResolvers = IntelliJZipResolver.fromConfig(resolversConfig.intellij)
val pluginResolver = PluginResolver.fromConfig(resolversConfig.plugins)
val jbrResolvers = JbrResolvers.fromConfig(resolversConfig.jbr)
val resourceProvider = ResourceProvider.fromConfig(paths)
val resourceProvider = ResourceProvider.fromConfig(paths, resolversConfig.retries)
val intelliJDependencyProvider = new IntelliJDependencyProvider(intelliJResolvers, resourceProvider)
val pluginDependencyProvider = new PluginDependencyProvider(Seq(pluginResolver), resourceProvider)
val jbrDependencyProvider = new JbrDependencyProvider(jbrResolvers, resourceProvider)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ object PantsPluginBuilder extends DependencyBuilder(Id("pants")) {
val env = config.get[Map[String, String]]("env").getOrElse(Map.empty)
val hash = GitRepository.commitHash(repository, "HEAD")
val artifact = repository.path.resolveChild(hash)
resources.get(artifact, provider = build(repository, env))
resources.get(artifact, provider = () => build(repository, env))
}

private def build(repository: GitRepository, userEnv: Map[String, String]): InputStream = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ object ScalaPluginBuilder extends DependencyBuilder(Id("scala")) {
val jdkVersion = params.jdk.getOrElse("11")
val hash = GitRepository.commitHash(repository, "HEAD")
val artifact = repository.path.resolveChild(hash)
resources.get(artifact, provider = build(repository, jdkVersion, resources))
resources.get(artifact, provider = () => build(repository, jdkVersion, resources))
}

private def build(
Expand Down

0 comments on commit 9b56dc2

Please sign in to comment.