mirror of
https://github.com/ysoftdevs/odc-analyzer.git
synced 2026-01-16 08:37:12 +01:00
Added throttling to reduce Bamboo peak load and number of concurrent connections
This commit is contained in:
@@ -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])
|
||||
|
||||
@@ -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._
|
||||
|
||||
22
app/services/throttlers.scala
Normal file
22
app/services/throttlers.scala
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user