Added throttling to reduce Bamboo peak load and number of concurrent connections

This commit is contained in:
Šesták Vít
2017-06-21 10:18:39 +02:00
parent c55c37fa9a
commit b00857368a
3 changed files with 27 additions and 17 deletions

View File

@@ -4,6 +4,7 @@ import com.google.inject.Inject
import com.google.inject.name.Named
import org.ccil.cowan.tagsoup.jaxp.SAXFactoryImpl
import play.api.libs.ws.{WS, WSClient}
import services.SingleFutureExecutionThrottler
import upickle.default._
import scala.concurrent.{ExecutionContext, Future}
@@ -64,6 +65,8 @@ final case class FlatArtifactDirectory(name: String, items: Seq[(String, String)
final class BambooDownloader @Inject()(@Named("bamboo-server-url") val server: String, @Named("bamboo-authentication") auth: AtlassianAuthentication)(implicit executionContext: ExecutionContext, wSClient: WSClient) extends Downloader {
private val throttler = new SingleFutureExecutionThrottler()
private object ArtifactKeys{
val BuildLog = "Build log"
val ResultsHtml = "Report results-HTML"
@@ -76,7 +79,7 @@ final class BambooDownloader @Inject()(@Named("bamboo-server-url") val server: S
}
private def downloadArtifact(url: String, name: String)(implicit wSClient: WSClient): Future[FlatArtifactItem] = {
bambooUrl(url).get().map{response =>
throttler.throttle(bambooUrl(url).get()).map{response =>
response.header("Content-Disposition") match{
case Some(_) => ArtifactFile(name = name, data = response.bodyAsBytes)
case None =>
@@ -149,7 +152,7 @@ final class BambooDownloader @Inject()(@Named("bamboo-server-url") val server: S
private def downloadProjectReport(project: String, versionOption: Option[Int]): Future[(String, Try[(Build, ArtifactItem, ArtifactFile)])] = {
val url = s"$server/rest/api/latest/result/$project-${versionOption.getOrElse("latest")}.json?expand=artifacts"
val resultFuture = (bambooUrl(url).get().flatMap { response =>
val resultFuture = (throttler.throttle(bambooUrl(url).get()).flatMap { response =>
val build = read[Build](response.body)
val artifactMap: Map[String, Artifact] = build.artifacts.artifact.map(x => x.name -> x).toMap
val logFuture = downloadArtifact(artifactMap, ArtifactKeys.BuildLog).map(_.asInstanceOf[ArtifactFile])

View File

@@ -14,21 +14,6 @@ import slick.jdbc.TransactionIsolation
import scala.concurrent.{ExecutionContext, Future}
final class SingleFutureExecutionThrottler() (implicit executionContext: ExecutionContext){
private var nextFuture: Future[_] = Future.successful(null)
def throttle[T](f: => Future[T]): Future[T] = synchronized{
val newFuture = nextFuture.recover{ case _ => null}.flatMap(_ => f)
nextFuture = newFuture
newFuture
}
}
final class NoThrottler() (implicit executionContext: ExecutionContext){
def throttle[T](f: => Future[T]): Future[T] = f
}
class VulnerabilityNotificationService @Inject() (protected val dbConfigProvider: DatabaseConfigProvider)(implicit executionContext: ExecutionContext) extends HasDatabaseConfigProvider[models.profile.type]{
import dbConfig.driver.api._
import models.tables._

View File

@@ -0,0 +1,22 @@
package services
import scala.concurrent.{ExecutionContext, Future}
trait Throttler {
def throttle[T](f: => Future[T]): Future[T]
}
final class SingleFutureExecutionThrottler() (implicit executionContext: ExecutionContext) extends Throttler{
private var nextFuture: Future[_] = Future.successful(null)
def throttle[T](f: => Future[T]): Future[T] = synchronized{
val newFuture = nextFuture.recover{ case _ => null}.flatMap(_ => f)
nextFuture = newFuture
newFuture
}
}
final class NoThrottler() (implicit executionContext: ExecutionContext) extends Throttler{
def throttle[T](f: => Future[T]): Future[T] = f
}